Vif is a simple web framework for OCaml 5 based on httpcats
and Miou. A tutorial is available here to learn how to use it, and another tutorial is available here to learn how to use Miou.
Vif is primarily a library that can be used in a project to launch a web server. However, the distribution also offers a tool called vif
that allows you to natively interpret an OCaml script in order to launch a web server:
$ cat >main.ml <<EOF
#require "vif" ;;
let default req server () =
let open Vif.Response.Syntax in
let field = "content-type" in
let* () = Vif.Response.add ~field "text/html; charset=utf-8" in
let* () = Vif.Response.with_string req "Hello World!" in
Vif.Response.respond `OK
;;
let routes =
let open Vif.Uri in
let open Vif.Route in
[ get (rel /?? nil) --> default ]
let () =
Miou_unix.run @@ fun () ->
Vif.run routes ()
;;
EOF
$ vif --pid vif.pid main.ml &
$ hurl http://localhost:8080/ -p b
Hello World!
$ kill -SIGINT $(cat vif.pid)
How to launch a Vif server?
The first entry point in Vif is the run
function, which launches the HTTP server. This function requires several arguments, the purpose of whose is described for the various modules that allow these arguments to be specified.
Vif essentially requires a list of routes for processing client requests. However, the user can also specify middleware (see Middlewares
), handlers for processing requests if no routes are recognised (see Handler
), a function for managing the WebSocket protocol (see websocket
), and devices that can manage other protocols (such as SQL) (see Device
).
Vif is therefore a web server that takes advantage of OCaml 5 and the use of domains thanks to Miou. If you are interested in the performance that Vif can offer, it is intrinsic to the results obtained with httpcats
. We therefore invite you to find out more about the latter if you are interested in these metrics.
But here are the latest results for httpcats
using the benchmarking framework provided by TechEnpower (on AMD Ryzen 9 7950X 16-Core Processor):
clients | threads | latencyAvg | latencyMax | latencyStdev | totalRequests |
---|
16 | 16 | 47.43us | 2.27ms | 38.48us | 5303700 |
32 | 32 | 71.73us | 1.04ms | 47.58us | 7016729 |
64 | 32 | 140.29us | 5.72ms | 121.50us | 7658146 |
128 | 32 | 279.73us | 11.35ms | 287.92us | 7977306 |
256 | 32 | 519.02us | 16.89ms | 330.20us | 7816435 |
512 | 32 | 1.06ms | 37.42ms | 534.14us | 7409781 |
The benchmark can be reproduced using this project.
There is a comparison between httpcats
(used by Vif) using the Miou scheduler and Eio. For more information on this, we invite you once again to take a look into the httpcats
project, which goes into detail about the differences between Eio and Miou.
Typed-way to make a web application
Vif was developed in line with the ideals of OCaml and aims to provide a typed API for a whole range of information considered essential for web development. In particular, Vif offers:
- conversion of user-submitted forms into OCaml values (such as records), thanks to
multipart_form
- transformation of JSON content into OCaml values, thanks to
jsont
- the ability to make typed SQL queries whose results can also be transformed into OCaml values, thanks to
caqti
(and caqti.template
) - and the ability to type routes, thanks to
furl
A full OCaml implementation of a web server
Finally, Vif was developed as part of our cooperative robur, which is reimplementing a whole series of protocols and formats in OCaml. In this case, apart from the fact that we use the TCP/IP implementation provided by your system (although we are also developing our own, see utcp
), everything required for Vif is strictly implemented in OCaml:
- cryptographic primitives are provided by
mirage-crypto
- hash algorithms are provided by
digestif
- checksum algorithms are provided by
checkseum
- the TLS protocol implementation is provided by
ocaml-tls
ocaml-dns
can be used for domain name resolution- the happy-eyeballs algorithm can be used to connect to a service which OCaml implementation is provided by the
happy-eyeballs
library - The HTTP/1.1 protocol is implemented by
ocaml-h1
- The H2 protocol is implemented by
h2
- Websockets are implemented by
ocaml-h1
(see H1.Websocket
) - compression (
zlib
and gzip
) is handled by decompress
- file MIME type recognition (required for
Content-Type
) is implemented by conan
Here is an overview of Vif, its dependencies, and what this library has to offer for developing a web application with OCaml 5.
The Uri
module provides a small DSL for describing a format that can accept values. Uri
can be considered as the counterpart of the Format
module, but for URIs. That is, you can describe a way to construct a URI and apply it to values such as integers or strings.
Vif proposes a way to describe a form via types in order to decode a multipart/form-data
request and obtain an OCaml record.
A request not only has content but also parameters (queries) that can be specified via the URI. This module allows you to extract the values specified in the URI to the user when managing the request.
Module Client
implements the client part of the HTTP protocol.
The user may want more precise dispatching than Vif can offer. In this case, if Vif cannot find any routes for a given request, handlers are used to possibly provide a response. Handlers therefore allow you to handle cases that cannot be described using Vif's URI and route system.
Sourceval config :
?domains:int ->
?cookie_key:Mirage_crypto.AES.GCM.key ->
?pid:Fpath.t ->
?http:
[ `H1 of H1.Config.t
| `H2 of H2.Config.t
| `Both of H1.Config.t * H2.Config.t ] ->
?tls:Tls.Config.server ->
?backlog:int ->
Unix.sockaddr ->
config
/