[JAVA] gRPC on Spring Boot with grpc-spring-boot-starter

This article is the third day of BrainPad Advent Calendar 2018.

Hello [@ nissy0409240] is (https://twitter.com/nissy0409240). I'm an engineer at BrainPad. It's been less than a month in 2018, How is everyone doing.

Although it is a private matter This year I was allowed to take the stage at PyCon 2018 image.png Watching C. Ronaldo's hat-trick locally at the World Cup image.png I had a valuable experience both publicly and privately.

At the end of 2018, when using gRPC that has nothing to do with the above written content in Spring Boot, I added something out of the ordinary and gRPC (because the amount of sentences is too small) in the first place. We will send you this entry.

What is gRPC?

First, let's talk about what gRPC is. gRPC is an RPC framework created by Google. This alone is a "what a mess" state, so I will also explain the RPC framework.

The official name of RPC for the RPC framework is "Remote Procedure Call". When translated, it becomes "remote procedure call". It allows you to call the methods described in an application running on a different server as if they were running on your server.

It's hard to get an image with just the letters, so let's take a look with the figure in the document of the gPRC head family.

image.png

The figure above shows a situation where a Ruby client and a Java client are calling a service written in C ++.

Benefits of using gRPC

In gRPC, by describing the implementation content that the service wants to provide in a definition file called a .proto file, a linkage module named stub that calls the service implementation from the client side is automatically generated. As a result, the interface specification definition file found in API linkage is always reflected in the implementation, so you can enjoy the following advantages.

--It is possible to share what type of data is exchanged between both the caller and the callee. --Since http2 + protocol buffers are used, it is possible to improve performance by API linkage. ――It is possible to proceed with microservices regardless of the language used by the caller / callee. --GRPC supports various languages, and most of the major languages used in Web development are already supported. スクリーンショット 2018-12-03 1.57.28.png

How to use gRPC

Add module to pom.xml

I would like to introduce how to use gRPC. However, it is difficult to convey with just the letters, and it is different for each language, so This time, I will use Java 8 + Spring Boot and proceed while actually moving my hands.

First, create a template product using Spring Initializer. Here is the composition of the template before it was created.

demo_protobuf


├── pom.xml
├── main
│   ├── java
│   │   └── com
│   │       └── example
│   │           └── demo_protobuf
│   │               └── DemoProtobufApplication.java
│   └── resources
│       └── application.properties
└── test
    └── java
        └── com
            └── example
                └── demo_protobuf
                    └── DemoProtobufApplicationTests.java

Next, I added a module to pom.xml, but this was a ridiculous part. We will discuss adding modules later, but first we will move on to the definition file.

How to create a definition file

Create a definition file when execution is complete. This time, I will write the definition in the src / main / proto / demo.proto file. The composition of the product at this point is as follows.

demo_protobuf


.
├── mvnw
├── mvnw.cmd
├── pom.xml
└── src
    ├── main
    │   ├── java
    │   │   └── com
    │   │       └── example
    │   │           └── demo_protobuf
    │   │               └── DemoProtobufApplication.java
    │   │           
    │   ├── proto
    │   │   └── demo.proto
    │   └── resources
    │       └── application.properties
    └── test
        └── java
            └── com
                └── example
                    └── demo_protobuf
                        └── DemoProtobufApplicationTests.java

In the created demo.proto, write as follows.

demo.proto


syntax = "proto3";

option java_multiple_files = true;
option java_package = "com.example.fizzbuzz";
option java_outer_classname = "FizzBuzzProto";

package calc;

//Defines a combination of return values and arguments for a service called Math
service Math {
    rpc Math (MathRequest) returns (IntResponse);
}

//Defines the type and number of return values when IntResponse is selected
message IntResponse {
    int32 value = 1;
}

//Defines the type and number of arguments when defining MathRequest
message MathRequest {
    int32 x = 1;
    int32 y = 2;
}

I'm sure some of you have pinned it, but in the .proto file "Which service receives what kind of request and what kind of return value is returned" is written. It just describes what type of data the .proto file exchanges with.

After writing, execute mvn clean install. After execution, the source code will be generated as follows. (Actually, more code will be generated, but I will omit it here)

.
├── mvnw
├── mvnw.cmd
├── pom.xml
├── src
│   ├── main
│   │   ├── java
│   │   │   └── com
│   │   │       └── example
│   │   │           └── demo_protobuf
│   │   │               └── DemoProtobufApplication.java
│   │   ├── proto
│   │   │   └── demo.proto
│   │   └── resources
│   │       └── application.properties
│   └── test
│       └── java
│           └── com
│               └── example
│                   └── demo_protobuf
│                       └── DemoProtobufApplicationTests.java
└── target
    └── generated-sources
        ├── annotations
        └── protobuf
            ├── grpc-java
            │   └── com
            │       └── example
            │           └── fizzbuzz
            │               └── MathGrpc.java
            └── java
                └── com
                    └── example
                        └── fizzbuzz
                            ├── FizzBuzzProto.java
                            ├── IntResponse.java
                            ├── IntResponseOrBuilder.java
                            ├── MathRequest.java
                            └── MathRequestOrBuilder.java

Code regeneration

But here I realized I made a mistake. Even though I stopped trying to use FizzBuzz at first and changed to Math I have generated some code with FizzBuzz. Would you like to discard the repository and recreate it? That's not true.

Rewrite the created demo.proto as follows

demo.proto


syntax = "proto3";

option java_multiple_files = true;
option java_package = "com.example.math";
option java_outer_classname = "MathProto";

package calc;

//Defines a combination of return values and arguments for a service called Math
service Math {
    rpc Math (MathRequest) returns (IntResponse);
}

//Defines the type and number of return values when IntResponse is selected
message IntResponse {
    int32 value = 1;
}

//Defines the type and number of arguments when defining MathRequest
message MathRequest {
    int32 x = 1;
    int32 y = 2;
}

Run mvn clean install.

.
├── mvnw
├── mvnw.cmd
├── pom.xml
├── src
│   ├── main
│   │   ├── java
│   │   │   └── com
│   │   │       └── example
│   │   │           └── demo_protobuf
│   │   │               └── DemoProtobufApplication.java
│   │   ├── proto
│   │   │   └── demo.proto
│   │   └── resources
│   │       └── application.properties
│   └── test
│       └── java
│           └── com
│               └── example
│                   └── demo_protobuf
│                       └── DemoProtobufApplicationTests.java
└── target
    └── generated-sources
        ├── annotations
        └── protobuf
            ├── grpc-java
            │   └── com
            │       └── example
            │           └── math
            │               └── MathGrpc.java
            └── java
                └── com
                    └── example
                        └── math
                            ├── MathProto.java
                            ├── IntResponse.java
                            ├── IntResponseOrBuilder.java
                            ├── MathRequest.java
                            └── MathRequestOrBuilder.java

The code under target has been reworked. You can also see that this method is good when you want to update demo.proto.

All you have to do is inherit the generated code and create the service and client.

What I got stuck when adding a module to pom.xml

Since I touched on a series of flows, I would like to introduce what I got stuck in here. To put it simply, "Be careful because the groupId of the module is different from the content that appears in the Maven Repository."

What is Maven Repository in the first place? As many of you may know, this is a site that must tell you what to write when importing middleware. In the case of other languages, Python's PyPi is similar.

And there are many so-called starters that are all-in-one tools that support the framework called Spring Boot. For example, use Spring Boot Security Starter when creating an authentication module.

Until now, when using gRPC with Spring Boot, it was written as follows.

pom.xml


<!-- https://mvnrepository.com/artifact/org.lognet/grpc-spring-boot-starter -->
<dependency>
    <groupId>org.lognet</groupId>
    <artifactId>grpc-spring-boot-starter</artifactId>
    <version>2.3.2</version>
</dependency>

However, when the latest version of this module was updated to 3 series, the groupId changed from "org.lognet" to "org.github.lognet", so not only the version but also the groupId had to be changed. I did.

The same information as above can be found in the grpc-spring-boot-starter repository. スクリーンショット 2018-12-04 2.25.34.png

Therefore, it is necessary to describe as follows from now on.

pomxml


<dependency>
    <groupId>io.github.lognet</groupId>
    <artifactId>grpc-spring-boot-starter</artifactId>
    <version>3.0.0</version>
</dependency>

Please note that if you leave the groupId uncorrected, the following error will occur at the time of mvn install.

[ERROR] Failed to execute goal on project demo_protobuf: Could not resolve dependencies for project com.example:demo_protobuf:jar:1.16.1: Failure to find org.lognet:grpc-spring-boot-starter:jar:3.0.0 in https://repo.maven.apache.org/maven2 was cached in the local repository, resolution will not be reattempted until the update interval of central has elapsed or updates are forced -> [Help 1]
[ERROR] 
[ERROR] To see the full stack trace of the errors, re-run Maven with the -e switch.
[ERROR] Re-run Maven using the -X switch to enable full debug logging.
[ERROR] 
[ERROR] For more information about the errors and possible solutions, please read the following articles:
[ERROR] [Help 1] http://cwiki.apache.org/confluence/display/MAVEN/DependencyResolutionException

Conclusion

Although the structure is a little strange, I would like to replace this entry with the hope that it will help those who are addicted to posting information with few Japanese entries along with an error message. I'm sorry that the text was disorganized, but thank you for staying with us until the end.

reference

https://qiita.com/nozaq/items/9cd9bf7ee6118779bda9 http://redj.hatenablog.com/entry/2017/10/13/084423 https://github.com/LogNet/grpc-spring-boot-starter https://kengotoda.gitbooks.io/what-is-maven/primer/maven-repository.html

Recommended Posts

gRPC on Spring Boot with grpc-spring-boot-starter
Download with Spring Boot
Generate barcode with Spring Boot
Hello World with Spring Boot
Spring Boot on Microsoft Azure
Implement GraphQL with Spring Boot
Get started with Spring boot
Hello World with Spring Boot!
Run LIFF with Spring Boot
SNS login with Spring Boot
File upload with Spring Boot
Spring Boot starting with copy
Spring Boot starting with Docker
Hello World with Spring Boot
Set cookies with Spring Boot
Use Spring JDBC with Spring Boot
Add module with Spring Boot
Getting Started with Spring Boot
Try Spring Boot on Mac
Create microservices with Spring Boot
Send email with spring boot
Create an app with Spring Boot 2
Hot deploy with Spring Boot development
Database linkage with doma2 (Spring boot)
Spring Boot programming with VS Code
Until "Hello World" with Spring Boot
Inquiry application creation with Spring Boot
Get validation results with Spring Boot
(Intellij) Hello World with Spring Boot
Create an app with Spring Boot
Google Cloud Platform with Spring Boot 2.0.0
Check date correlation with Spring Boot
I tried GraphQL with Spring Boot
[Java] LINE integration with Spring Boot
Try running Spring Boot on Kubernetes
Beginning with Spring Boot 0. Use Spring CLI
I tried Flyway with Spring Boot
Message cooperation started with Spring Boot
Spring Boot gradle build with Docker
Processing at application startup with Spring Boot
Create Spring Boot development environment on Vagrant
Spring Boot environment construction memo on mac
Hello World with Eclipse + Spring Boot + Maven
Send regular notifications with LineNotify + Spring Boot
Perform transaction confirmation test with Spring Boot
HTTPS with Spring Boot and Let's Encrypt
Try using Spring Boot with VS Code
Start web application development with Spring Boot
Launch Nginx + Spring Boot application with docker-compose
I tried Lazy Initialization with Spring Boot 2.2.0
Implement CRUD with Spring Boot + Thymeleaf + MySQL
Asynchronous processing with Spring Boot using @Async
Implement paging function with Spring Boot + Thymeleaf
(IntelliJ + gradle) Hello World with Spring Boot
Use cache with EhCashe 2.x with Spring Boot
Form class validation test with Spring Boot
Run WEB application with Spring Boot + Thymeleaf
Achieve BASIC authentication with Spring Boot + Spring Security
Challenge Spring Boot
Spring Boot Form
Spring Boot Memorandum