Skip to content
Hypha Stack

Wiretype

JSON contracts for OCaml.

Source on GitHubLatest: 0.5.0

About

Describe a JSON shape once, or derive it from your type. That one value reads a document and reports every problem in it, writes a value, checks the bounds it states, and prints itself as JSON Schema 2020-12 and as Zod.

A server, a browser and a model's tool call read the same contract. It depends on Ptime, Mtime and Uuidm alone.

Data contracts

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 wiretype ppx_wiretype

Then in your dune file:

(libraries wiretype)
(preprocess (pps ppx_wiretype))

In code

  1. A type, its bounds and its docs, derived as one description.

    module J = Wiretype
    
    (** A line of an order. *)
    type line = {
      sku : string;
      quantity : int; [@min 1] [@max 99]  (** how many *)
      note : string option; [@max_length 200]
    } [@@deriving wiretype]
    
    let () =
      match J.decode line_json {|{"sku": "A1", "quantity": 120, "note": 7}|} with
      | Ok _ -> ()
      | Error problems ->
          List.iter (fun p -> print_endline (J.Problem.to_string p)) problems
  2. Every problem in one pass, each with its path and a code a client branches on.

    quantity: This must be at most 99. (too_large)
    note: This must be text, not a number. (unexpected_type)
  3. The same description, printed as Zod for the front end.

    /** A line of an order. */
    export const LineSchema = z.object({
      sku: z.string(),
      /** how many */
      quantity: z.int().check(z.gte(1), z.lte(99)),
      note: z.optional(z.string().check(z.maxLength(200))),
    });
    export type Line = z.infer<typeof LineSchema>;

Ontology

Build with Hypha.