Repository navigation
Routing
Dandy Router is completely new vision of how to create flexible, lightweight, language-independent DSL for designing a schema of web-application routing. Rails, Hanami, Sinatra and others provide more or less visually similar DSL for defining routing schema. Their routers use Ruby blocks-based DSL for that. Ruby is a power, Ruby is a weakness: for such purpose Ruby is too verbose. An example demonstrating all features:
:receive
.->
/auth ->
:before -> current_user@load_current_user
/posts ->
GET -> list_posts
POST -> create_post
$id ->
:before -> post@load_post
GET -> show_post
PATCH -> update_post -> :respond =200
DELETE -> remove_post -> :respond =200
/comments ->
GET -> list_comments
POST => add_comment \
=> notify_author \
=* notify_subscribers \
-> :respond <- comment_plain =201
$comment_id ->
GET -> show_comment -> :respond <- comment
DELETE -> remove_comment
:catch -> handle_errors
Routes configuration by default is located in file app/app.routes. You can change it's location in dandy.yml file.
Routes definition has tree-like structure. There're two root entries - :receive and :catch.
:receive section describes regular flow of incoming request.
:catch section defines an action which calls when an error raised somewhere in the regular flow.
:receive section should start from . - root point of the routing.
Every line of the definition is a piece of path to target action or chain.
Symbols -> and <TAB> emulates directory structure. Configuration demonstrated above can be interpreted like:
GET /auth/posts/$id (show_post)
DELETE /auth/posts/$id/comments/$comment_id (remove_comment)
Symbol $ allows to receive request parameters.
As you can see, some routes reference to a chain of actions, like:
-> update_user -> notify_admin -> log_action
It means that you can define a number of atomic operations in order to reach request goals.
-> is a simple sequential type of action. Process flow waits until finishing of it's execution before starting the next
action or making a response.
More interesting case:
=> add_comment => notify_author =* notify_subscribers
=> is a parallel operation. All parallel operations complete before the next sequential (->) or ending of the chain.
=* is an asynchronous operation. It must not be completed before next sequential and even ending of the chain.
The time of execution of asynchronous and parallel operations can be limited in config file (by default it's 10 seconds).
By default Dandy responds with HTTP status 200 (201 for POST) and empty body. You can define :respond instructions for sending custom status and specific response body:
...
POST => add_comment => ... -> :respond <- comment_plain =201
Expression :respond <- declares a view ("comment_plain") and a status = (201). Details about views formatting are described below.