Skip to content

Implement JsonRpcService #6286

@ikhoon

Description

@ikhoon

The following code is designed as an API to support the JSON-RPC protocol. The design may be subject to change during implementation.
Related: #6179 #6222

  • JsonRpcService is an HttpService to decode JSON RPC requests and handle responses
    • Responses to batched requests may be sent via Server-sent events when:
      • the client accepts text/event-stream and;
      • JsonRpcServiceBuilder.useSse(true) is enabled.
    public final class JsonRpcService implements HttpService {
    
        public static JsonRpcServiceBuilder builder() {
            return new JsonRpcServiceBuilder();
        }
    
        @Override
        public HttpResponse serve(ServiceRequestContext ctx, HttpRequest req) throws Exception {
            // Parse the incoming request as JSON.
            JsonNode rawRequest = null;
            if (rawRequest.isObject()) {
                return handleUnaryRequest(ctx, rawRequest);
            } else if (rawRequest.isArray()) {
                return handleBatchRequests(ctx, rawRequest);
            } else {
                // If the request is neither an object nor an array, return an error response.
                return HttpResponse.ofJson(HttpStatus.BAD_REQUEST, "Invalid JSON-RPC request format.");
            }
        }
    
        private HttpResponse handleUnaryRequest(ServiceRequestContext ctx, JsonNode rawRequest) {
            // Handle the unary JSON-RPC request.
            // Find a suitable handler for the method and invoke it.
            return null;
        }
    
        private HttpResponse handleBatchRequests(ServiceRequestContext ctx, JsonNode rawRequest) {
            if (shouldUseSse) {
                // Handle the batch JSON-RPC requests using Server-Sent Events (SSE).
                // This is useful for long-running operations or streaming responses.
            } else {
                // Handle the batch JSON-RPC requests normally.
                // Process each request in the batch and return a combined response in array format.
            }
            return null;
        }
    }
  • JsonServiceBuilder to add handlers and set options
    public final class JsonRpcServiceBuilder {
    
        JsonRpcServiceBuilder() {}
    
        public JsonRpcServiceBuilder addHandler(String methodName, JsonRpcHandler handler) {
            return this;
        }
    
        /**
         * Use Sever-Sent Event (SSE) to send batched responses.
         */
        public JsonRpcServiceBuilder useSse(boolean useSse) {
            return this;
        }
    
        /**
         * Builds a new {@link JsonRpcService} instance.
         */
        public JsonRpcService build() {
            return new JsonRpcService();
        }
    }
  • JsonRpcHandler to handle each request, such as { "jsonrpc": "2.0", "method": "foo", "id": 1 ... }
    @FunctionalInterface
    public interface JsonRpcHandler {
    
        CompletableFuture<JsonRpcResponse> handle(ServiceRequestContext ctx, JsonRpcRequest request);
    }
  • JsonRpcRequest to represent the incoming request
    public interface JsonRpcRequest {
    
        /**
         * Returns the ID of the JSON-RPC request.
         */
        @Nullable
        Object id();
      
        /**
         * Returns the JSON-RPC method name.
         */
        String method();
    
        /**
         * Returns the parameters for the JSON-RPC method.
         */
        Object[] params();
      
        /**
         * Returns the JSON-RPC version.
         */
        String version();
    }
  • JsonRpcResponse to represent the response to be sent to the client
    public interface JsonRpcResponse {
        // "id" and "jsonrpc" will be automatically filled by JsonRpcService
      	
        @Nullable
        Object result();
      
        @Nullable
        JsonRpcError error();	
    }

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions