package vif

  1. Overview
  2. Docs

Module VifSource

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 as a library and vif as a tool

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).

Performances & Vif

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.

Sourcemodule Uri : sig ... end

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.

Sourcemodule Json : sig ... end
Sourcemodule Stream : sig ... end
Sourcemodule Headers : sig ... end
Sourcemodule Method : sig ... end

HTTP request methods.

Sourcemodule Multipart_form : sig ... end

Vif proposes a way to describe a form via types in order to decode a multipart/form-data request and obtain an OCaml record.

Sourcemodule Type : sig ... end
Sourcemodule Middleware : sig ... end
Sourcemodule Request : sig ... end
Sourcemodule Queries : sig ... end

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.

Sourcemodule Route : sig ... end
Sourcemodule Client : sig ... end

Module Client implements the client part of the HTTP protocol.

Sourcemodule Device : sig ... end
Sourcemodule Devices : sig ... end
Sourcemodule Server : sig ... end
Sourcemodule Middlewares : sig ... end
Sourcemodule Status : sig ... end
Sourcemodule Response : sig ... end
Sourcemodule Handler : sig ... end

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.

Sourcetype config
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
Sourceval run : ?cfg:config -> ?devices:'value Devices.t -> ?middlewares:'value Middlewares.t -> ?handlers:('c, 'value) Handler.t list -> ?websocket:(ic -> oc -> Server.t -> 'value -> unit) -> (Server.t -> 'value -> (Response.empty, Response.sent, unit) Response.t) Route.t list -> 'value -> unit

/

Sourceval setup_config : unit Cmdliner.Term.t