Production-oriented JSON-RPC 2.0 server library for Java, with optional Spring WebMVC and Spring Boot integration.
- JSON-RPC 2.0 compliant core request/response/error handling
- Pure Java support (
jsonrpc-core) for custom transports - Spring WebMVC transport adapter and Spring Boot auto-configuration
- Multiple registration styles (annotation/manual/typed)
- Explicit extension points (parser/validator/invoker/exception mapping/interceptors/metrics)
- Focused dependency surface (no direct Guava, Commons Lang3, or Jakarta Validation dependency)
- JSON-RPC 2.0: https://www.jsonrpc.org/specification
- RFC 8259 (JSON): https://www.rfc-editor.org/rfc/rfc8259
- Java: 17+
- Spring Boot baseline: 4.0.2
- Jackson baseline: 3.0.x
- Build: Gradle with Version Catalog
- CI matrix: Java 17, 21, 25
| Module | Purpose |
|---|---|
jsonrpc-core |
Protocol model, parser/validator, dispatcher, method registry, typed binding |
jsonrpc-spring-webmvc |
HTTP endpoint adapter and HTTP status strategy |
jsonrpc-spring-boot-autoconfigure |
Property binding, bean wiring, method scanning, metrics/access integration |
jsonrpc-spring-boot-starter |
Starter dependency bundle for Spring Boot applications |
Maven:
<dependency>
<groupId>io.github.limehee</groupId>
<artifactId>jsonrpc-spring-boot-starter</artifactId>
<version>0.1.0</version>
</dependency>Gradle (Kotlin DSL):
implementation("io.github.limehee:jsonrpc-spring-boot-starter:0.1.0")Gradle (Groovy DSL):
implementation 'io.github.limehee:jsonrpc-spring-boot-starter:0.1.0'Maven:
<dependency>
<groupId>io.github.limehee</groupId>
<artifactId>jsonrpc-core</artifactId>
<version>0.1.0</version>
</dependency>Gradle (Kotlin DSL):
implementation("io.github.limehee:jsonrpc-core:0.1.0")Gradle (Groovy DSL):
implementation 'io.github.limehee:jsonrpc-core:0.1.0'import com.limehee.jsonrpc.core.JsonRpcMethod;
import com.limehee.jsonrpc.core.JsonRpcParam;
import org.springframework.stereotype.Service;
@Service
class GreetingRpcService {
@JsonRpcMethod("greet")
public String greet(@JsonRpcParam("name") String name) {
return "hello " + name;
}
}Default endpoint: POST /jsonrpc
Request:
{"jsonrpc":"2.0","method":"greet","params":{"name":"developer"},"id":1}Response:
{"jsonrpc":"2.0","id":1,"result":"hello developer"}import tools.jackson.databind.JsonNode;
import tools.jackson.databind.ObjectMapper;
import tools.jackson.databind.json.JsonMapper;
import tools.jackson.databind.node.StringNode;
import com.limehee.jsonrpc.core.JsonRpcDispatchResult;
import com.limehee.jsonrpc.core.JsonRpcDispatcher;
ObjectMapper mapper = JsonMapper.builder().build();
JsonRpcDispatcher dispatcher = new JsonRpcDispatcher();
dispatcher.register("ping", params -> StringNode.valueOf("pong"));
JsonNode payload = mapper.readTree("""
{"jsonrpc":"2.0","method":"ping","id":1}
""");
JsonRpcDispatchResult result = dispatcher.dispatch(payload);
System.out.println(mapper.writeValueAsString(result.singleResponse().orElseThrow()));Supported styles:
@JsonRpcMethodon Spring beansJsonRpcMethodRegistrationbeans (manual)JsonRpcTypedMethodHandlerFactory(typed adapter used by manual or custom registration)
Registration order in Spring Boot runtime:
JsonRpcMethodRegistrationbeans are registered first (orderedStream();@Orderapplies).@JsonRpcMethodscanning runs after singleton initialization and registers annotated methods.
Conflict behavior for duplicate method names is controlled by jsonrpc.method-registration-conflict-policy:
REJECT(default): throws and fails startup/runtime registration.REPLACE: later registration replaces earlier one.
Practical implication with REPLACE: annotated methods can override manual registrations for the same name because annotation scanning executes later.
@JsonRpcMethod("name"): explicit JSON-RPC name.@JsonRpcMethodwithout value: Java method name is used.- Multi-parameter binding mode:
paramsobject -> named binding (@JsonRpcParamfirst, then Java parameter names with-parameters)paramsarray -> positional binding (exact argument count required)
- Single parameter -> entire
paramsnode mapped to declared type. - Return values are serialized via Jackson (
ObjectMapper.valueToTreeby default).
./gradlew check
./gradlew apiCompat -PapiBaselineVersion=<released-version>
./gradlew :jsonrpc-core:jmh
./gradlew :jsonrpc-core:jmhQuick
./scripts/verify-consumer-smoke.shDetailed docs are under docs/:
docs/index.mddocs/getting-started.mddocs/spring-boot-guide.mddocs/pure-java-guide.mddocs/registration-and-binding.mddocs/configuration-reference.mddocs/extension-points.mddocs/protocol-and-compliance.mddocs/testing-and-quality.mddocs/performance.mddocs/troubleshooting.md
- Spring Boot sample app:
samples/spring-boot-demo
Run:
./gradlew -p samples/spring-boot-demo bootRun- Contributing:
CONTRIBUTING.md - Security:
SECURITY.md - Release checklist:
docs/release-checklist.md - Releases: https://github.com/limehee/jsonrpc-spring-boot-starter/releases