gRPC with Spring Boot Path I
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