gRPC
Experimental feature - it’s not complete and API may change
tapir supports currently defining and exposing gRPC endpoints. There is also a handy tool for generating proto files from these endpoints’ definitions.
Modules
protobuf
- contains a Protobuf protocol model and utilities that make generating proto files handy. This module should be used for generating proto files from endpoints definitionspbDirectProtobuf
- integration withPBDirect
library. Should be used for auto codecs derivation. Currently, it’s necessary to add this module for generating proto files with theprotobuf
module.akkaGrpcServer
- a module that providesAkkaGrpcServerInterpreter
implementation. It should be used to serve tapir grpc endpoints.grpcExamples
- contains example use cases
Defining endpoints
Every gRPC endpoint requires specifying the following values: service name, method name, input format, output format.
In tapir, we can simply pass service and method names as strings separated with /
to the tapir endpoint input
definition e.g. endpoint.in("Library" / "AddBook")
where "Library"
is a service name and "AddBook"
is a method
name.
Definition of an endpoint’s inputs and output format is very similar to the one that we use for JSONs. We can use an
endpoint body constructor helper sttp.tapir.grpc.protobuf.pbdirect.grpcBody[T]
that based on the type T
create a
body definition that can be passed to as input or output of a given endpoint
e.g. endpoint.in(grpcBody[AddSimpleBook]).out(grpcBody[SimpleBook])
.
Currently, the only supported protocol is protobuf. On the server side, we use a PBDirect library for encoding and decoding messages. It derives codecs from a class definition which means we do not depend on the generated code from a proto file.
The grpcBody
function takes as an implicit param tapir schema definition, that is used to generate a proto file, and
PBDirect codecs for a given type.
Currently, we don’t support passing any metadata.
Generating proto file
With defined endpoints, we can move towards generating a proto file that we could use to generate clients for our API.
The easiest way to do it is by using a built-in ProtoSchemaGenerator
. We need to only choose a path for the file,
package name, pass endpoints definitions, and finally invoke the renderToFile
function e.g.
ProtoSchemaGenerator.renderToFile(
path = "grpc/examples/src/main/protobuf/main.proto",
packageName = "sttp.tapir.grpc.examples.gen",
endpoints = Endpoints.endpoints
)
gRPC server
With the proto file, we can generate clients for our API or the server-side code using ScalaPb library.
It’s possible to connect the generated server code to tapir endpoints definitions, but it’s not convenient since depends
on auto-generated code. We strongly recommend using the new dedicated server interpreter AkkaGrpcServerInterpreter
.
It’s built on top of AkkaHttpServerInterpreter
and provides support for encoding and decoding HTTP2 binary messages.
Here you can find a simple example.
It’s worth mentioning that by adjusting slightly encoders/decoders it’s possible to expose gRPC endpoints with
AkkaHttpServerInterpreter
as simple HTTP endpoints. This approach is not recommended, because it does not support
transmitting multiple messages in a single http request.