Spring Boot with gRPC[RU]

Alexander Uryadov
4 min readDec 4, 2022

--

После долгих поисков изящной и лаконичной реализации gRPC c Spring Boot и Gradle, прочтения документации, а также прибегая к помощи Stack Overflow (куда же без него) я все таки решился написать статью(english). Здесь я хотел бы описать только процесс создания сервера и клиента, не прибегая к теории и не объясняя что такое gRPC.

Чтобы перейти непосредственно к выполнению поставленной задачи вы должны иметь минимальные навыки работы со Spring Boot. Если читаете эту статью, вероятно, вы уже знакомы с вышеупомянутыми технологиями.

1. Сервер

1.1. Добавление зависимостей.

Для начала создадим Spring Boot проект и добавим в файл build.gradle плагин и одну зависимость.

Плагин:

id 'com.google.protobuf' version '0.8.19'

Зависимость:

implementation 'net.devh:grpc-server-spring-boot-starter:2.13.1.RELEASE'

Вот так будет выглядеть конечный файл build.gradle:

plugins {
id 'org.springframework.boot' version '2.7.4'
id 'io.spring.dependency-management' version '1.0.14.RELEASE'
id 'java'
id 'idea'
// protobuf plugin
id 'com.google.protobuf' version '0.8.19'
}

group = 'com.example'
version = '0.0.1-SNAPSHOT'
sourceCompatibility = '8'

repositories {
mavenCentral()
}

dependencies {
implementation 'org.springframework.boot:spring-boot-starter'

// grpc server
implementation 'net.devh:grpc-server-spring-boot-starter:2.13.1.RELEASE'
}

Теперь создадим один вспомогательный файл grpc.gradle для конфигурации gRPC. Эту конфигурацию можно было бы написать в исходном build.gradle файле, но лучше не засорять его, а держать всё относящееся к gRPC отдельно.

Файл grpc.gradle:

protobuf {
protoc {
artifact = "com.google.protobuf:protoc:3.7.1"
}
plugins {
grpc {
artifact = "io.grpc:protoc-gen-grpc-java:1.19.0"
}
}
generateProtoTasks {
ofSourceSet('main').each { task ->
task.builtins {
java {
outputSubDir = 'proto_gen'
}
}
task.plugins {
grpc {
outputSubDir = 'proto_gen'
}
}
}
}
generatedFilesBaseDir = "$projectDir/src/"
}
task cleanProtoGen {
doFirst {
delete("$projectDir/src/main/proto_gen")
}
}

clean.dependsOn cleanProtoGen

На этом все, что связано с зависимостями.

1.2. Реализация.

Создадим test.proto файл по пути src/main/proto/test.proto:

Следующий шаг будет реализация метода test определенного в файле test.proto. Для этого создадим класс MyServiceImpl:

На этом создание сервера закончено, но еще одна конфигурация которую можно пропустить - это изменение порта сервера. По умолчанию порт сервера 9090, его можно установить в файле application.properties:

grpc.port=9090

1.3. Тестирование.

Чтобы проверить работоспособность нашего сервера можно воспользоваться Postman.

Создадим новый тип запроса gRPC Request:

Импортируем test.proto файл из проекта Choose a File => Next:

Пропишем адрес нашего сервера localhost:9090 и из выпадающего списка выберем удаленный метод(процедуру) test. Во вкладке message передадим наш запрос:

Во вкладке Response получим ответ от нашего сервера.

2. Клиент

2.1. Добавление зависимостей.

Процес добавления зависимостей в клиент идентичен серверу, но оличается только одной зависимостью. Создадим еще один Spring Boot проект и добавим в файл build.gradle плагин и одну зависимость.

Плагин:

id 'com.google.protobuf' version '0.8.19'

Зависимость:

implementation 'net.devh:grpc-client-spring-boot-starter:2.13.1.RELEASE'

Вот так будет выглядеть конечный файл build.gradle:

plugins {
id 'org.springframework.boot' version '2.7.4'
id 'io.spring.dependency-management' version '1.0.14.RELEASE'
id 'java'
id 'idea'
// protobuf plugin
id 'com.google.protobuf' version '0.8.19'
}

group = 'com.example'
version = '0.0.1-SNAPSHOT'
sourceCompatibility = '8'

repositories {
mavenCentral()
}

dependencies {
implementation 'org.springframework.boot:spring-boot-starter'

// grpc client
implementation 'net.devh:grpc-client-spring-boot-starter:2.13.1.RELEASE'
}

Теперь создадим один вспомогательный файл grpc.gradle для конфигурации gRPC.

Файл grpc.gradle:

protobuf {
protoc {
artifact = "com.google.protobuf:protoc:3.7.1"
}
plugins {
grpc {
artifact = "io.grpc:protoc-gen-grpc-java:1.19.0"
}
}
generateProtoTasks {
ofSourceSet('main').each { task ->
task.builtins {
java {
outputSubDir = 'proto_gen'
}
}
task.plugins {
grpc {
outputSubDir = 'proto_gen'
}
}
}
}
generatedFilesBaseDir = "$projectDir/src/"
}
task cleanProtoGen {
doFirst {
delete("$projectDir/src/main/proto_gen")
}
}

clean.dependsOn cleanProtoGen

На этом все, что связано с зависимостями.

2.2. Реализация.

Создадим test.proto файл по пути src/main/proto/test.proto:

Следующий шаг будет создание класса использующего метод test нашего сервиса GrpcTestService:

Последний шаг будет добавление адреса нашего сервера в файл application.yaml:

3. Тестирование

Чтобы проверить работу клиента с сервером, добавим вызов метода printResponse после запуска клиента. Для этой цели будем использовать ApplicationRunner:

Запустим оба приложения и в логах клиента можем наблюдать результат выполнения метода printResponse:

Заключение

В этой статье я постарался кратко описать процес создание сервера и клиента с миниматьным количеством кода и конфигурации. Надеюсь статья была полезной и вы сможете использовать ее в ваших проектах.

Ссылки репозиториев:

Сервер: https://github.com/UryadovAlex/grpc-server.git

Клиент: https://github.com/UryadovAlex/grpc-client.git

--

--

Alexander Uryadov

Experienced Software Engineer with a demonstrated history of working in the computer software industry.