The Official gRPC Starter: Discover the auto-configuration, native testing and exception mapping that makes gRPC a first-class citizen.

For years, Spring Boot developers who wanted gRPC had one default option: the community-maintained net.devh:grpc-spring-boot-starter. It worked, it was reliable — but it always felt like a plugin rather than a native citizen.
That changes now. With the official Spring gRPC starter, the Spring team has finally embraced gRPC as a first-class protocol within the Boot ecosystem — complete with auto-configuration, testing, exception mapping and observability.
⚡ TL;DR (Quick Recap)
- New official starter: org.springframework.grpc:spring-grpc-spring-boot-starter brings gRPC into the Spring Boot core ecosystem.
- Spring-first experience: Works with @GrpcService, GrpcExceptionHandler and in-process tests — no custom server setup required.
- Migration ready: Replaces net.devh.grpc-spring-boot-starter with cleaner configuration, better testing and official support.
Why gRPC Finally Feels Native in Spring Boot
gRPC has long been a favorite for inter-service communication in microservice architectures — fast, strongly typed and polyglot. But in Spring Boot, it’s always been a little… external.
With the official starter (spring-grpc-spring-boot-starter), gRPC now feels like just another Spring Boot technology. You define .proto files, annotate your services and Spring Boot does the rest .
It’s the same “convention over configuration” magic that Spring brought to REST, now applied to binary gRPC.
Setting Up the Project
Here’s all you need in pom.xml:
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.grpc</groupId>
<artifactId>spring-grpc-dependencies</artifactId>
<version>0.11.0</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.grpc</groupId>
<artifactId>spring-grpc-spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>io.grpc</groupId>
<artifactId>grpc-services</artifactId>
</dependency>
</dependencies>
And a Protobuf compiler plugin:
<plugin>
<groupId>io.github.ascopes</groupId>
<artifactId>protobuf-maven-plugin</artifactId>
<version>3.8.0</version>
<configuration>
<protocVersion>4.31.1</protocVersion>
<binaryMavenPlugins>
<binaryMavenPlugin>
<groupId>io.grpc</groupId>
<artifactId>protoc-gen-grpc-java</artifactId>
<version>1.74.0</version>
</binaryMavenPlugin>
</binaryMavenPlugins>
</configuration>
</plugin>
That’s it — Spring Boot will handle gRPC server startup automatically when you run:
./mvnw spring-boot:run
Defining Your Contract
Your gRPC API lives in a .proto file. Here’s a trimmed example from demo.proto:
syntax = "proto3";
package demo;
service DemoService {
rpc CreateDemo(CreateDemoRequest) returns (DemoResponse);
rpc GetDemo(GetDemoRequest) returns (DemoResponse);
rpc ListDemos(ListDemosRequest) returns (ListDemosResponse);
}
message Demo {
string id = 1;
string name = 2;
}
...
When you build the project, the Maven plugin generates type-safe Java classes for the messages and stubs — exactly the kind of compile-time safety gRPC is loved for.
Implementing a gRPC Service the Spring Way
The magic happens with @GrpcService.
@GrpcService
public class GrpcDemoService extends DemoServiceGrpc.DemoServiceImplBase {
@Override
public void createDemo(CreateDemoRequest request, StreamObserver<DemoResponse> responseObserver) {
var response = DemoResponse.newBuilder()
.build())
.build();
responseObserver.onNext(response);
responseObserver.onCompleted();
}
}
Why this is different from net.devh:
- @GrpcService is official — no external package.
- It’s Spring-managed, so you can inject beans, apply interceptors and rely on Spring Boot’s lifecycle.
- Exception handling and observability are auto-wired if you include Spring Boot dependencies
Configuration? Just Properties
The configuration model mirrors other Spring Boot starters:
- spring.grpc.server.* — for server configuration
- spring.grpc.client.* — for client configuration
- Built-in support for in-process servers for tests and health/reflection services.
It just feels natural if you’ve ever configured spring.datasource.*
Error Handling
One of the big wins over the old ecosystem is exception mapping. The new GrpcExceptionHandler interface lets you translate exceptions into gRPC status codes without writing boilerplate try-catch logic:
@Component
public class NotFoundExceptionHandler implements GrpcExceptionHandler {
@Override
public StatusException handleException(Throwable ex) {
if (ex instanceof NotFoundException e) {
return Status.NOT_FOUND
.withDescription(e.getMessage())
.asException();
}
return null;
}
}
This is cleaner, more predictable and easily testable. Add multiple handlers, order them and you get HTTP-like semantics (404, 400, etc.) in your gRPC world.
Testing
The official starter integrates tightly with Spring Boot’s test lifecycle:
@SpringBootTest(
properties = {
"spring.grpc.server.port=0",
"spring.grpc.client.channels.demo.address=static://localhost:${local.grpc.port}"
})
@ImportGrpcClients(types = DemoServiceGrpc.DemoServiceBlockingStub.class)
class GrpcDemoServiceIntegrationTest {
@Autowired
private DemoServiceGrpc.DemoServiceBlockingStub stub;
@Test
void shouldCreateDemo() {
var request = CreateDemoRequest.newBuilder().setName("Test").build();
var response = stub.createDemo(request);
assertThat(response.getDemo().getName()).isEqualTo("Test");
}
}
No mock servers, no manual ports. Spring Boot spins up an in-process gRPC server and injects the client stubs automatically.
Comparing to net.devh’s gRPC Starter
Let’s be honest: net.devh carried the community for years. It gave us working gRPC support long before Spring cared. But it’s time to move on.
Here’s how the new starter compares:
✅ Official Spring gRPC Starter
- Owned and maintained by the Spring team
- Aligned with Spring Boot 3.x and 4.x lifecycle
- Built-in observability, metrics and security via Spring Boot
- First-class support for in-process servers, exception mapping and declarative security
- Uses spring.grpc.* property namespace
⚙️ net.devh gRPC Starter
- Community-driven, slower to update for major Spring Boot releases
- Lacked native testing integration
- Used grpc.server.* and grpc.client.* properties
- Still useful for legacy Boot 2.x and 3.x applications
Migrating is straightforward:
- Replace dependencies with the new Spring starter.
- Update your annotations to @GrpcService and @ImportGrpcClients.
- Adjust property names to spring.grpc.*.
- Remove custom server bootstrap or config beans — Spring Boot handles them now.
You’ll gain cleaner config, better Spring integration and official long-term support.
Why This Matters
This official starter finally closes a long-standing gap between REST and gRPC in the Spring world.
We now get:
- The speed and type safety of gRPC.
- The developer ergonomics of Spring Boot.
- The confidence of first-party support.
And it’s not just about convenience — features like in-process testing, native images, observability and Spring Security integration make it production-ready from day one.
Final Takeaways
If you’ve been holding off on adopting gRPC in your Spring Boot services because the setup felt “third-party,” now’s the time to revisit it.
- Use the official spring-grpc-spring-boot-starter for new projects.
- Migrate existing net.devh setups gradually — most patterns carry over cleanly.
- Leverage in-process tests and exception handlers to make your services robust.
Spring’s official gRPC integration is here — and it finally feels like it belongs.
You can find all the code on GitHub.
Originally posted on marconak-matej.medium.com.