I’m going to show you how to create a gRPC Java Hello World example that uses Maven and Spring Boot.
(Step-by-step)
So if you’re new to gRPC, you’ll love this guide.
Let’s dive right in.
1. What Is gRPC?
gRPC is a high performance, open-source universal RPC framework. By default it uses Protocol Buffers to define exposed services.
The framework provides features such as bidirectional streaming and has support for many different programming languages.
gRPC was initially developed at Google and is now licensed under Apache 2.0.
To show how gRPC works let’s build a client and corresponding server that exposes a simple Hello World gRPC service.
2. Defining a Service Using Protocol Buffers
gRPC services are defined using protocol buffers. These are Google’s language-neutral, platform-neutral, extensible mechanism for serializing structured data.
You specify how you want the information you’re serializing to be structured by defining protocol buffer message types in .proto files. Each protocol buffer message is a small logical record of information, containing a series of name-value pairs.
For this example, we define a first message containing information about a Person and a second message containing a Greeting. Both are then used in a sayHello() RPC method that takes the person message from the client and returns a greeting from the server.
We also define the version of the protocol buffers language that is used (proto3) in addition to package name and an option that enables the generation of separate files for different classes.
For more information check the protocol buffers language guide.
The below protocol buffer file is stored in src/main/proto/HelloWorld.proto.
Now that we have defined how the data is structured we need to generate source code that allows us to easily write and read protobuf messages using Java. We will do this in the next section using a Maven plugin.
3. General Project Setup
We will use the following tools/frameworks:
- gRPC 1.16
- Spring Boot 2.1
- Maven 3.5
Our project has the following directory structure:
4. Maven Setup
We build and run our example using Maven. If not already the case make sure to download and install Apache Maven.
Shown below is the XML representation of our Maven project in a POM file. It contains the needed dependencies for compiling and running the example.
In order to configure and expose the Hello World gRPC service endpoint, we will use the Spring Boot project.
To facilitate the management of the different Spring dependencies, Spring Boot Starters are used. These are a set of convenient dependency descriptors that you can include in your application.
We include the spring-boot-starter-web
dependency which automatically sets up an embedded Apache Tomcat that will host our gRPC service endpoint.
The spring-boot-starter-test
includes the dependencies for testing Spring Boot applications with libraries that include JUnit, Hamcrest and Mockito.
The Spring boot starter for gRPC framework auto-configures and runs an embedded gRPC server with @GRpcService
enabled Beans as part of a Spring Boot application. The starter supports both Spring Boot version 1.5.X and 2.X.X. We enable it by including the grpc-spring-boot-starter
dependency.
Protocol buffers support generated code in a number of programming languages. This tutorial focuses on Java.
There are multiple ways to generate the protobuf-based code and in this example we will use the protobuf-maven-plugin as documented on the grpc-java GitHub page.
We also include the os-maven-plugin extension that generates various useful platform-dependent project properties. This information is needed as the Protocol Buffer compiler is native code. In other words, the protobuf-maven-plugin
needs to fetch the correct compiler for the platform it is running on.
Finally, the plugins section includes the spring-boot-maven-plugin
. This allows us to build a single, runnable uber-jar. This is a convenient way to execute and transport our code. Also, the plugin allows us to start the example via a Maven command.
The protobuf-maven-plugin
will generate Java artifacts for the HelloWorld.proto file located in src/main/proto/ (this is the default location the plugin uses).
Execute following Maven command, and the different message and service classes should be generated under target/generated-sources/protobuf/.
5. Spring Boot Setup
Create a SpringGrpcApplication
that contains a main()
method that uses Spring Boot’s SpringApplication.run()
method to bootstrap the application, starting Spring.
Note that
@SpringBootApplication
is a convenience annotation that adds:@Configuration
,@EnableAutoConfiguration
, and@ComponentScan
.
For more information on Spring Boot, we refer to the Spring Boot getting started guide.
6. Creating the Server
The service implementation is defined in the HelloWorldServiceImpl
POJO that implements the HelloWorldServiceImplBase
class that was generated from the HelloWorld.proto file.
We override the sayHello()
method and generate a Greeting
response based on the first and last name of the Person
passed in the request.
Note that the response is a
StreamObserver
object. In other words, the service is by default asynchronous. Whether you want to block or not when receiving the response(s) is the decision of the client as we will see further below.
We use the response observer’s onNext()
method to return the Greeting
and then call the response observer’s onCompleted()
method to tell gRPC that we’ve finished writing responses.
The HelloWorldServiceImpl
POJO is annotated with @GRpcService
which auto-configures the specified gRPC service to be exposed on port 6565.
7. Creating the Client
The client code is specified in the HelloWorldClient
class.
We annotate the client with @Component
which will cause Spring to automatically create and import below bean into the container if automatic component scanning is enabled (adding the @SpringBootApplication
annotation to the main SpringWsApplication
class is equivalent to using @ComponentScan
).
To call gRPC service methods, we first need to create a stub.
There are two types of stubs available:
- A blocking/synchronous stub that will wait for the server to respond
- A non-blocking/asynchronous stub that makes non-blocking calls to the server, where the response is returned asynchronously.
In this example, we will implement a blocking stub.
In order to transport messages, gRPC uses http/2 and some abstraction layers in between. This complexity is hidden behind a MessageChannel
that handles the connectivity. The general recommendation is to use one channel per application and share it among service stubs.
We use an init()
method annotated with @PostConstruct
in order to build a new MessageChannel
right after the after the bean has been initialized. The channel is then used to create the helloWorldServiceBlockingStub
stub.
gRPC by default uses a secure connection mechanism such as TLS. As this is a simple development test will use
usePlaintext()
in order to avoid having to configure the different security artifacts such as key/trust stores.
The sayHello()
method creates a Person object using the Builder pattern on which we set the ‘firstname’ and ‘lastname’ input parameters.
The helloWorldServiceBlockingStub
is then used to send the request towards the Hello World gRPC service. The result is a Greeting
object from which we return the containing message.
8. gRPC Java Testing
Let’s wrap up by creating a basic unit test case in which the above client is used to send a request to the gRPC Hello World service endpoint. We then verify if the response is equal to the expected greeting.
The @RunWith
and @SpringBootTest
testing annotations, that were introduced with Spring Boot 1.4, are used to tell JUnit to run using Spring’s testing support and bootstrap with Spring Boot’s support.
The HelloWorldClient
Bean is auto-wired so we can use it in the test case. The service itself is automatically started by the @SpringBootTest
annotation.
All that is left to do is to compare the received result to the expected greeting message using an assert statement.
Run the above test case. Open a command prompt in the projects root folder and execute following Maven command:
The result should be a successful build during which the gRPC server is started and a call is made to the Hello World service.
If you just want to start Spring Boot so that the service endpoint is up and running, execute following Maven command:
If you would like to run the above code sample you can get the full source code here.
In this tutorial you learned how to implement a gRPC Java service and corresponding client using Spring Boot and Maven.
If you liked this example or have a question you would like to ask:
Leave a comment below.
Thanks!
原创文章,作者:ItWorker,如若转载,请注明出处:https://blog.ytso.com/271576.html