Skip to content

Commit

Permalink
Add helper library for using typed-rpc with ocaml-protoc
Browse files Browse the repository at this point in the history
  • Loading branch information
mbarbin committed Jan 9, 2024
1 parent 394edb5 commit 027e57e
Show file tree
Hide file tree
Showing 5 changed files with 232 additions and 0 deletions.
15 changes: 15 additions & 0 deletions dune-project
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,21 @@
(ocaml-protoc-plugin
(>= 4.5))))

(package
(name grpc-protoc)
(synopsis "An implementation of gRPC using ocaml-protoc")
(description
"Functionality for building gRPC services and rpcs with `ocaml-protoc`")
(depends
(grpc
(= :version))
(ocaml-protoc
(>= 3.0))
(pbrt
(>= 3.0))
(pbrt_services
(>= 3.0))))

(package
(name grpc-examples)
(synopsis "Various gRPC examples")
Expand Down
42 changes: 42 additions & 0 deletions grpc-protoc.opam
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
# This file is generated by dune, edit dune-project instead
opam-version: "2.0"
synopsis: "An implementation of gRPC using ocaml-protoc"
description:
"Functionality for building gRPC services and rpcs with `ocaml-protoc`"
maintainer: ["Daniel Quernheim <grpc@quernd.uber.space>"]
authors: [
"Andrew Jeffery <dev@jeffas.io>"
"Daniel Quernheim <quernd@users.noreply.github.com>"
"Michael Bacarella <m@bacarella.com>"
"Sven Anderson <sven@anderson.de>"
"Tim McGilchrist <timmcgil@gmail.com>"
"Wojtek Czekalski <me@wczekalski.com>"
"dimitris.mostrous <dimitris.mostrous@gmail.com>"
]
license: "BSD-3-Clause"
homepage: "https://github.com/dialohq/ocaml-grpc"
doc: "https://dialohq.github.io/ocaml-grpc"
bug-reports: "https://github.com/dialohq/ocaml-grpc/issues"
depends: [
"dune" {>= "3.7"}
"grpc" {= version}
"ocaml-protoc" {>= "3.0"}
"pbrt" {>= "3.0"}
"pbrt_services" {>= "3.0"}
"odoc" {with-doc}
]
build: [
["dune" "subst"] {dev}
[
"dune"
"build"
"-p"
name
"-j"
jobs
"@install"
"@runtest" {with-test}
"@doc" {with-doc}
]
]
dev-repo: "git+https://github.com/dialohq/ocaml-grpc.git"
4 changes: 4 additions & 0 deletions lib/grpc-protoc/dune
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
(library
(name grpc_protoc)
(public_name grpc-protoc)
(libraries grpc ocaml-protoc pbrt pbrt_services))
55 changes: 55 additions & 0 deletions lib/grpc-protoc/grpc_protoc.ml
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
let encode (type a) (encode : a -> Pbrt.Encoder.t -> unit) (a : a) =
let encoder = Pbrt.Encoder.create () in
encode a encoder;
Pbrt.Encoder.to_string encoder

let decode (type a) (decode : Pbrt.Decoder.t -> a) buffer =
let decoder = Pbrt.Decoder.of_string buffer in
decode decoder

module Client_rpc = struct
let make (type request response)
(rpc : (request, _, response, _) Pbrt_services.Client.rpc) ~request_mode
~response_mode =
{
Grpc.Rpc.Client_rpc.service_spec =
{ package = rpc.package; service_name = rpc.service_name };
rpc_name = rpc.rpc_name;
encode_request = encode rpc.encode_pb_req;
decode_response = decode rpc.decode_pb_res;
request_mode;
response_mode;
}

let unary rpc = make rpc ~request_mode:Unary ~response_mode:Unary
let client_streaming rpc = make rpc ~request_mode:Stream ~response_mode:Unary
let server_streaming rpc = make rpc ~request_mode:Unary ~response_mode:Stream

let bidirectional_streaming rpc =
make rpc ~request_mode:Stream ~response_mode:Stream
end

module Server_rpc = struct
let make (type request response)
(rpc : (request, _, response, _) Pbrt_services.Server.rpc) ~request_mode
~response_mode =
{
Grpc.Rpc.Server_rpc.service_spec = None;
rpc_name = rpc.name;
decode_request = decode rpc.decode_pb_req;
encode_response = encode rpc.encode_pb_res;
request_mode;
response_mode;
}

let unary rpc = make rpc ~request_mode:Unary ~response_mode:Unary
let client_streaming rpc = make rpc ~request_mode:Stream ~response_mode:Unary
let server_streaming rpc = make rpc ~request_mode:Unary ~response_mode:Stream

let bidirectional_streaming rpc =
make rpc ~request_mode:Stream ~response_mode:Stream
end

let handlers { Pbrt_services.Server.package; service_name; handlers } =
Grpc.Rpc.Handlers.With_service_spec
{ service_spec = { package; service_name }; handlers }
116 changes: 116 additions & 0 deletions lib/grpc-protoc/grpc_protoc.mli
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
(** A utility library for constructing gRPC specifications using [Ocaml_protoc].
This module is designed to work alongside [Ocaml_protoc] to generate gRPC
stubs, as outlined in {!module:Grpc.Rpc}. It offers a collection of helper
functions that construct gRPC specifications from the code produced by
[Ocaml_protoc] based on the services defined in *.proto files. *)

(** {1 Client side} *)

module Client_rpc : sig
val unary :
( 'request,
Pbrt_services.Value_mode.unary,
'response,
Pbrt_services.Value_mode.unary )
Pbrt_services.Client.rpc ->
( 'request,
Grpc.Rpc.Value_mode.unary,
'response,
Grpc.Rpc.Value_mode.unary )
Grpc.Rpc.Client_rpc.t

val client_streaming :
( 'request,
Pbrt_services.Value_mode.stream,
'response,
Pbrt_services.Value_mode.unary )
Pbrt_services.Client.rpc ->
( 'request,
Grpc.Rpc.Value_mode.stream,
'response,
Grpc.Rpc.Value_mode.unary )
Grpc.Rpc.Client_rpc.t

val server_streaming :
( 'request,
Pbrt_services.Value_mode.unary,
'response,
Pbrt_services.Value_mode.stream )
Pbrt_services.Client.rpc ->
( 'request,
Grpc.Rpc.Value_mode.unary,
'response,
Grpc.Rpc.Value_mode.stream )
Grpc.Rpc.Client_rpc.t

val bidirectional_streaming :
( 'request,
Pbrt_services.Value_mode.stream,
'response,
Pbrt_services.Value_mode.stream )
Pbrt_services.Client.rpc ->
( 'request,
Grpc.Rpc.Value_mode.stream,
'response,
Grpc.Rpc.Value_mode.stream )
Grpc.Rpc.Client_rpc.t
end

(** {1 Server side} *)

module Server_rpc : sig
val unary :
( 'request,
Pbrt_services.Value_mode.unary,
'response,
Pbrt_services.Value_mode.unary )
Pbrt_services.Server.rpc ->
( 'request,
Grpc.Rpc.Value_mode.unary,
'response,
Grpc.Rpc.Value_mode.unary,
unit )
Grpc.Rpc.Server_rpc.t

val client_streaming :
( 'request,
Pbrt_services.Value_mode.stream,
'response,
Pbrt_services.Value_mode.unary )
Pbrt_services.Server.rpc ->
( 'request,
Grpc.Rpc.Value_mode.stream,
'response,
Grpc.Rpc.Value_mode.unary,
unit )
Grpc.Rpc.Server_rpc.t

val server_streaming :
( 'request,
Pbrt_services.Value_mode.unary,
'response,
Pbrt_services.Value_mode.stream )
Pbrt_services.Server.rpc ->
( 'request,
Grpc.Rpc.Value_mode.unary,
'response,
Grpc.Rpc.Value_mode.stream,
unit )
Grpc.Rpc.Server_rpc.t

val bidirectional_streaming :
( 'request,
Pbrt_services.Value_mode.stream,
'response,
Pbrt_services.Value_mode.stream )
Pbrt_services.Server.rpc ->
( 'request,
Grpc.Rpc.Value_mode.stream,
'response,
Grpc.Rpc.Value_mode.stream,
unit )
Grpc.Rpc.Server_rpc.t
end

val handlers : 'a Pbrt_services.Server.t -> (_, 'a) Grpc.Rpc.Handlers.t

0 comments on commit 027e57e

Please sign in to comment.