Giter Site home page Giter Site logo

c-cube / ocaml-twirp Goto Github PK

View Code? Open in Web Editor NEW
6.0 2.0 0.0 51 KB

[wip] OCaml implementation of Twirp using ocaml-protoc

Home Page: https://c-cube.github.io/ocaml-twirp/

Makefile 10.28% OCaml 87.87% Shell 1.33% Lua 0.52%
http1-1 ocaml protobuf rpc twirp

ocaml-twirp's Introduction

Twirp

This is an OCaml implementation of Twirp that relies on ocaml-protoc to compile protobuf IDL files.

NOTE: this relies on unreleased changes to ocaml-protoc, currently on master. The whole twirp library will have to wait for ocaml-protoc 3.0 to be released to be released itself.

License

MIT license

Usage

In the following examples we use a basic "calculator" service as an example:

syntax = "proto3";

// single int
message I32 {
  int32 value = 0;
}

// add two numbers
message AddReq {
  int32 a = 1;
  int32 b = 2;
}

// add an array of numbers
message AddAllReq {
  repeated int32 ints = 1;
}

service Calculator {
  rpc add(AddReq) returns (I32);

  rpc add_all(AddAllReq) returns (I32);
}

We assume there's a dune rule to extract it into a pair of .ml and .mli files:

(rule
 (targets calculator.ml calculator.mli)
 (deps calculator.proto)
 (action
  (run ocaml-protoc --binary --pp --yojson --services --ml_out ./ %{deps})))

Using Tiny_httpd as a server

The library twirp_tiny_httpd uses Tiny_httpd as a HTTP server to host services over HTTP 1.1.

Tiny_httpd is a convenient little HTTP server with no dependencies that uses direct style control flow and system threads, rather than an event loop. Realistically, it is sufficient for low traffic services (say, less than 100 req/s), and is best used coupled with a thread pool such as Moonpool to improve efficiency.

detailed example

See 'examples/twirp_tiny_httpd/' for an example:

module H = Tiny_httpd
open Calculator

(* here we give concrete implementations for each of the
  methods of the service.  *)
module Service_impl = struct
  let add (a : add_req) : i32 = default_i32 ~value:Int32.(add a.a a.b) ()

  let add_all (a : add_all_req) : i32 =
    let l = ref 0l in
    List.iter (fun x -> l := Int32.add !l x) a.ints;
    default_i32 ~value:!l ()
end

(* instantiate the code-generated [Calculator] service
  to turn it into a [Pbrt_services.Server.t] abstract service. *)
let calc_service : Twirp_tiny_httpd.handler Pbrt_services.Server.t =
  Calculator.Server.make
    ~add:(fun rpc -> Twirp_tiny_httpd.mk_handler rpc Service_impl.add)
    ~add_all:(fun rpc -> Twirp_tiny_httpd.mk_handler rpc Service_impl.add_all)
    ()

let () =
  let port = try int_of_string (Sys.getenv "PORT") with _ -> 8080 in
  Printf.printf "listen on http://localhost:%d/\n%!" port;

  (* create the httpd on the given port *)
  let server = H.create ~port () in
  (* register the service in the httpd (adds routes) *)
  Twirp_tiny_httpd.add_service ~prefix:(Some "twirp") server calc_service;

  H.run_exn server

We implement the concrete service Calculator, then turn it into a Pbrt_services.Server.t (which is an abtract representation of any service: a set of endpoints). We can then create a [Tiny_httpd.Server.t] (a web server) and register the service (or multiple services) in it. This will add new routes (e.g. "/twirp/foo.bar.Calculator/add") and call the functions we defined above to serve these routes.

Using ezcurl as a client

The library twirp_ezcurl uses Ezcurl as a Curl wrapper to provide Twirp clients.

Curl is very widely available and is a robust HTTP client; ezcurl adds a simple OCaml API on top. Twirp_ezcurl is best used for low-traffic querying of services.

full example Example (as in 'examples/twirp_ezcurl/') that computes `31 + 100` remotely:
let spf = Printf.sprintf

let () =
  let port = try int_of_string (Sys.getenv "PORT") with _ -> 8080 in
  Printf.printf "query on http://localhost:%d/\n%!" port;

  let r =
    match
      (* call [Calculator.add] with arguments [{a=31; b=100}] *)
      Twirp_ezcurl.call ~use_tls:false ~host:"localhost" ~port
        Calculator.Calculator.Client.add
      @@ Calculator.default_add_req ~a:31l ~b:100l ()
    with
    | Ok x -> x.value |> Int32.to_int
    | Error err ->
      failwith (spf "call to add failed: %s" @@ Twirp_ezcurl.show_error err)
  in

  Printf.printf "add call: returned %d\n%!" r;
  ()

The main function is Twirp_ezcurl.call, which takes a remote host, port, service endpoint (code-generated from a .proto file), and an argument, and performs a HTTP query. The user can provide an already existing Curl client to reuse, turn TLS off or on, and pick the wire format (JSON or binary protobuf).

ocaml-twirp's People

Contributors

c-cube avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.