Module Tezos_rpc.Path

include module type of struct include Resto.Path end

Paths describe URIs/URLs: segments separated by slashes (/).

Note that paths can be static (i.e., all the segments of the path are determined in advance) or dynamic (i.e., some segments of the path are actually arguments for the service -- e.g., paths can have the form /user/<user-name> where <user-name> is a string encoding of a user identifier).

type ('prefix, 'params) t = ('prefix, 'params) Resto.Path.t

The type for service's paths

A (p, a) path is a path in which some segments encode a value of type a.

Typically a (_, unit) path is a static path. Also typically, a dynamic path has type (_, ((unit * a) * b) * ..) path where different segments encode the different components of the tuple (a, b, etc.). For example the path /entries-by-date/<year>/<month>/<day> may be described as a (_, ((unit * int) * int) * int) path.

type ('prefix, 'params) path = ('prefix, 'params) t
type 'prefix context = ('prefix, 'prefix) path
val root : unit context

root is the basis to build paths upon. It is the "Nil" of path construction.

val open_root : 'a context
val add_suffix : ('prefix, 'params) path -> string -> ('prefix, 'params) path

add_suffix p s is a path in which s has been appended to the sequence of segments described by p.

val (/) : ('prefix, 'params) path -> string -> ('prefix, 'params) path

(/) is an infix operator for add_suffix.

val add_arg : ('prefix, 'params) path -> 'a Resto.Arg.t -> ('prefix, 'params * 'a) path

add_arg p a is a path in which a segment representing a value of type a has been appended to the sequence of segments described by p.

This is intended for use by services. Specifically, a service that is parameterized over a value of type ty is attached to a path that includes an argument for a value of type ty. When the service is called, Resto decodes the argument and passes its value to the service.

val (/:) : ('prefix, 'params) path -> 'a Resto.Arg.t -> ('prefix, 'params * 'a) path

(/:) is an infix operator for add_arg.

val add_final_args : ('prefix, 'params) path -> 'a Resto.Arg.t -> ('prefix, 'params * 'a list) path

add_final_args p a is a path in which an arbitrary sequence of segments representing values of type a has been appended to the sequence of segments described by p.

A similar use to the add_arg is intended, but for a list of values rather than a single value.

Note that, as the name suggests, add_final_args is final: you cannot add further suffixes or arguments to the resulting path. Attempting to do so raises Invalid_arg. Similarly, using the resulting path as a prefix (see below) raises the same exception. This is because paths built with add_final_args consume all the suffix as an unterminated list of arguments, there cannot be further suffixes or arguments.

val (/:*) : ('prefix, 'params) path -> 'a Resto.Arg.t -> ('prefix, 'params * 'a list) path

( /:* ) is an infix operator for add_final_args.

val prefix : ('prefix, 'a) path -> ('a, 'params) path -> ('prefix, 'params) path

prefix p q is a path in which the sequence of segments of p is followed by the sequence of segments of q.

val subst0 : ('p, 'p) path -> ('p2, 'p2) path

subst0 p is a path akin to p but with a different type for the prefix parameter. This is useful when declaring a service in a part of the code where the type of the prefix parameters are not available.

The typical use-case is with protocol services. A service is declared with some dummy prefix parameters.

Later, the shell instantiates the protocol. The shell obtains this service declaration from the instantiated protocol. The shell maintains a protocol state (so called context), which is associated to a given chain (main, testnet, etc.).

The shell registers the service by substituting the shell-side prefix parameters.

For example, below is a commented excerpt from src/lib_shell/block_directory.ml.

(* new directory with concrete prefix parameters *)
let dir :
    (Store.chain_store * Block_hash.t * Block_header.t) Tezos_rpc.Directory.t
    ref =
  ref Tezos_rpc.Directory.empty
in
(* function to add a service to the new directory
   note the call to [subst0] which substitutes the dummy prefix parameters of
   [s] to the concrete ones *)
let register0 s f =
  dir :=
    Tezos_rpc.Directory.register
      !dir
      (Tezos_rpc.Service.subst0 s) (* apply [subst0] to the path of [s] *)
      (fun block p q -> f block p q)
in
(* get the service declarations from the [Proto]col *)
let module Block_services = Block_services.Make (Proto) (Proto) in
let module S = Block_services.S in
register0
  S.hash (* service declared in the protocol used a dummy unit instead of
            [(chain, hash, header)] *)
  (fun (_, hash, _) () () -> return hash) ;
(* more registration with subst0 threaded in …*)
val subst1 : ('p, 'p * 'a) path -> ('p2, 'p2 * 'a) path

See subst0 for rationale.

val subst2 : ('p, ('p * 'a) * 'b) path -> ('p2, ('p2 * 'a) * 'b) path

See subst0 for rationale.

val subst3 : ('p, (('p * 'a) * 'b) * 'c) path -> ('p2, (('p2 * 'a) * 'b) * 'c) path

See subst0 for rationale.

val to_segments : (_, _) path -> string list

to_segments path evaluates in the list of the different elements that constitute the given path.

val to_string : (_, _) path -> string

to_string path evaluates in a string representation of the given path.