timemates / rrpc-kotlin

RPC framework for Kotlin built on top of RSocket
https://rrpc.timemates.org
MIT License
9 stars 0 forks source link

Implement RPC-to-REST Generation Adapter #13

Open y9vad9 opened 4 days ago

y9vad9 commented 4 days ago

Summary

The goal is to provide REST adapters for RRPC APIs, enabling non-RRPC developers or systems to access RRPC endpoints via REST if needed. Unlike conventional API generation approaches, this feature focuses on optional, configurable adapters that extend RRPC functionality. It targets accessibility rather than replacing RRPC's core functionality.

Additionally, the design will explore supporting Google's built-in REST configuration model (such as google.api.http annotations in protobuf) to align with existing standards.


Rationale

RRPC is designed around RSocket, providing native support for streaming and request-response communication patterns. However, not all environments or users may be ready or willing to adopt RSocket due to its complexity or limited use cases.

By offering REST adapters:

  1. Broader Adoption: Developers unfamiliar with RSocket can access the product via REST.
  2. System Integration: REST is ideal for environments where integrating RSocket would add unnecessary overhead.
  3. Backward Compatibility: REST adapters allow RRPC-powered products to be consumed by legacy systems.
  4. Extensibility: Aligning with Google’s REST annotation model ensures flexibility and future compatibility.

Proposed Implementation

REST Adapter Design

  1. Configurable Adapters:

    • REST endpoints are optional and generated only if configured by the developer.
    • Adapters allow selective exposure of RRPC services via REST.
  2. Route Mapping:

    • RRPC methods are mapped to RESTful endpoints based on configurable rules or annotations.
    • Default mapping:
      • Request-response RPCs are mapped to standard HTTP methods (e.g., GET, POST).
    • Extend to support custom mapping via google.api.http annotations.
  3. Serialization and Validation:

    • Input and output data are serialized/deserialized to/from JSON.
    • Validate input to match RRPC service contracts before forwarding the request.
  4. Adapter Lifecycle:

    • The adapter listens for REST requests and delegates them to the corresponding RRPC handlers.
    • Errors from RRPC are translated to HTTP status codes and JSON error messages.

Implementation Plan

Phase 1: Request-Response Support

  1. Adapter Generator:

    • Build adapters dynamically using the RRPC service descriptor.
    • Parse google.api.http annotations, if present, to define routes and HTTP methods.
  2. Middleware:

    • Create middleware to:
      • Convert REST requests to RRPC calls.
      • Map RRPC responses to HTTP responses.
    • Default mapping if no custom annotations are provided.
  3. Testing:

    • Focus on integration testing with REST clients consuming RRPC services.
    • Validate behavior with and without custom annotations.
  4. Documentation:

    • Explain how to enable REST adapters and use them with RRPC.
Phase 2: Advanced Features

Supporting Google's REST Model

  1. Integration with google.api.http:
    • Utilize annotations like:
      rpc GetBook (GetBookRequest) returns (Book) {
      option (google.api.http) = {
       get: "/v1/{name=books/*}"
      };
      }
    • Map annotated RPCs to REST endpoints accordingly.
  2. Fallback for Unannotated RPCs:
    • Default route mapping based on RRPC's naming conventions if no annotations exist.

Example Usage

Protobuf Service Definition:

service BookService {
  rpc GetBook (GetBookRequest) returns (Book) {
    option (google.api.http) = {
      get: "/v1/books/{id}"
    };
  }
  rpc ListBooks (ListBooksRequest) returns (ListBooksResponse);
}

Exposed REST Endpoints:

REST Request Flow:

  1. A client sends a GET /v1/books/123.
  2. The REST adapter translates it to an RRPC call for GetBook.
  3. The adapter sends the result back as JSON.

Minimal goals

  1. REST adapter framework for request-response RPCs.
  2. Example integration with google.api.http annotations.
  3. Documentation and examples showcasing usage.

Next Steps

  1. Implement a proof-of-concept REST adapter for a sample RRPC service.
  2. Expand the design for streaming RPCs in later releases.
  3. Evaluate feedback and improve configuration flexibility.
y9vad9 commented 4 days ago

we may also support OpenAPI schema generation in #7 from such adapter