This library allows to make a JSON encoded HTTP request to a gRPC service that is implemented in Java or Scala (using ScalaPB).
It provides an implementation-agnostic module for mapping to your favorite HTTP server (core
, core-scalapb
) as well as few implementations for direct usage in some well-known HTTP servers.
Standard GPB <-> JSON mapping is used.
The API is finally tagless (read more e.g. here) meaning it can use whatever F[_]: cats.effect.Effect
(e.g. cats.effect.IO
, monix.eval.Task
).
compile 'com.avast.grpc:grpc-json-bridge-core_2.12:x.x.x'
libraryDependencies += "com.avast.grpc" %% "grpc-json-bridge-core" % "x.x.x"
syntax = "proto3";
package com.avast.grpc.jsonbridge.test;
service TestService {
rpc Add (AddParams) returns (AddResponse) {}
}
message AddParams {
int32 a = 1;
int32 b = 2;
}
message AddResponse {
int32 sum = 1;
}
import com.avast.grpc.jsonbridge.ReflectionGrpcJsonBridge
// for whole server
val grpcServer: io.grpc.Server = ???
val bridge = ReflectionGrpcJsonBridge.createFromServer[Task](grpcServer)
// or for selected services
val s1: ServerServiceDefinition = ???
val s2: ServerServiceDefinition = ???
val anotherBridge = ReflectionGrpcJsonBridge.createFromServices[Task](s1, s2)
// call a method manually, with a header specified
val jsonResponse = bridge.invoke("com.avast.grpc.jsonbridge.test.TestService/Add", """ { "a": 1, "b": 2} """, Map("My-Header" -> "value"))
This usage supposes that the project uses standard gRPC Java class generation, using protoc-gen-grpc-java.
If the project uses ScalaPB to generate the classes then following dependency should used instead:
compile 'com.avast.grpc:grpc-json-bridge-core-scalapb_2.12:x.x.x'
libraryDependencies += "com.avast.grpc" %% "grpc-json-bridge-core-scalapb" % "x.x.x"
And ScalaPBReflectionGrpcJsonBridge
class must be used to create a new bridge.
compile 'com.avast.grpc:grpc-json-bridge-http4s_2.12:x.x.x'
libraryDependencies += "com.avast.grpc" %% "grpc-json-bridge-http4s" % "x.x.x"
import com.avast.grpc.jsonbridge.GrpcJsonBridge
import com.avast.grpc.jsonbridge.http4s.{Configuration, Http4s}
import org.http4s.HttpService
val bridge: GrpcJsonBridge[Task] = ???
val service: HttpService[Task] = Http4s(Configuration.Default)(bridge)
compile 'com.avast.grpc:grpc-json-bridge-akkahttp_2.12:x.x.x'
libraryDependencies += "com.avast.grpc" %% "grpc-json-bridge-akkahttp" % "x.x.x"
import com.avast.grpc.jsonbridge.GrpcJsonBridge
import com.avast.grpc.jsonbridge.akkahttp.{AkkaHttp, Configuration}
import akka.http.scaladsl.server.Route
val bridge: GrpcJsonBridge[Task] = ???
val route: Route = AkkaHttp(Configuration.Default)(bridge)
List all available methods:
> curl -X GET http://localhost:9999/
com.avast.grpc.jsonbridge.test.TestService/Add
List all methods from particular service:
> curl -X GET http://localhost:9999/com.avast.grpc.jsonbridge.test.TestService
com.avast.grpc.jsonbridge.test.TestService/Add
Call a method (please note that POST
and application/json
must be always specified):
> curl -X POST -H "Content-Type: application/json" --data ""{\"a\":1, \"b\": 2 }"" http://localhost:9999/com.avast.grpc.jsonbridge.test.TestService/Add
{"sum":3}