VifSourceVif 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 as a toolVif 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)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.
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:
multipart_formjsontcaqti (and caqti.template)furlFinally, 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:
mirage-cryptodigestifcheckseumocaml-tlsocaml-dns can be used for domain name resolutionhappy-eyeballs libraryocaml-h1h2ocaml-h1 (see H1.Websocket)zlib and gzip) is handled by decompressContent-Type) is implemented by conanHere 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.
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.
val config :
?with_rng:bool ->
?domains:int ->
?cookie_key:Mirage_crypto.AES.GCM.key ->
?pid:Fpath.t ->
?reporter:Logs.reporter ->
?level:Logs.level option ->
?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 ->
configval run :
?cfg:config ->
?devices:(Server.t * 'value) Devices.t ->
?middlewares:'value Middlewares.t ->
?handlers:('c, 'value) Handler.t list ->
?websocket:(ic -> oc -> Server.t -> 'value -> unit) ->
?stop:Httpcats.Server.stop ->
(Server.t ->
'value ->
(Response.empty, Response.sent, unit) Response.t)
Route.t
list ->
'value ->
unit/