Library
Module
Module type
Parameter
Class
Class type
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 creating a server handle. 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.
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)
;;
We saw how to define services that don't require any information from the server handle to prepare responses. For some use-cases (Specially when working with streaming bodies that hold onto external resources), one might want to access the server handle within the service. This might look like:
open Shuttle_http
let my_service (ctx : 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
(* Register a callback that's called when the server handler is closed that will also
close the pipe, in-turn closing the Reader and the underlying file descriptor. This
is useful in scenarios where the connection is interrupted before the response body
is fully exhausted and helps avoid resource leaks. This example is demonstrating how
to do this manually using the server handler. Creating a response via
[Server.respond_stream] will automatically register the action to close a stream on
Server connection closing. *)
upon (Server.closed ctx) (fun () -> Pipe.close_read reader_pipe);
let response_stream = Body.of_pipe `Chunked reader_pipe in
Response.create ~body:response_stream `Ok
;;
let main reader writer =
let server = Server.create reader writer in
Server.run server (my_service server)
;;
The following modules are part of the library: