gRPC with Spring Boot Path I

Chiwa Kantawong (Pea)
4 min readAug 31, 2021
https://grpc.io/docs/what-is-grpc/introduction/
https://grpc.io/docs/what-is-grpc/introduction/

gRPC (Google Protocol RPC) เป็น open source framework ที่ทำงานได้รวดเร็วมากของ google
RPC (อาร์พีซี) ย่อมาจากคำว่า “Remote Procedure Call (รีโมท โพรซีเดอร์ คอล)” เป็นโปรโตคอลตัวหนึ่งทำหน้าที่เรียกขอใช้บริการและตอบรับคำขอใช้บริการ procedure (โพรซีเดอร์) หรือโปรแกรมที่อยู่บนคอมพิวเตอร์เครื่องอื่นในเครือข่ายเดียวกันรวมถึงยังเป็นโปรโตคอลที่มีรูปแบบโครงสร้างแบบ ลูกข่าย/แม่ข่าย

อ่านรายละเอียดได้ที่ https://www.grpc.io/

เรามาสร้าง project กันครับ

เปิด Project มา เราจะสร้าง module สอง ตัวคือ grpc-common และ grpc-service

แก้ pom

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<packaging>pom</packaging>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.5.4</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.zengcode</groupId>
<artifactId>grpc-demo</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>grpc-demo</name>
<modules>
<module>grpc-common</module>
<module>grpc-service</module>
</modules>
</project>

แก้ pom ของ grpc-common

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>grpc-demo</artifactId>
<groupId>com.zengcode</groupId>
<version>0.0.1-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>

<artifactId>grpc-common</artifactId>
<properties>
<protobuf.version>3.14.0</protobuf.version>
<protobuf-plugin.version>0.6.1</protobuf-plugin.version>
<grpc.version>1.35.0</grpc.version>
<java.version>11</java.version>
<maven.compiler.source>11</maven.compiler.source>
<maven.compiler.target>11</maven.compiler.target>
</properties>

<dependencies>
<dependency>
<groupId>io.grpc</groupId>
<artifactId>grpc-stub</artifactId>
<version>1.35.0</version>
</dependency>
<dependency>
<groupId>io.grpc</groupId>
<artifactId>grpc-protobuf</artifactId>
<version>1.35.0</version>
</dependency>
<dependency>
<groupId>jakarta.annotation</groupId>
<artifactId>jakarta.annotation-api</artifactId>
<version>1.3.5</version>
<optional>true</optional>
</dependency>
</dependencies>

<build>
<extensions>
<extension>
<groupId>kr.motd.maven</groupId>
<artifactId>os-maven-plugin</artifactId>
<version>1.6.2</version>
</extension>
</extensions>

<plugins>
<plugin>
<groupId>org.xolstice.maven.plugins</groupId>
<artifactId>protobuf-maven-plugin</artifactId>
<version>0.6.1</version>
<configuration>
<protocArtifact>com.google.protobuf:protoc:${protobuf.version}:exe:osx-x86_64</protocArtifact>
<pluginId>grpc-java</pluginId>
<pluginArtifact>io.grpc:protoc-gen-grpc-java:${grpc.version}:exe:osx-x86_64</pluginArtifact>
</configuration>
<executions>
<execution>
<goals>
<goal>compile</goal>
<goal>compile-custom</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>

</project>

ต่อไปมา define service กันครับ โดยการระบุ method ที่สามารถ remote call ได้

syntax = "proto3";

package com.zengcode.grpc;

option java_multiple_files = true;
option java_package = "com.zengcode.grpc";

service ZengcodeService {
rpc hello(ZengcodeRequest) returns (ZengcodeResponse) {
}
}

message ZengcodeRequest {
string message = 1;
}

message ZengcodeResponse {
string message = 1;
}

เมื่อเรา compile ตัว plugin จะมาอ่านไฟล์นี้ เพื่อสร้าง Java class ที่จำเป็นต่อการใช้งานให้เราอัตโนมัต

โดยจะสร้าง ZengcodeService และ method hello ส่ง payload เป็น ZengcodeRequest และ Response เป็น ZengcodeResponse กลับมาให้

ที่ Terminal ไปที่ folder grpc-common

grpc-common > mvn clean install

Maven จะสร้าง classes ต่างๆ ให้เราครับ

ต่อไปเรามาสร้าง gRPC Service กัน แก้ pom ที่ grpc-service

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>grpc-demo</artifactId>
<groupId>com.zengcode</groupId>
<version>0.0.1-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>

<artifactId>grpc-service</artifactId>
<dependencies>

<dependency>
<groupId>net.devh</groupId>
<artifactId>grpc-server-spring-boot-starter</artifactId>
<version>2.12.0.RELEASE</version>
</dependency>

<dependency>
<groupId>com.zengcode</groupId>
<artifactId>grpc-common</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>

<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>

<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>

</project>

เพิ่ม

package com.zengcode.grpc;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class GrpcSpringBootExampleApplication {

public static void main(String[] args) {
SpringApplication.run(GrpcSpringBootExampleApplication.class, args);
}

}

ต่อไปสร้าง Implementation ของ gRPC ที่เรา Defined ไว้ใน grpc-common กันครับ

package com.zengcode.grpc.service;


import com.zengcode.grpc.ZengcodeRequest;
import com.zengcode.grpc.ZengcodeResponse;
import com.zengcode.grpc.ZengcodeServiceGrpc;
import io.grpc.stub.StreamObserver;
import net.devh.boot.grpc.server.service.GrpcService;

@GrpcService
public class ZencodeGrpcImpl extends ZengcodeServiceGrpc.ZengcodeServiceImplBase {

@Override
public void hello(ZengcodeRequest request, StreamObserver<ZengcodeResponse> responseObserver) {
String message = request.getMessage();
System.out.println("Received Message: " + message);


ZengcodeResponse zengcodeResponse = ZengcodeResponse.newBuilder()
.setMessage("Received message : " + message + " From Server. ")
.build();

responseObserver.onNext(zengcodeResponse);
responseObserver.onCompleted();
}

}

เสร็จแล้วมาลองรันกันดูครับ

ต่อไปลองเรียก gRPC ที่เราสร้างขึ้นกันครับ เราจะเรียกผ่าน grpcurl ทาง Terminal นะครับ สำหรับ max รัน

> brew install grpcurl

ลองเรียกดูเลยครับ ตื่นเต้นๆ

จะเห็นว่า มี ZengcodeService ที่เราสร้างขึ้นมา มาลองเรียกใช้ดูครับ

สำเร็จแล้วครับ

ลองไปศึกษาเพิ่มเติมนะครับ

ไปสร้าง gRPC Client กันครับ https://zengcode.medium.com/grpc-with-spring-boot-path-ii-83a42349f334

--

--