Adding a gRPC Endpoint to order-service: A Practical Guide
-
Jason Yang - 02 Dec, 2025
- Updated 04 Jan, 2026
- Views —
This guide walks you through the standard procedure for adding a new gRPC endpoint to the order-service Spring Boot project.
The goal is to expose an RPC method for creating a new order, while internally calling user-service to validate user information.
By the end of this guide, you will be able to:
- Define a gRPC service using
.proto - Generate Java stubs with Maven
- Implement a gRPC service in Spring Boot
- Integrate with other internal services
- Run a gRPC server on a custom port
Why gRPC?
Modern distributed systems often require high performance and strict API contracts. gRPC provides:
- High performance
Uses HTTP/2 + Protobuf (binary), enabling low latency and efficient bandwidth use. - Strongly typed interfaces
.protofiles define all messages and RPC operations, giving compile-time safety. - Multi-language support
Perfect for polyglot microservices — Java, Go, Node.js, Python, and more.
1. Define the API with Protocol Buffers
Start by creating a new .proto file under src/main/proto.
order.proto
syntax = "proto3";
package com.abc.order.grpc;
option java_multiple_files = true;
option java_package = "com.abc.order.grpc";
option java_outer_classname = "OrderProto";
// gRPC service definition
service OrderCreationService {
rpc CreateOrder(CreateOrderRequest) returns (CreateOrderResponse) {}
}
// Request message for creating an order
message CreateOrderRequest {
string user_id = 1;
repeated string product_ids = 2;
string correlation_id = 3;
}
// Response message from the order creation
message CreateOrderResponse {
bool success = 1;
string order_id = 2;
string message = 3;
}
Key Notes
repeatedmeans the field behaves like a list.correlation_idenables request tracking in distributed systems.- The
.protofile acts as your API contract — the source of truth shared by all clients.
2. Configure Maven for gRPC Code Generation
Your pom.xml needs both gRPC dependencies and Protobuf code generation plugins.
Dependencies
<properties>
<grpc.version>1.73.0</grpc.version>
<protobuf.version>4.31.1</protobuf.version>
<grpc.spring.boot.starter.version>5.2.0</grpc.spring.boot.starter.version>
</properties>
<dependencies>
<dependency>
<groupId>io.github.lognet</groupId>
<artifactId>grpc-spring-boot-starter</artifactId>
<version>${grpc.spring.boot.starter.version}</version>
</dependency>
<dependency>
<groupId>io.grpc</groupId>
<artifactId>grpc-stub</artifactId>
<version>${grpc.version}</version>
</dependency>
<dependency>
<groupId>io.grpc</groupId>
<artifactId>grpc-protobuf</artifactId>
<version>${grpc.version}</version>
</dependency>
<dependency>
<groupId>javax.annotation</groupId>
<artifactId>javax.annotation-api</artifactId>
<version>1.3.2</version>
</dependency>
</dependencies>
Code Generation Plugins
These plugins generate Java classes from your .proto files and register them as project sources.
<build>
<extensions>
<extension>
<groupId>kr.motd.maven</groupId>
<artifactId>os-maven-plugin</artifactId>
<version>1.7.1</version>
</extension>
</extensions>
<plugins>
<!-- Generate protobuf and gRPC Java classes -->
<plugin>
<groupId>org.xolstice.maven.plugins</groupId>
<artifactId>protobuf-maven-plugin</artifactId>
<version>0.6.1</version>
<configuration>
<protocArtifact>com.google.protobuf:protoc:3.25.1:exe:${os.detected.classifier}</protocArtifact>
<pluginId>grpc-java</pluginId>
<pluginArtifact>io.grpc:protoc-gen-grpc-java:${grpc.version}:exe:${os.detected.classifier}</pluginArtifact>
</configuration>
<executions>
<execution>
<goals>
<goal>compile</goal>
<goal>compile-custom</goal>
</goals>
</execution>
</executions>
</plugin>
<!-- Add generated files to the Java source path -->
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>build-helper-maven-plugin</artifactId>
<version>3.5.0</version>
<executions>
<execution>
<id>add-source</id>
<phase>generate-sources</phase>
<goals>
<goal>add-source</goal>
</goals>
<configuration>
<sources>
<source>${project.build.directory}/generated-sources/protobuf/java</source>
<source>${project.build.directory}/generated-sources/protobuf/grpc-java</source>
</sources>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
After the configuration is added, run:
mvn clean install
This creates Java stubs under:
target/generated-sources/
3. Implement the gRPC Service
Now extend the generated base class and implement your business logic.
OrderCreationServiceImpl.java
package com.abc.orderservice.grpc;
import com.abc.orderservice.service.InternalOrderProcessingService;
import com.abc.orderservice.service.UserService;
import com.abc.order.grpc.OrderCreationServiceGrpc;
import com.abc.order.grpc.CreateOrderRequest;
import com.abc.order.grpc.CreateOrderResponse;
import io.grpc.stub.StreamObserver;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.lognet.springboot.grpc.GRpcService;
@GRpcService
@RequiredArgsConstructor
@Slf4j
public class OrderCreationServiceImpl
extends OrderCreationServiceGrpc.OrderCreationServiceImplBase {
private final UserService userService;
private final InternalOrderProcessingService orderProcessingService;
@Override
public void createOrder(CreateOrderRequest request,
StreamObserver<CreateOrderResponse> responseObserver) {
log.info("Received order request for user '{}'", request.getUserId());
try {
// Validate user through internal user-service
boolean isUserValid = userService.validateUser(request.getUserId());
if (!isUserValid) {
throw new IllegalArgumentException("Invalid User ID");
}
// Execute order creation
String orderId = orderProcessingService.create(
request.getUserId(),
request.getProductIdsList()
);
// Send success response
CreateOrderResponse response = CreateOrderResponse.newBuilder()
.setSuccess(true)
.setOrderId(orderId)
.setMessage("Order created successfully.")
.build();
responseObserver.onNext(response);
responseObserver.onCompleted();
} catch (Exception e) {
log.error("Order creation failed", e);
CreateOrderResponse response = CreateOrderResponse.newBuilder()
.setSuccess(false)
.setMessage("Order creation failed: " + e.getMessage())
.build();
responseObserver.onNext(response);
responseObserver.onCompleted();
}
}
}
Important Notes
@GRpcServiceautomatically registers the class as a gRPC endpoint.- You must call
onNext()andonCompleted()even in error cases. - gRPC uses an asynchronous streaming model;
StreamObserveris the callback interface.
4. Configure the gRPC Server Port
Add the following to your application.yml:
grpc:
server:
port: 9090
Your gRPC service is now accessible at:
localhost:9090
5. (Optional) Test with grpcurl
You can quickly test your endpoint with grpcurl:
grpcurl -plaintext \
-d '{"user_id":"U1","product_ids":["P1","P2"],"correlation_id":"c-001"}' \
localhost:9090 \
com.abc.order.grpc.OrderCreationService/CreateOrder
Conclusion
You have successfully:
- Defined a gRPC service
- Generated Java stubs
- Implemented a gRPC endpoint with Spring Boot
- Integrated with internal services
- Exposed the service on a custom port
This is the typical workflow for adding new RPC operations to your microservices that communicate using gRPC.