gRPC Support
EasyApi provides built-in support for gRPC services, allowing you to export gRPC service definitions and call gRPC endpoints directly from the IDE.
Enabling gRPC Support
- Open Preferences(Settings) > Other Settings > EasyApi > gRPC tab
- Enable gRPC support to recognize gRPC service classes (default: on)
- Optionally enable gRPC call to invoke gRPC endpoints from the IDE (default: off)
How gRPC Services Are Recognized
EasyApi recognizes gRPC services through multiple detection strategies:
1. Extending BindableService
A class is recognized as a gRPC service if it extends io.grpc.BindableService directly or through a generated ImplBase superclass anywhere in the hierarchy:
// Generated by protobuf: XxxGrpc.XxxImplBase extends AbstractStub implements BindableService
public class GreeterServiceImpl extends GreeterGrpc.GreeterImplBase {
@Override
public void sayHello(HelloRequest request, StreamObserver<HelloReply> responseObserver) {
// ...
}
}The recognizer walks the full supertype hierarchy to find BindableService, so it works even when the implementation class doesn't directly implement it.
2. @GrpcService Annotation
Classes annotated with @GrpcService from grpc-spring-boot-starter are also recognized:
@GrpcService
public class GreeterServiceImpl extends GreeterGrpc.GreeterImplBase {
// ...
}Meta-annotations are also supported — if you create a custom annotation that is itself annotated with @GrpcService, classes using your custom annotation will be recognized.
3. Custom Rule Override
You can customize gRPC class recognition using the class.is.grpc rule:
class.is.grpc=groovy:it.isExtend("io.grpc.BindableService")gRPC Method Detection
EasyApi discovers RPC methods using two strategies:
Signature Pattern Matching
For instance methods, EasyApi detects the streaming type from the method signature:
| Pattern | Streaming Type |
|---|---|
void method(RequestType req, StreamObserver<Resp> resp) | UNARY (or SERVER_STREAMING) |
StreamObserver<Req> method(StreamObserver<Resp> resp) | CLIENT_STREAMING (or BIDIRECTIONAL) |
Note: At the implementation level, unary and server-streaming share the same Java signature. EasyApi defaults to UNARY. Similarly, client-streaming and bidirectional share the same signature and default to CLIENT_STREAMING.
@RpcMethod Annotation
For static methods or when signature detection is ambiguous, EasyApi reads the @RpcMethod annotation generated by gRPC:
@RpcMethod(
fullMethodName = "com.example.Greeter/SayHello",
requestType = HelloRequest.class,
responseType = HelloReply.class,
methodType = "UNARY"
)This annotation provides precise streaming type information (UNARY, SERVER_STREAMING, CLIENT_STREAMING, BIDIRECTIONAL).
Protobuf Message Type Parsing
EasyApi parses protobuf-generated message classes to extract field information for request/response documentation:
- Scalar fields → mapped to protobuf types (e.g.,
String→string,int→int32) - Repeated fields (
List<T>) → array types - Map fields (
Map<K,V>) → map types - Nested message types → recursive parsing (up to depth 5)
Internal protobuf methods (like getDefaultInstance, getUnknownFields, getXxxBytes, getXxxCount) are automatically filtered out.
Exporting gRPC APIs
Once gRPC support is enabled, you can export gRPC service methods:
- Export to Postman: gRPC methods will be included in the collection
- Export to Markdown: gRPC service documentation will be generated
- Export to Curl: gRPC endpoints can be exported as curl commands
Each exported endpoint includes:
- gRPC service path (
/{package}.{ServiceName}/{MethodName}) - Streaming type
- Request/response protobuf message types and fields
Calling gRPC Endpoints
When gRPC call is enabled, you can invoke gRPC methods directly from the IDE:
- Navigate to a gRPC service class
- Use the EasyApi Call action on a method
- Provide the request parameters in JSON format
- View the response
How gRPC Call Works
EasyApi uses dynamic class loading to invoke gRPC methods without requiring compile-time stubs:
- Resolves gRPC runtime JARs from local Maven/Gradle repositories
- Creates a gRPC channel to the target server
- Resolves the service descriptor (from
.protofiles or server reflection) - Converts the JSON request to protobuf binary format
- Invokes the RPC method and converts the response back to JSON
Service Descriptor Resolution
EasyApi resolves gRPC service descriptors from multiple sources:
- Proto files in the project: Parses
.protofiles to build service descriptors - Server reflection: Queries the gRPC server for service descriptors (if enabled)
- Generated stub classes: Reads method info from
@RpcMethodannotations
Configuration
gRPC Settings
| Setting | Default | Description |
|---|---|---|
| Enable gRPC support | On | Recognize gRPC service classes |
| Enable gRPC call | Off | Allow calling gRPC endpoints from the IDE |
| Auto Detect | — | Automatically detect gRPC runtime artifacts in project |
| Runtime Packages | — | gRPC runtime artifact configurations (group:artifact:version:enabled) |
| Additional JARs | — | Additional JAR files for gRPC runtime |
Runtime Resolution
EasyApi searches for gRPC runtime JARs in the following locations:
- Maven local repository (
~/.m2/repository) - Gradle cache (
~/.gradle/caches/modules-2/files-2.1) - Custom configured repositories
The resolver selects the newest complete version that has all required artifacts:
| Artifact | Description |
|---|---|
io.grpc:grpc-netty-shaded | Netty transport (shaded) |
io.grpc:grpc-api | gRPC core API |
io.grpc:grpc-protobuf | Protobuf codec |
io.grpc:grpc-stub | Stub generation |
io.grpc:grpc-core | gRPC core |
io.grpc:grpc-services | Server reflection & health |
com.google.protobuf:protobuf-java | Protobuf runtime |
com.google.protobuf:protobuf-java-util | Protobuf JSON utilities |
com.google.guava:guava | Guava (dependency) |
com.google.guava:failureaccess | Failure access (dependency) |
com.google.code.gson:gson | Gson (dependency) |
io.perfmark:perfmark-api | Performance marking (dependency) |
Custom gRPC Recognition
class.is.grpc=groovy:it.isExtend("io.grpc.BindableService") || it.hasAnn("net.devh.boot.grpc.server.service.GrpcService")Ignore Internal gRPC Methods
ignore=groovy:it.name() == "getServiceDescriptor" || it.name() == "bindService" || it.name() == "getMethodDescriptors"