package shuttle_http
Install
Dune Dependency
Authors
Maintainers
Sources
sha256=073651dfcbe88a29856ae9568583ecece3df659aa74470ca92671e388ccc9351
sha512=78a8f4517238a7332cf5211f250aa031a3f64fcdf3617c23f072183bbbd9535e295cdef9551d24e4451ef674e0ce6845296960f66ca9c28b81430f4cf0dda563
doc/index.html
Shuttle_http
Shuttle_http is a low level library for implementing HTTP/1.1 web services in OCaml using the Async library for lightweight concurrency. It allows defining services as simple OCaml functions, and supports streaming bodies to allow working with large bodies incrementally.
It supports error reporting using error handlers and provides a default implementation that responds with the error status code and an empty response body. Users can provide their own error handler implementation when setting up a server config. The library however only considers unhandled exceptions, and errors encountered while parsing the wire payload as use-cases that invoke the error handler. The expectation is that application specific errors will be dealt with by the user within their service definition.
Tutorial
Basics
Shuttle_http is not a framework and hence doesn't ship with any abstractions beyond service definitions needing to be a function that accept a request and return a deferred response.
A service definition in its most simple form might look like:
open Shuttle_http
let my_service (request : Request.t) =
return (Response.create ~body:(Body.string "Hello World") `Ok)
;;
Streaming response
We saw how to define services that respond with data that's entirely in memory. For some use-cases (Specially when working with really large bodies created from external sources like files), one might want to use a streaming body to serve large amounts of data without loading it all in memory:
open Shuttle_http
let my_service (context : Server.t) (request : Request.t) =
let%map reader =
(* This an example to show a stream that works with an external resource. *)
Reader.open_file "<some file path>"
in
(* Create a pipe from the reader that we will use as a streaming response body. *)
let reader_pipe = Reader.pipe reader in
(* Create a response from the reader's pipe. If the server is closed before the full
response was served, the pipe will be closed which in-turn will close the reader and
the underlying file descriptor. *)
Response.create ~body:(Body.of_pipe `Chunked reader_pipe) `Ok
;;
let main port =
Server.run_inet (Tcp.Where_to_listen.of_port port) my_service
;;
API docs
The following modules are part of the library: