Server Reflection
This feature is experimental (Issue #850).
It implements version v1alpha of the upstream standard, so we might expect subsequent versions of the service to emerge. Also, the Java/Scala API’s to enable this feature may still change in further versions of Akka gRPC, and future versions of this feature may not work with services generated with older versions of Akka gRPC.
There may be missing features and bugs in the current implementation. If you encounter any, you are welcome to share a reproducer in our issue tracker.
Server Reflection is a gRPC feature that allows ‘dynamic’ clients, such as command-line tools for debugging, to discover the protocol used by a gRPC server at run time. They can then use this metadata to implement things like completion and sending arbitrary commands.
This is achieved by providing a gRPC service that provides endpoints that can be used to query this information
Providing
When providing gRPC Server Reflection, you will be serving multiple services (at least your own service and the reflection service) as described here. The reflection service can be generated via ServerReflection
:
- Scala
-
source
import akka.http.scaladsl._ import akka.http.scaladsl.model._ import akka.grpc.scaladsl.ServiceHandler import akka.grpc.scaladsl.ServerReflection import example.myapp.helloworld.grpc._ // Create service handlers val greeter: PartialFunction[HttpRequest, Future[HttpResponse]] = GreeterServiceHandler.partial(new GreeterServiceImpl()) val reflection: PartialFunction[HttpRequest, Future[HttpResponse]] = ServerReflection.partial(List(GreeterService)) // Bind service handler servers to localhost:8080 val binding = Http().bindAndHandleAsync( ServiceHandler.concatOrNotFound(greeter, reflection), interface = "127.0.0.1", port = 8080, connectionContext = HttpConnectionContext())
- Java
-
source
import java.util.Arrays; import akka.grpc.javadsl.ServiceHandler; import akka.grpc.javadsl.ServerReflection; import akka.http.javadsl.*; import example.myapp.helloworld.grpc.*; // Instantiate implementation GreeterService impl = new GreeterServiceImpl(); // Bind service handler servers to localhost:8080 return Http.get(sys) .newServerAt("127.0.0.1", 8080) .bind( ServiceHandler.concatOrNotFound( GreeterServiceHandlerFactory.create(impl, sys), ServerReflection.create(Arrays.asList(GreeterService.description), sys) ) );
Consuming
The Server Reflection endpoint exposed above can be used for example to consume the service with grpc_cli:
$ ./bins/opt/grpc_cli call localhost:8080 helloworld.GreeterService.SayHello "name:\"foo\""
connecting to localhost:8080
Received initial metadata from server:
date : Wed, 08 Jan 2020 16:57:56 GMT
server : akka-http/10.1.10
message: "Hello, foo"
Received trailing metadata from server:
date : Wed, 08 Jan 2020 16:57:56 GMT
Rpc succeeded with OK status