Skip to content
Hypha Stack

Spindle

The Eio-native web framework for modern OCaml.

Source on GitHubDocumentationLatest: 0.6.1

About

Typed routes, dependencies and answers, on its own HTTP/1.1 engine: every requirement of RFC 9112 and 9110 it meets is a test, and so are WebSockets, forms and Structured Fields.

Interactive OpenAPI docs and front-end schemas come from the routes the server runs. Postgres, sessions, logging, traces and metrics are in the box.

HTTP and APIsData contractsData and persistenceObservabilityIdentity and access

Install

From Hypha's opam repository, on OCaml 5.5 or later:

opam repo add hypha https://github.com/hyphatech/opam-repository.git
opam install spindle spindle-postgres spindle-cli

Then in your dune file:

(executable
 (name main)
 (libraries spindle eio_main)
 (preprocess (pps ppx_wiretype)))

In code

  1. A route: its method and path, what it reads and what it answers, typed from the records.

    open Spindle.Syntax
    
    type bill = {
      total : float; [@min 0.]
      tip : int; [@min 0] [@max 100]  (** percent *)
      people : int; [@min 1] [@max 50]
    }
    [@@deriving wiretype]
    
    type share = { each : float } [@@deriving wiretype]
    
    let split b =
      let total = b.total *. float (100 + b.tip) /. 100. in
      Ok { each = total /. float b.people }
    
    let routes =
      [
        Spindle.post
          Spindle.Path.(s "split")
          (Spindle.Returns.json share_json)
          (let+ b = Spindle.json bill_json in
           split b);
      ]
    
    let () =
      Spindle.Log.setup ();
      Eio_main.run @@ fun env ->
      Spindle.serve env (routes @ Spindle.Openapi.docs routes)
  2. Called. Interactive docs for every route are at /docs, generated from the same routes.

    $ curl localhost:8080/split --json '{"total": 90, "tip": 10, "people": 3}'
    {"each":33}

Ontology

  • RouteRequestanswers
  • RouteResponsereturns
  • RefusalResponseis a
  • HandlerRouteserves
  • RouteData shapeis typed by
  • Client schemaData shapeprinted from
  • API specRouteprinted from
  • HandlerStatementruns
  • Connection poolDatabaseconnects to
  • TraceRequestfollows
  • SpanTraceis part of
  • SpanStatementrecords
  • MetricRequestcounts
  • LogRequestrecords
  • Health checkDatabasechecks
  • PermissionRouteguards
  • RequestSessioncarries
  • SessionIdentityproves
  • Rate limitRequestthrottles
  • Audit logRequestrecords
  • HandlerConfigreads
  • Feature flagHandlergates
  • HandlerCachereads
  • HandlerEventemits
  • HandlerFilestores

Build with Hypha.