Skip to content

Commit 027e57e

Browse files
committed
Add helper library for using typed-rpc with ocaml-protoc
1 parent 394edb5 commit 027e57e

File tree

5 files changed

+232
-0
lines changed

5 files changed

+232
-0
lines changed

dune-project

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,21 @@
107107
(ocaml-protoc-plugin
108108
(>= 4.5))))
109109

110+
(package
111+
(name grpc-protoc)
112+
(synopsis "An implementation of gRPC using ocaml-protoc")
113+
(description
114+
"Functionality for building gRPC services and rpcs with `ocaml-protoc`")
115+
(depends
116+
(grpc
117+
(= :version))
118+
(ocaml-protoc
119+
(>= 3.0))
120+
(pbrt
121+
(>= 3.0))
122+
(pbrt_services
123+
(>= 3.0))))
124+
110125
(package
111126
(name grpc-examples)
112127
(synopsis "Various gRPC examples")

grpc-protoc.opam

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
# This file is generated by dune, edit dune-project instead
2+
opam-version: "2.0"
3+
synopsis: "An implementation of gRPC using ocaml-protoc"
4+
description:
5+
"Functionality for building gRPC services and rpcs with `ocaml-protoc`"
6+
maintainer: ["Daniel Quernheim <[email protected]>"]
7+
authors: [
8+
"Andrew Jeffery <[email protected]>"
9+
"Daniel Quernheim <[email protected]>"
10+
"Michael Bacarella <[email protected]>"
11+
"Sven Anderson <[email protected]>"
12+
"Tim McGilchrist <[email protected]>"
13+
"Wojtek Czekalski <[email protected]>"
14+
"dimitris.mostrous <[email protected]>"
15+
]
16+
license: "BSD-3-Clause"
17+
homepage: "https://github.com/dialohq/ocaml-grpc"
18+
doc: "https://dialohq.github.io/ocaml-grpc"
19+
bug-reports: "https://github.com/dialohq/ocaml-grpc/issues"
20+
depends: [
21+
"dune" {>= "3.7"}
22+
"grpc" {= version}
23+
"ocaml-protoc" {>= "3.0"}
24+
"pbrt" {>= "3.0"}
25+
"pbrt_services" {>= "3.0"}
26+
"odoc" {with-doc}
27+
]
28+
build: [
29+
["dune" "subst"] {dev}
30+
[
31+
"dune"
32+
"build"
33+
"-p"
34+
name
35+
"-j"
36+
jobs
37+
"@install"
38+
"@runtest" {with-test}
39+
"@doc" {with-doc}
40+
]
41+
]
42+
dev-repo: "git+https://github.com/dialohq/ocaml-grpc.git"

lib/grpc-protoc/dune

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
(library
2+
(name grpc_protoc)
3+
(public_name grpc-protoc)
4+
(libraries grpc ocaml-protoc pbrt pbrt_services))

lib/grpc-protoc/grpc_protoc.ml

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
let encode (type a) (encode : a -> Pbrt.Encoder.t -> unit) (a : a) =
2+
let encoder = Pbrt.Encoder.create () in
3+
encode a encoder;
4+
Pbrt.Encoder.to_string encoder
5+
6+
let decode (type a) (decode : Pbrt.Decoder.t -> a) buffer =
7+
let decoder = Pbrt.Decoder.of_string buffer in
8+
decode decoder
9+
10+
module Client_rpc = struct
11+
let make (type request response)
12+
(rpc : (request, _, response, _) Pbrt_services.Client.rpc) ~request_mode
13+
~response_mode =
14+
{
15+
Grpc.Rpc.Client_rpc.service_spec =
16+
{ package = rpc.package; service_name = rpc.service_name };
17+
rpc_name = rpc.rpc_name;
18+
encode_request = encode rpc.encode_pb_req;
19+
decode_response = decode rpc.decode_pb_res;
20+
request_mode;
21+
response_mode;
22+
}
23+
24+
let unary rpc = make rpc ~request_mode:Unary ~response_mode:Unary
25+
let client_streaming rpc = make rpc ~request_mode:Stream ~response_mode:Unary
26+
let server_streaming rpc = make rpc ~request_mode:Unary ~response_mode:Stream
27+
28+
let bidirectional_streaming rpc =
29+
make rpc ~request_mode:Stream ~response_mode:Stream
30+
end
31+
32+
module Server_rpc = struct
33+
let make (type request response)
34+
(rpc : (request, _, response, _) Pbrt_services.Server.rpc) ~request_mode
35+
~response_mode =
36+
{
37+
Grpc.Rpc.Server_rpc.service_spec = None;
38+
rpc_name = rpc.name;
39+
decode_request = decode rpc.decode_pb_req;
40+
encode_response = encode rpc.encode_pb_res;
41+
request_mode;
42+
response_mode;
43+
}
44+
45+
let unary rpc = make rpc ~request_mode:Unary ~response_mode:Unary
46+
let client_streaming rpc = make rpc ~request_mode:Stream ~response_mode:Unary
47+
let server_streaming rpc = make rpc ~request_mode:Unary ~response_mode:Stream
48+
49+
let bidirectional_streaming rpc =
50+
make rpc ~request_mode:Stream ~response_mode:Stream
51+
end
52+
53+
let handlers { Pbrt_services.Server.package; service_name; handlers } =
54+
Grpc.Rpc.Handlers.With_service_spec
55+
{ service_spec = { package; service_name }; handlers }

lib/grpc-protoc/grpc_protoc.mli

Lines changed: 116 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,116 @@
1+
(** A utility library for constructing gRPC specifications using [Ocaml_protoc].
2+
3+
This module is designed to work alongside [Ocaml_protoc] to generate gRPC
4+
stubs, as outlined in {!module:Grpc.Rpc}. It offers a collection of helper
5+
functions that construct gRPC specifications from the code produced by
6+
[Ocaml_protoc] based on the services defined in *.proto files. *)
7+
8+
(** {1 Client side} *)
9+
10+
module Client_rpc : sig
11+
val unary :
12+
( 'request,
13+
Pbrt_services.Value_mode.unary,
14+
'response,
15+
Pbrt_services.Value_mode.unary )
16+
Pbrt_services.Client.rpc ->
17+
( 'request,
18+
Grpc.Rpc.Value_mode.unary,
19+
'response,
20+
Grpc.Rpc.Value_mode.unary )
21+
Grpc.Rpc.Client_rpc.t
22+
23+
val client_streaming :
24+
( 'request,
25+
Pbrt_services.Value_mode.stream,
26+
'response,
27+
Pbrt_services.Value_mode.unary )
28+
Pbrt_services.Client.rpc ->
29+
( 'request,
30+
Grpc.Rpc.Value_mode.stream,
31+
'response,
32+
Grpc.Rpc.Value_mode.unary )
33+
Grpc.Rpc.Client_rpc.t
34+
35+
val server_streaming :
36+
( 'request,
37+
Pbrt_services.Value_mode.unary,
38+
'response,
39+
Pbrt_services.Value_mode.stream )
40+
Pbrt_services.Client.rpc ->
41+
( 'request,
42+
Grpc.Rpc.Value_mode.unary,
43+
'response,
44+
Grpc.Rpc.Value_mode.stream )
45+
Grpc.Rpc.Client_rpc.t
46+
47+
val bidirectional_streaming :
48+
( 'request,
49+
Pbrt_services.Value_mode.stream,
50+
'response,
51+
Pbrt_services.Value_mode.stream )
52+
Pbrt_services.Client.rpc ->
53+
( 'request,
54+
Grpc.Rpc.Value_mode.stream,
55+
'response,
56+
Grpc.Rpc.Value_mode.stream )
57+
Grpc.Rpc.Client_rpc.t
58+
end
59+
60+
(** {1 Server side} *)
61+
62+
module Server_rpc : sig
63+
val unary :
64+
( 'request,
65+
Pbrt_services.Value_mode.unary,
66+
'response,
67+
Pbrt_services.Value_mode.unary )
68+
Pbrt_services.Server.rpc ->
69+
( 'request,
70+
Grpc.Rpc.Value_mode.unary,
71+
'response,
72+
Grpc.Rpc.Value_mode.unary,
73+
unit )
74+
Grpc.Rpc.Server_rpc.t
75+
76+
val client_streaming :
77+
( 'request,
78+
Pbrt_services.Value_mode.stream,
79+
'response,
80+
Pbrt_services.Value_mode.unary )
81+
Pbrt_services.Server.rpc ->
82+
( 'request,
83+
Grpc.Rpc.Value_mode.stream,
84+
'response,
85+
Grpc.Rpc.Value_mode.unary,
86+
unit )
87+
Grpc.Rpc.Server_rpc.t
88+
89+
val server_streaming :
90+
( 'request,
91+
Pbrt_services.Value_mode.unary,
92+
'response,
93+
Pbrt_services.Value_mode.stream )
94+
Pbrt_services.Server.rpc ->
95+
( 'request,
96+
Grpc.Rpc.Value_mode.unary,
97+
'response,
98+
Grpc.Rpc.Value_mode.stream,
99+
unit )
100+
Grpc.Rpc.Server_rpc.t
101+
102+
val bidirectional_streaming :
103+
( 'request,
104+
Pbrt_services.Value_mode.stream,
105+
'response,
106+
Pbrt_services.Value_mode.stream )
107+
Pbrt_services.Server.rpc ->
108+
( 'request,
109+
Grpc.Rpc.Value_mode.stream,
110+
'response,
111+
Grpc.Rpc.Value_mode.stream,
112+
unit )
113+
Grpc.Rpc.Server_rpc.t
114+
end
115+
116+
val handlers : 'a Pbrt_services.Server.t -> (_, 'a) Grpc.Rpc.Handlers.t

0 commit comments

Comments
 (0)