Bonsai
Getting started
It's as simple as
app = App()
app("/path"; method = GET) do request
reponse = "hello"
return response
end
start(app)
Now visit localhost:8081
.
The handler function takes a HTTP.Request
and returns a HTTP.Response
.
After your handler is called if it's return type isn't a Response
it will be made into one by
calling create_response
. You can overload create_reponse
for your specific type to have more control.
create_response(t::Mytype)::HTTP.Response
This is already defined for AbstractString
and AbstractDict
, were the Content-Type header is set as text/plain
and application/json
respectively.
Routing and Query Parameters
Routes can be defined for multiple methods by passing an array
app(handler, "/path"; method = [GET, POST])
They can be parametrized by using the syntax /:x
. You can then access
the parameters in the handler with.
app("/route/:id", method = [GET, POST]) do request
params = path_params(request)
# Dict(:id => value)
end
Specific routes take priority over variable routes, in other words "/route/1"
will be matched before "/route/:id"
.
Query parameters can be accessed in a similar way.
query = query_params(request)
Files
To serve a file pass the route and a file path.
app("/", p"index.html")
The MIME type will be inferred from the extension, the supported MIME types can be found here. If the MIME-type is unsupported it can be added to the global MIME_TYPES
.
Folders
You can server folders using the following syntax
app("/img", p"images"; recursive=true, filter_fn=filepath->true)
filter_fn
can be used to remove files you don't want to be served, it
should return a boolean.
If given a folder of the following structure.
images/
├── cat.jpeg
└── dog.jpeg
The routes generated would be img/cat.jpeg
and img/dog.jpeg
.
Sessions
When instantiating the app you can pass data structure you want to use for the session, by default this will be a Dict
. But could be anything you want to use to store state e.g
app = App(session = ReidsSession())
The session can then be accessed in the handler.
app("/path") do req
session = app.session
end
Since a Dict
isn't thread-safe so this will likey change in the future to a different data structure, once parallelism is addressed.
WebSockets
app(ws"/chat_room") do ws
while isopen(ws)
# do stuff
end
end
Middleware
Still thinking about the nicest way to implement this suggesting are welcome!
Docker
Yet todo but will probably add a CLI using Comonicon, that can take a Julia project and generate a Dockerfile with SimpleContainerGenerator.
Examples
For more examples see the examples
folder.
Useful Packages
Some packages that you may find useful to pair with Bonsai
.
- Octo.jl - a SQL Query DSL