Skip to content

feat: JSON-RPC protocol engines for Jackson & Avaje#3870

Merged
jknack merged 12 commits intomainfrom
3868
Mar 10, 2026
Merged

feat: JSON-RPC protocol engines for Jackson & Avaje#3870
jknack merged 12 commits intomainfrom
3868

Conversation

@jknack
Copy link
Member

@jknack jknack commented Mar 9, 2026

Description

This PR introduces a complete, spec-compliant JSON-RPC 2.0 implementation for Jooby. It leverages Jooby's annotation processing tool (APT) to eliminate boilerplate, mapping standard JSON-RPC requests to native controller methods, and includes core parser/decoder implementations across multiple JSON engines.

Key Changes:

  • APT Generation & Dispatching: Added support for @JsonRpc controllers. The annotation processor now automatically generates the protocol dispatcher, seamlessly routing JSON-RPC method strings (e.g., movies.getById) directly to native JsonRpcService methods without requiring developers to write protocol-specific routing logic.
  • Multi-Engine Parsers: Implemented JsonRpcParser, JsonRpcDecoder, and JsonRpcReader interfaces for Jackson 2, Jackson 3, and Avaje JSON-B to handle payload deserialization efficiently.
  • Strict Protocol Compliance: Enforced the JSON-RPC 2.0 mutual exclusivity rules for response envelopes (payloads MUST NOT contain both result and error simultaneously) using custom serializers (StdSerializer for Jackson, JsonAdapter.Factory for Avaje).
  • Robust Error Handling & Type Coercion: Upgraded primitive readers to reject invalid types with IllegalArgumentException. Integrated JsonRpcErrorCode to seamlessly map native application exceptions (like HTTP 404) to JSON-RPC standard error codes (e.g., -32004) while populating the data field.
  • Test Infrastructure: Extracted protocol tests into an AbstractJsonRpcProtocolTest to execute the entire compliance test suite (including batch processing, invalid params, and parse errors) against all registered JSON modules.

jknack added 12 commits March 8, 2026 17:30
…tcher

- Transition from artificial namespace routing to strict JSON-RPC 2.0 method mapping.
- Update APT `JoobyProcessor` to generate isolated `*Rpc_` classes for each `@JsonRpc` annotated controller.
- Preserve standard MVC factory constructor patterns (`Function<Context, T>`) in generated RPC services to maintain full Dependency Injection support.
- Introduce `JsonRpcService.getMethods()` to explicitly declare supported protocol methods.
- Implement $O(1)$ `HashMap` method resolution in the Tier 1 `JsonRpcDispatcher`.
- Remove implicit `Extension` self-registration from generated classes in favor of explicit manual registration via the dispatcher constructor.
- Fix `@Generated` annotation metadata output for Java (`.class`) and Kotlin (`::class`).
- ref #3868
…ntrollers

- Fix an issue where mixing standard REST annotations (e.g., `@GET`, `@Path`) with `@JsonRpc` on the same controller caused the APT processor to exit early, skipping the standard MVC router generation.
- Update `JoobyProcessor` to perform two distinct file generation passes, allowing a single controller to output both REST and JSON-RPC routing files simultaneously.
- Introduce `hasRestRoutes()` and `hasJsonRpcRoutes()` condition checks to `MvcRouter`.
- Refactor the monolithic `toSourceCode()` method into strictly isolated `getRestSourceCode()` and `getRpcSourceCode()` methods.
- Ensure standard routes generate `[Name]_` files and JSON-RPC routes generate `[Name]Rpc_` files without filename or class name conflicts.
- Fine-tune `CodeBlock` formatting in the JSON-RPC generator, removing manual newline hacks in favor of native block indentation.
- Add `JsonRpcErrorCode` enum mapping core JSON-RPC 2.0 protocol errors
  (-32700 to -32603) and implementation-defined server errors
  (-32000 to -32099) to Jooby's standard HTTP `StatusCode`s.
- Introduce a `protocol` flag on error codes to cleanly differentiate
  between transport/parsing faults and application-level exceptions.
- Ensure error payloads comply with the 2.0 spec by utilizing the `data`
  field to hold specific exception messages, keeping the `message` field
  generic and strictly compliant.
- Refactor and expand `JsonRpcProtocolTest` into isolated test methods.
- Add comprehensive integration tests for error edge cases: missing/invalid
  parameters, unknown methods, application exception bubbling, and specific
  batch processing edge cases (empty arrays, arrays of invalid data).
…ompliance

- Add `JsonRpcParser`, `JsonRpcDecoder`, and `JsonRpcReader` implementations for Jackson 2, Jackson 3, and Avaje JSON-B.
- Implement custom serializers (`StdSerializer` for Jackson, `JsonAdapter` for Avaje) for `JsonRpcResponse` and `ErrorDetail` to enforce JSON-RPC 2.0 mutual exclusivity (payloads MUST NOT contain both `result` and `error`).
- Add robust type coercion to JSON readers to reject invalid primitives and throw `IllegalArgumentException` instead of failing silently.
- Refactor `JsonRpcProtocolTest` into `AbstractJsonRpcProtocolTest` to seamlessly run the entire protocol compliance suite against all registered JSON engines.
@jknack jknack added this to the 4.0.17 milestone Mar 10, 2026
@jknack jknack merged commit e84e2f9 into main Mar 10, 2026
5 checks passed
@jknack jknack modified the milestones: 4.0.17, 4.1.0 Mar 10, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant