Created
August 10, 2019 21:48
-
-
Save jgaskins/cdc6084f265e6e12f9d4357d118ec7cd to your computer and use it in GitHub Desktop.
Roda-like web framework in Crystal
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class App | |
# Provides the `call(context : HTTP::Server::Context)` interface | |
include HTTP::Handler | |
# Provides the `route` method that we pass the context to to be | |
# able to use routing and response data | |
include Route | |
def call(context : HTTP::Server::Context) | |
route context do |r, response, session| | |
# We render the top part of the app separately because ECR | |
# doesn't have a clean way to render a template within other | |
# template without allocating a big intermediate string on the | |
# heap containing the app's main body markup. Rendering them | |
# sequentially allows us to skip that extra allocation and | |
# use that memory and allocation/GC time to service other | |
# requests. | |
ecr_render "app_header" | |
# Ensure that we send the body to the browser immediately so | |
# it can begin fetching stylesheets while we're rendering the | |
# rest of the page. | |
response.flush | |
# The `ecr_render` macro renders the specified ECR template | |
# (from the `views` directory) into our response. If we call the | |
# response variable `response` in our block params for `route`, | |
# we can omit it here as we did above for `"app_header"`. | |
r.root { ecr_render "index", to: response } | |
# Delegate routes to other "apps" that just render body content. | |
# From their perspective, the path will have the matched portion | |
# removed, so in this example, routing `/orders/123` would | |
# expose the path as `/123` to the Orders route. | |
r.on "orders" { Orders.new.call context } | |
r.on "whatever" { Whatever.new.call context } | |
# Render a 404 page if no other routes picked this up | |
r.miss { ecr_render "not_found" } | |
# Render the app footer | |
ecr_render "app_footer" | |
end | |
end | |
end | |
server = HTTP::Server.new([ | |
HTTP::LogHandler.new, | |
App.new, | |
]) | |
server.listen 8080 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment