### Minimal Apex JSON-RPC Module Registration and Execution Source: https://github.com/damecek/salesforce-apex-json-rpc/blob/main/examples/README.md Demonstrates the simplest setup for a JSON-RPC module in Apex, including a Data Transfer Object (DTO) pair, a handler, module registration, and an execution call. This serves as a basic template for new implementations. ```apex /* minimal-module.apex */ // DTO Pair public class MyRequest { public String message; } public class MyResponse { public String reply; } // Handler public class MyHandler { public MyResponse handle(MyRequest req) { MyResponse res = new MyResponse(); res.reply = 'Received: ' + req.message; return res; } } // Module Registration public class MyModule implements JsonRpcModule { public Object handle(String method, Object params) { if (method == 'myMethod') { MyRequest req = (MyRequest)JSON.deserialize(JSON.வதாக(params), MyRequest.class); MyHandler handler = new MyHandler(); return handler.handle(req); } return null; // Or throw an exception } } // Execution Call (Example) // JsonRpcRuntime.execute('MyModule', 'myMethod', JSON.serialize(new MyRequest(message='Hello')), null); ``` -------------------------------- ### Manage 2GP Package Versions (Bash) Source: https://github.com/damecek/salesforce-apex-json-rpc/blob/main/README.md Commands for managing 2GP (Second-Generation Packaging) for the Apex JSON-RPC framework. This includes initializing the package in the Dev Hub, creating a new version, and promoting or installing it. ```bash # Create package in Dev Hub (idempotent): npm run package:init # Create version: npm run release:version # Promote/install (requires PACKAGE_VERSION_ID): npm run release:promote npm run release:install ``` -------------------------------- ### Install Apex JSON-RPC Framework Dependencies (Bash) Source: https://github.com/damecek/salesforce-apex-json-rpc/blob/main/README.md Commands to set up a Salesforce environment for the Apex JSON-RPC framework. This includes refreshing the scratch org, deploying the package, and running tests. It assumes a default Dev Hub alias but allows for overrides. ```bash npm run org:fresh npm run org:deploy npm run org:test ``` -------------------------------- ### Apex JSON-RPC Runtime Options with Custom Exception Mapper Source: https://github.com/damecek/salesforce-apex-json-rpc/blob/main/examples/README.md Shows how to configure runtime options for the JSON-RPC framework, specifically demonstrating the use of a custom exception mapper. This allows for tailored error responses when exceptions occur during request processing. ```apex /* custom-exception-mapper.apex */ public class CustomExceptionMapper implements JsonRpcExceptionMapper { public Map mapException(Exception e) { Map error = new Map(); error.put('code', -32000); error.put('message', 'A custom error occurred: ' + e.getMessage()); // Optionally add data // error.put('data', e.getStackTraceString()); return error; } } // Runtime Options Configuration (Example) // JsonRpcRuntime.setExceptionMapper(new CustomExceptionMapper()); // JsonRpcRuntime.setModuleRegistration(new MyModuleRegistration()); // Assuming a registration class // Then execute requests as usual... ``` -------------------------------- ### Apex JSON-RPC Handler Unit and Integration Testing Pattern Source: https://github.com/damecek/salesforce-apex-json-rpc/blob/main/examples/README.md Presents a pattern for writing unit and integration tests for JSON-RPC handlers and the runtime environment. This enables developers to verify the correctness of their API logic and ensure reliable operation. ```apex /* testing-handler.apex */ @IsTest private class MyHandlerTests { @IsTest static void testMyMethodSuccess() { MyRequest req = new MyRequest(); req.message = 'Test Message'; MyHandler handler = new MyHandler(); MyResponse res = handler.handle(req); System.assertEquals('Received: Test Message', res.reply, 'Response message should match input'); } } @IsTest private class MyModuleIntegrationTests { @IsTest static void testModuleExecution() { // Assuming MyModule is registered and accessible // Object result = JsonRpcRuntime.execute('MyModule', 'myMethod', JSON.serialize(new MyRequest(message='Integration Test')), null); // MyResponse res = (MyResponse)result; // System.assertEquals('Received: Integration Test', res.reply, 'Integration test failed'); } } ``` -------------------------------- ### Configure JSON-RPC Modules using Apex JsonRpcModuleBuilder Source: https://context7.com/damecek/salesforce-apex-json-rpc/llms.txt Explains how to use JsonRpcModuleBuilder as an abstract base class for centralizing module configuration. Developers can extend this class and implement the `configure` method to register handlers. The example demonstrates building a module with math-related handlers and executing a request. ```apex public class MathModuleBuilder extends JsonRpcModuleBuilder { public override void configure(JsonRpcModule module) { module.register(new SumHandler()); module.register(new MultiplyHandler()); module.register(new DivideHandler()); } } JsonRpcModule module = new MathModuleBuilder().build(); JsonRpcExecutionResult result = JsonRpcServiceRuntime.execute( '{"jsonrpc":"2.0","method":"math.sum","params":{"a":10,"b":5},"id":1}', module ); System.debug(result.toJson()); // Output: {"jsonrpc":"2.0","result":{"sum":15},"id":1} ``` -------------------------------- ### Execute JSON-RPC Requests with Apex JsonRpcServiceRuntime Source: https://context7.com/damecek/salesforce-apex-json-rpc/llms.txt Demonstrates how to use the JsonRpcServiceRuntime to execute JSON-RPC requests. It covers defining typed parameter and result Data Transfer Objects (DTOs) with validation, implementing method handlers, and registering them with a module for execution. The example shows a simple 'math.sum' method. ```apex public class SumParams extends JsonRpcParamsBase { public Integer a; public Integer b; public override void validate() { if (a == null || b == null) { throw new JsonRpcException('a and b are required.'); } } } public class SumResult extends JsonRpcResultBase { public Integer sum; } public class SumHandler implements JsonRpcMethodHandler { public String methodName() { return 'math.sum'; } public Type paramsType() { return SumParams.class; } public Type resultType() { return SumResult.class; } public Object invoke(Object params, JsonRpcInvocationContext context) { SumParams p = (SumParams) params; SumResult r = new SumResult(); r.sum = p.a + p.b; return r; } } JsonRpcModule module = new JsonRpcModule().register(new SumHandler()); JsonRpcExecutionResult result = JsonRpcServiceRuntime.execute( '{"jsonrpc":"2.0","method":"math.sum","params":{"a":2,"b":3},"id":1}', module ); System.debug(result.toJson()); // Output: {"jsonrpc":"2.0","result":{"sum":5},"id":1} ``` -------------------------------- ### Construct Apex JSON-RPC Success and Failure Responses Source: https://context7.com/damecek/salesforce-apex-json-rpc/llms.txt Provides examples of using the JsonRpcResponse class in Apex to construct both success and failure responses for JSON-RPC 2.0. It covers creating responses with results, errors, and parsing existing responses from raw data. ```apex // Create success response JsonRpcResponse success = JsonRpcResponse.success(1, new Map{ 'userId' => 'U123', 'status' => 'active' }); System.debug(JSON.serialize(success.toMap())); // {"jsonrpc":"2.0","result":{"userId":"U123","status":"active"},"id":1} // Create failure response JsonRpcResponse failure = JsonRpcResponse.failure(2, JsonRpcError.methodNotFound('Unknown method: foo.bar')); System.debug(JSON.serialize(failure.toMap())); // {"jsonrpc":"2.0","error":{"code":-32601,"message":"Method not found","data":"Unknown method: foo.bar"},"id":2} // Parse response from untyped map String responseJson = '{"jsonrpc":"2.0","result":{"sum":5},"id":1}'; Map raw = (Map) JSON.deserializeUntyped(responseJson); JsonRpcResponse parsed = JsonRpcResponse.fromMap(raw); System.debug('Has result: ' + parsed.hasResult); // true System.debug('Result: ' + parsed.result); // {sum=5} ``` -------------------------------- ### Register and Resolve JSON-RPC Handlers with Apex JsonRpcModule Source: https://context7.com/damecek/salesforce-apex-json-rpc/llms.txt Illustrates the usage of JsonRpcModule for managing JSON-RPC method handlers. It shows how to register multiple handlers using fluent calls and how to resolve a handler by its method name. The example also demonstrates that attempting to resolve a non-existent method returns null. ```apex JsonRpcModule module = new JsonRpcModule() .register(new SumHandler()) .register(new MultiplyHandler()) .register(new DivideHandler()); JsonRpcMethodHandler handler = module.resolve('math.sum'); if (handler != null) { System.debug('Handler found for: ' + handler.methodName()); } JsonRpcMethodHandler missing = module.resolve('unknown.method'); System.assertEquals(null, missing); ``` -------------------------------- ### Apex JSON-RPC Batch Processing with Mixed Results Source: https://github.com/damecek/salesforce-apex-json-rpc/blob/main/examples/README.md Illustrates handling a batch of JSON-RPC requests, including successful calls, requests with invalid parameters, notifications (which don't expect a response), and malformed individual items within the batch. This showcases robust error handling for batch operations. ```apex /* batch-mixed.apex */ // Assume MyModule and MyRequest/MyResponse are defined as in minimal-module.apex // Example Batch Execution // List batch = new List(); // batch.add(JSON.deserialize('{"id": 1, "method": "myMethod", "params": {"message": "Success"}}', Object.class)); // Success // batch.add(JSON.deserialize('{"id": 2, "method": "myMethod", "params": "invalid"}', Object.class)); // Invalid params // batch.add(JSON.deserialize('{"method": "myNotification", "params": {"data": "fire and forget"}}', Object.class)); // Notification // batch.add(JSON.deserialize('malformed json', Object.class)); // Malformed item // JsonRpcRuntime.executeBatch(batch); ``` -------------------------------- ### Apex JSON-RPC Method Not Found and Invalid Request Handling Source: https://github.com/damecek/salesforce-apex-json-rpc/blob/main/examples/README.md Details the standard behavior of the JSON-RPC framework when a requested method does not exist or when the incoming request is malformed (invalid JSON, missing required fields). This covers common error scenarios for API consumers. ```apex /* method-not-found-and-invalid-request.apex */ // Example of a request that would trigger 'method not found' // JsonRpcRuntime.execute('MyModule', 'nonExistentMethod', '"some params"', null); // Example of an invalid request (malformed JSON) // JsonRpcRuntime.execute('MyModule', 'myMethod', '{invalid json', null); // The framework automatically returns standard JSON-RPC error responses for these cases. ``` -------------------------------- ### Handle Standard JSON-RPC Protocol Errors (Apex) Source: https://context7.com/damecek/salesforce-apex-json-rpc/llms.txt Demonstrates how the framework automatically handles standard JSON-RPC 2.0 errors. Examples include 'Method not found' (-32601), 'Invalid Request' (-32600), 'Parse error' (-32700), and 'Invalid params' (-32602), showing the resulting error responses. ```apex JsonRpcModule module = new JsonRpcModule(); // Method not found (-32601) JsonRpcExecutionResult notFound = JsonRpcServiceRuntime.execute( '{"jsonrpc":"2.0","method":"missing.method","id":1}', module ); System.debug(notFound.toJson()); // {"jsonrpc":"2.0","error":{"code":-32601,"message":"Method not found","data":"Method not registered: missing.method"},"id":1} // Invalid request (-32600) - missing required fields JsonRpcExecutionResult invalidReq = JsonRpcServiceRuntime.execute( '{"jsonrpc":"2.0","id":2}', module ); System.debug(invalidReq.toJson()); // {"jsonrpc":"2.0","error":{"code":-32600,"message":"Invalid Request","data":"method is required..."},"id":2} // Parse error (-32700) - malformed JSON JsonRpcExecutionResult parseErr = JsonRpcServiceRuntime.execute( '{invalid json}', module ); System.debug(parseErr.toJson()); // {"jsonrpc":"2.0","error":{"code":-32700,"message":"Parse error","data":"..."},"id":null} // Invalid params (-32602) - validation failure module.register(new SumHandler()); JsonRpcExecutionResult invalidParams = JsonRpcServiceRuntime.execute( '{"jsonrpc":"2.0","method":"math.sum","params":{"a":1},"id":3}', module ); System.debug(invalidParams.toJson()); // {"jsonrpc":"2.0","error":{"code":-32602,"message":"Invalid params","data":"..."},"id":3} ``` -------------------------------- ### Prepare Scratch Org for New Task (Bash) Source: https://github.com/damecek/salesforce-apex-json-rpc/blob/main/README.md Commands for preparing a fresh scratch org for a new development task. The default command creates a new org, while the `skip-org` variant allows for local overrides without creating a new org. ```bash npm run task:prepare # Explicit local override: npm run task:prepare:skip-org ``` -------------------------------- ### Configure Runtime Options for Apex JSON-RPC Source: https://context7.com/damecek/salesforce-apex-json-rpc/llms.txt Demonstrates how to configure runtime options for the Apex JSON-RPC service, specifically enabling internal error details for debugging. This affects the verbosity of error messages returned in responses. ```apex JsonRpcServiceRuntimeOptions options = new JsonRpcServiceRuntimeOptions(); options.includeInternalErrorDetails = true; JsonRpcModule module = new JsonRpcModule().register(new SumHandler()); JsonRpcExecutionResult result = JsonRpcServiceRuntime.execute( '{"jsonrpc":"2.0","method":"math.sum","params":{"a":1,"b":2},"id":1}', module, options ); // With includeInternalErrorDetails = true, internal errors include exception message // With includeInternalErrorDetails = false (default), generic "Internal error" is returned ``` -------------------------------- ### Execute JSON-RPC Requests and Handle Results (Apex) Source: https://context7.com/damecek/salesforce-apex-json-rpc/llms.txt Demonstrates executing single and batched JSON-RPC requests using `JsonRpcServiceRuntime.execute`. It shows how to inspect the `JsonRpcExecutionResult` for batch status, response presence, and how to serialize the result to JSON. Notifications without an ID do not produce a response. ```apex JsonRpcModule module = new JsonRpcModule().register(new SumHandler()); // Single request execution JsonRpcExecutionResult singleResult = JsonRpcServiceRuntime.execute( '{"jsonrpc":"2.0","method":"math.sum","params":{"a":1,"b":2},"id":1}', module ); System.debug('Is batch: ' + singleResult.isBatch); // false System.debug('Has response: ' + singleResult.hasResponse); // true System.debug('Responses: ' + singleResult.responses.size()); // 1 System.debug(singleResult.toJson()); // {"jsonrpc":"2.0","result":{"sum":3},"id":1} // Notification (no id) produces no response JsonRpcExecutionResult notifResult = JsonRpcServiceRuntime.execute( '{"jsonrpc":"2.0","method":"math.sum","params":{"a":1,"b":2}}', module ); System.debug('Has response: ' + notifResult.hasResponse); // false System.debug(notifResult.toJson()); // null ``` -------------------------------- ### Integration Test Apex JSON-RPC Full Runtime Source: https://context7.com/damecek/salesforce-apex-json-rpc/llms.txt Tests the entire JSON-RPC runtime pipeline, including request parsing, handler invocation, and response generation. This pattern ensures that the framework components work together correctly and involves using `JsonRpcServiceRuntime.execute()`. ```apex // Integration test pattern - test full runtime pipeline @IsTest static void testSumHandler_IntegrationStyle() { JsonRpcModule module = new JsonRpcModule().register(new SumHandler()); JsonRpcExecutionResult execution = JsonRpcServiceRuntime.execute( '{"jsonrpc":"2.0","method":"math.sum","params":{"a":10,"b":20},"id":77}', module ); System.assertEquals(true, execution.hasResponse); System.assertEquals(false, execution.isBatch); System.assertEquals(1, execution.responses.size()); JsonRpcResponse response = execution.responses[0]; System.assertEquals(true, response.hasResult); System.assertEquals(false, response.hasError); System.assert(execution.toJson().contains('"sum":30')); } ``` -------------------------------- ### Access Request Metadata in Handlers (Apex) Source: https://context7.com/damecek/salesforce-apex-json-rpc/llms.txt Illustrates how to implement a `JsonRpcMethodHandler` and access request metadata within the `invoke` method using the `JsonRpcInvocationContext`. This context provides details like `requestId`, `methodName`, `batchIndex`, `rawRequest`, and `correlationMetadata` for tracing and logging. ```apex public class AuditedHandler implements JsonRpcMethodHandler { public String methodName() { return 'audit.action'; } public Type paramsType() { return AuditParams.class; } public Type resultType() { return AuditResult.class; } public Object invoke(Object params, JsonRpcInvocationContext context) { // Access request metadata Object requestId = context.requestId; // Request ID (String, Integer, Long, Decimal, or null) String method = context.methodName; // 'audit.action' Integer batchIdx = context.batchIndex; // 0-based index in batch, 0 for single requests Map rawReq = context.rawRequest; // Original untyped request envelope // Use correlation metadata for tracing Map correlation = context.correlationMetadata; correlation.put('traceId', 'trace-' + String.valueOf(System.currentTimeMillis())); AuditResult r = new AuditResult(); r.recorded = true; return r; } } ``` -------------------------------- ### Implement Custom Exception Mapping for Apex JSON-RPC Source: https://context7.com/damecek/salesforce-apex-json-rpc/llms.txt Shows how to implement a custom exception mapper for Apex JSON-RPC to translate domain-specific exceptions into JSON-RPC errors. This allows for more user-friendly error reporting by mapping internal exceptions to predefined error codes and messages. ```apex // Define domain exception public class DomainFailureException extends Exception {} // Implement custom mapper public class CustomExceptionMapper implements JsonRpcExceptionMapper { public JsonRpcError mapException(Exception ex, JsonRpcInvocationContext context) { if (ex instanceof DomainFailureException) { return new JsonRpcError(12001, 'Domain failure', new Map{ 'method' => context.methodName, 'detail' => ex.getMessage() }); } // Fall back to internal error for unknown exceptions return JsonRpcError.internalError(); } } // Configure runtime with custom mapper JsonRpcServiceRuntimeOptions options = new JsonRpcServiceRuntimeOptions(); options.exceptionMapper = new CustomExceptionMapper(); JsonRpcModule module = new JsonRpcModule().register(new FailingHandler()); JsonRpcExecutionResult result = JsonRpcServiceRuntime.execute( '{"jsonrpc":"2.0","method":"domain.fail","params":{},"id":9}', module, options ); System.debug(result.toJson()); // Output: {"jsonrpc":"2.0","error":{"code":12001,"message":"Domain failure","data":{"method":"domain.fail","detail":"..."}},"id":9} ``` -------------------------------- ### Process JSON-RPC Batch Requests in Apex Source: https://context7.com/damecek/salesforce-apex-json-rpc/llms.txt Demonstrates how the Salesforce Apex JSON-RPC runtime automatically handles JSON-RPC batch requests, which are arrays of request objects. Each request within the batch is processed independently. Notifications (requests without an `id`) do not produce a response entry. ```apex JsonRpcModule module = new JsonRpcModule().register(new SumHandler()); // Batch with: success, invalid params, notification (no id), malformed item String batchPayload = '[' + '{"jsonrpc":"2.0","method":"math.sum","params":{"a":1,"b":2},"id":1}, '{"jsonrpc":"2.0","method":"math.sum","params":{"a":1},"id":2}, '{"jsonrpc":"2.0","method":"math.sum","params":{"a":5,"b":6}}, '7' + ']'; JsonRpcExecutionResult batchResult = JsonRpcServiceRuntime.execute(batchPayload, module); System.debug('Is batch: ' + batchResult.isBatch); // true System.debug('Has response: ' + batchResult.hasResponse); // true System.debug('Response count: ' + batchResult.responses.size()); // 3 (notification omitted) System.debug(batchResult.toJson()); // Output: [ // {"jsonrpc":"2.0","result":{"sum":3},"id":1}, // {"jsonrpc":"2.0","error":{"code":-32602,"message":"Invalid params","data":"..."},"id":2}, // {"jsonrpc":"2.0","error":{"code":-32600,"message":"Invalid Request","data":"..."},"id":null} // ] ``` -------------------------------- ### Create Standard and Custom JSON-RPC 2.0 Errors in Apex Source: https://context7.com/damecek/salesforce-apex-json-rpc/llms.txt Illustrates the use of the JsonRpcError factory class in Apex to create standard JSON-RPC 2.0 error objects, including parse errors, invalid requests, method not found, invalid parameters, and internal errors. It also shows how to create custom errors with application-specific codes and data payloads. ```apex // Standard error factories JsonRpcError parseErr = JsonRpcError.parseError(); // -32700 Parse error JsonRpcError invalidReq = JsonRpcError.invalidRequest(); // -32600 Invalid Request JsonRpcError notFound = JsonRpcError.methodNotFound(); // -32601 Method not found JsonRpcError invalidParams = JsonRpcError.invalidParams(); // -32602 Invalid params JsonRpcError internal = JsonRpcError.internalError(); // -32603 Internal error // With additional data payload JsonRpcError parseErrData = JsonRpcError.parseError('Unexpected token at position 42'); JsonRpcError invalidReqData = JsonRpcError.invalidRequest('Missing jsonrpc field'); // Custom error with application-specific code JsonRpcError customErr = new JsonRpcError(40001, 'Resource not found', new Map{ 'resourceType' => 'Account', 'resourceId' => '001xx000003DGbYAAW' }); // Convert to map for JSON serialization Map errorMap = customErr.toMap(); // {"code":40001,"message":"Resource not found","data":{"resourceType":"Account","resourceId":"001xx000003DGbYAAW"}} ``` -------------------------------- ### Implement JSON-RPC Method Handler in Apex Source: https://context7.com/damecek/salesforce-apex-json-rpc/llms.txt Defines the interface contract for implementing JSON-RPC method handlers. Each handler specifies its method name, parameter type, result type, and the core invocation logic. It uses Apex classes to structure the request and response data. ```apex public class GetUserHandler implements JsonRpcMethodHandler { // Method name used in JSON-RPC requests public String methodName() { return 'user.get'; } // Params DTO type for automatic deserialization and validation public Type paramsType() { return GetUserParams.class; } // Result DTO type for response serialization public Type resultType() { return GetUserResult.class; } // Core method logic - receives typed params and invocation context public Object invoke(Object params, JsonRpcInvocationContext context) { GetUserParams p = (GetUserParams) params; // Access context metadata System.debug('Request ID: ' + context.requestId); System.debug('Method: ' + context.methodName); System.debug('Batch Index: ' + context.batchIndex); GetUserResult r = new GetUserResult(); r.userId = p.userId; r.username = 'user_' + p.userId; return r; } } ``` -------------------------------- ### JsonRpcInvocationContext - Request Metadata Source: https://context7.com/damecek/salesforce-apex-json-rpc/llms.txt The JsonRpcInvocationContext provides handlers with metadata about the incoming JSON-RPC request, including request ID, method name, batch index, and the original raw request. ```APIDOC ## JsonRpcInvocationContext - Request Metadata Context object passed to handlers and exception mappers containing request metadata and correlation information. ### Description This context object is available within handler `invoke` methods and exception mappers, providing access to request details and correlation data. ### Fields - **requestId** (Object) - The ID of the request. Can be String, Integer, Long, Decimal, or null. - **methodName** (String) - The name of the method being invoked. - **batchIndex** (Integer) - The 0-based index of the request within a batch. 0 for single requests. - **rawRequest** (Map) - The original, untyped JSON-RPC request envelope. - **correlationMetadata** (Map) - A map for storing and retrieving correlation information, useful for distributed tracing. ### Example Usage in Handler ```apex public class AuditedHandler implements JsonRpcMethodHandler { public String methodName() { return 'audit.action'; } public Type paramsType() { return AuditParams.class; } public Type resultType() { return AuditResult.class; } public Object invoke(Object params, JsonRpcInvocationContext context) { // Access request metadata Object requestId = context.requestId; // Request ID String method = context.methodName; // 'audit.action' Integer batchIdx = context.batchIndex; // 0-based index in batch Map rawReq = context.rawRequest; // Original untyped request envelope // Use correlation metadata for tracing Map correlation = context.correlationMetadata; correlation.put('traceId', 'trace-' + String.valueOf(System.currentTimeMillis())); AuditResult r = new AuditResult(); r.recorded = true; return r; } } ``` ``` -------------------------------- ### Unit Test Apex JSON-RPC Handler Logic Source: https://context7.com/damecek/salesforce-apex-json-rpc/llms.txt Tests the logic of a specific handler in isolation without involving the full runtime. This pattern is useful for verifying individual handler functionality and requires instantiating the handler and its parameters directly. ```apex // Unit test pattern - test handler logic in isolation @IsTest static void testSumHandler_UnitStyle() { SumParams p = new SumParams(); p.a = 4; p.b = 8; SumHandler handler = new SumHandler(); SumResult result = (SumResult) handler.invoke(p, new JsonRpcInvocationContext()); System.assertEquals(12, result.sum); } ``` -------------------------------- ### Error Handling - Standard Protocol Errors Source: https://context7.com/damecek/salesforce-apex-json-rpc/llms.txt The framework automatically handles standard JSON-RPC 2.0 error conditions, returning appropriate error codes and messages for issues like method not found, invalid requests, parse errors, and invalid parameters. ```APIDOC ## Error Handling - Standard Protocol Errors The framework automatically handles standard JSON-RPC 2.0 error conditions with appropriate error codes. ### Description This section details how the JSON-RPC service runtime handles common errors as defined by the JSON-RPC 2.0 specification, providing standardized error responses. ### Standard Error Codes - **-32601: Method not found** - The method specified in the request does not exist or is not registered. - **-32600: Invalid Request** - The request is malformed or missing required fields (e.g., 'method' or 'jsonrpc' version). - **-32700: Parse error** - The request body is not valid JSON. - **-32602: Invalid params** - The parameters provided for the method do not match the expected signature or validation fails. ### Examples ```apex JsonRpcModule module = new JsonRpcModule(); // Method not found (-32601) JsonRpcExecutionResult notFound = JsonRpcServiceRuntime.execute( '{"jsonrpc":"2.0","method":"missing.method","id":1}', module ); System.debug(notFound.toJson()); // {"jsonrpc":"2.0","error":{"code":-32601,"message":"Method not found","data":"Method not registered: missing.method"},"id":1} // Invalid request (-32600) - missing required fields JsonRpcExecutionResult invalidReq = JsonRpcServiceRuntime.execute( '{"jsonrpc":"2.0","id":2}', module ); System.debug(invalidReq.toJson()); // {"jsonrpc":"2.0","error":{"code":-32600,"message":"Invalid Request","data":"method is required..."},"id":2} // Parse error (-32700) - malformed JSON JsonRpcExecutionResult parseErr = JsonRpcServiceRuntime.execute( '{invalid json}', module ); System.debug(parseErr.toJson()); // {"jsonrpc":"2.0","error":{"code":-32700,"message":"Parse error","data":"..."},"id":null} // Invalid params (-32602) - validation failure module.register(new SumHandler()); // Assuming SumHandler is registered JsonRpcExecutionResult invalidParams = JsonRpcServiceRuntime.execute( '{"jsonrpc":"2.0","method":"math.sum","params":{"a":1},"id":3}', module ); System.debug(invalidParams.toJson()); // {"jsonrpc":"2.0","error":{"code":-32602,"message":"Invalid params","data":"..."},"id":3} ``` ``` -------------------------------- ### Implement Apex JSON-RPC Method Handler Source: https://github.com/damecek/salesforce-apex-json-rpc/blob/main/README.md Implements the `JsonRpcMethodHandler` interface to define a specific JSON-RPC method. This includes specifying the method name, parameter types, result types, and the invocation logic. The `invoke` method processes the typed parameters and returns the typed result. ```apex public class SumHandler implements JsonRpcMethodHandler { public String methodName() { return 'math.sum'; } public Type paramsType() { return SumParams.class; } public Type resultType() { return SumResult.class; } public Object invoke(Object params, JsonRpcInvocationContext context) { SumParams typed = (SumParams) params; SumResult result = new SumResult(); result.sum = typed.a + typed.b; return result; } } ``` -------------------------------- ### Execute Apex JSON-RPC Request Source: https://github.com/damecek/salesforce-apex-json-rpc/blob/main/README.md Executes a JSON-RPC 2.0 request using the `JsonRpcServiceRuntime`. This involves creating a module with registered handlers, defining the request JSON, and then calling the `execute` method. The result is a `JsonRpcExecutionResult` object that can be converted back to JSON. ```apex JsonRpcModule module = new JsonRpcModule().register(new SumHandler()); JsonRpcExecutionResult execResult = JsonRpcServiceRuntime.execute( '{"jsonrpc":"2.0","method":"math.sum","params":{"a":1,"b":2},"id":1}', module ); String responseJson = execResult.toJson(); ``` -------------------------------- ### JsonRpcExecutionResult - Execution Output Source: https://context7.com/damecek/salesforce-apex-json-rpc/llms.txt The JsonRpcExecutionResult class is a container for JSON-RPC execution outcomes. It holds response payloads, batch execution status, and facilitates serialization of results. ```APIDOC ## JsonRpcExecutionResult - Execution Output Container for JSON-RPC execution results including response payloads, batch status, and serialization. ### Method `JsonRpcServiceRuntime.execute(String request, JsonRpcModule module)` ### Description Executes a single JSON-RPC request or a batch of requests against a registered module. ### Request Example ```apex JsonRpcModule module = new JsonRpcModule().register(new SumHandler()); // Single request execution JsonRpcExecutionResult singleResult = JsonRpcServiceRuntime.execute( '{"jsonrpc":"2.0","method":"math.sum","params":{"a":1,"b":2},"id":1}', module ); System.debug('Is batch: ' + singleResult.isBatch); // false System.debug('Has response: ' + singleResult.hasResponse); // true System.debug('Responses: ' + singleResult.responses.size()); // 1 System.debug(singleResult.toJson()); // {"jsonrpc":"2.0","result":{"sum":3},"id":1} // Notification (no id) produces no response JsonRpcExecutionResult notifResult = JsonRpcServiceRuntime.execute( '{"jsonrpc":"2.0","method":"math.sum","params":{"a":1,"b":2}}', module ); System.debug('Has response: ' + notifResult.hasResponse); // false System.debug(notifResult.toJson()); // null ``` ### Response #### Success Response (200) - **isBatch** (Boolean) - Indicates if the execution was for a batch of requests. - **hasResponse** (Boolean) - Indicates if the execution resulted in a response (notifications do not produce responses). - **responses** (List) - A list of responses for batch executions. #### Response Example ```json { "jsonrpc": "2.0", "result": { "sum": 3 }, "id": 1 } ``` ``` -------------------------------- ### Validate and Normalize JSON-RPC IDs (Apex) Source: https://context7.com/damecek/salesforce-apex-json-rpc/llms.txt Provides utility functions for validating and normalizing JSON-RPC request/response IDs according to the specification. `JsonRpcId.isSupported` checks if an ID is of a valid type (null, String, Number), while `JsonRpcId.normalizedOrNull` returns the ID if valid or null otherwise. ```apex // Check if value is a valid JSON-RPC id type System.assertEquals(true, JsonRpcId.isSupported(null)); // null is valid System.assertEquals(true, JsonRpcId.isSupported('req-123')); // String System.assertEquals(true, JsonRpcId.isSupported(42)); // Integer System.assertEquals(true, JsonRpcId.isSupported(9007199254740992L)); // Long System.assertEquals(true, JsonRpcId.isSupported(3.14)); // Decimal System.assertEquals(false, JsonRpcId.isSupported(new List())); // Arrays not supported System.assertEquals(false, JsonRpcId.isSupported(new Map())); // Objects not supported // Normalize ID (return value if supported, null otherwise) Object normalized = JsonRpcId.normalizedOrNull('valid-id'); // 'valid-id' Object invalid = JsonRpcId.normalizedOrNull(new List{1,2}); // null ``` -------------------------------- ### Define Typed Parameters with Validation in Apex Source: https://context7.com/damecek/salesforce-apex-json-rpc/llms.txt Provides a base class for typed parameter Data Transfer Objects (DTOs). Developers extend this class and override the `validate()` method to implement custom validation logic that is automatically executed during request processing. Invalid parameters result in a JSON-RPC error. ```apex public class CreateOrderParams extends JsonRpcParamsBase { public String productId; public Integer quantity; public String customerId; public override void validate() { if (String.isBlank(productId)) { throw new JsonRpcException('productId is required.'); } if (quantity == null || quantity <= 0) { throw new JsonRpcException('quantity must be a positive integer.'); } if (String.isBlank(customerId)) { throw new JsonRpcException('customerId is required.'); } } } // Validation runs automatically during execute() // Invalid params trigger -32602 Invalid params error ``` -------------------------------- ### JsonRpcId - ID Type Utilities Source: https://context7.com/damecek/salesforce-apex-json-rpc/llms.txt The JsonRpcId utility class provides methods for validating and normalizing JSON-RPC request and response IDs according to the specification. ```APIDOC ## JsonRpcId - ID Type Utilities Utility class for validating and normalizing JSON-RPC request/response IDs per specification requirements. ### Description This class helps ensure that request and response IDs adhere to the JSON-RPC 2.0 specification, which allows null, String, Number (Integer, Long, Decimal) types for IDs. ### Methods - **isSupported(Object id)**: Returns `true` if the provided object is a supported JSON-RPC ID type, `false` otherwise. - **normalizedOrNull(Object id)**: Returns the normalized ID if it's supported, otherwise returns `null`. ### Examples ```apex // Check if value is a valid JSON-RPC id type System.assertEquals(true, JsonRpcId.isSupported(null)); // null is valid System.assertEquals(true, JsonRpcId.isSupported('req-123')); // String System.assertEquals(true, JsonRpcId.isSupported(42)); // Integer System.assertEquals(true, JsonRpcId.isSupported(9007199254740992L)); // Long System.assertEquals(true, JsonRpcId.isSupported(3.14)); // Decimal System.assertEquals(false, JsonRpcId.isSupported(new List())); // Arrays not supported System.assertEquals(false, JsonRpcId.isSupported(new Map())); // Objects not supported // Normalize ID (return value if supported, null otherwise) Object normalized = JsonRpcId.normalizedOrNull('valid-id'); // 'valid-id' Object invalid = JsonRpcId.normalizedOrNull(new List{1,2}); // null ``` ``` -------------------------------- ### Define Apex JSON-RPC Parameters and Result DTOs Source: https://github.com/damecek/salesforce-apex-json-rpc/blob/main/README.md Defines custom parameter and result classes for JSON-RPC 2.0 requests. These classes extend base DTOs and can include validation logic. They are used to strongly type the input and output of Apex JSON-RPC methods. ```apex public class SumParams extends JsonRpcParamsBase { public Integer a; public Integer b; public override void validate() { if (a == null || b == null) { throw new JsonRpcException('a and b are required.'); } } } public class SumResult extends JsonRpcResultBase { public Integer sum; } ``` -------------------------------- ### Define Typed Results with Validation in Apex Source: https://context7.com/damecek/salesforce-apex-json-rpc/llms.txt Offers a base class for typed result DTOs. This class can be extended, and the `validate()` method optionally overridden to perform result validation before serialization. This ensures the integrity of the response data sent back to the client. ```apex public class CreateOrderResult extends JsonRpcResultBase { public String orderId; public String status; public Datetime createdAt; public override void validate() { if (String.isBlank(orderId)) { throw new JsonRpcException('orderId is required in result.'); } } } // Result validation ensures response integrity public class CreateOrderHandler implements JsonRpcMethodHandler { public String methodName() { return 'order.create'; } public Type paramsType() { return CreateOrderParams.class; } public Type resultType() { return CreateOrderResult.class; } public Object invoke(Object params, JsonRpcInvocationContext context) { CreateOrderParams p = (CreateOrderParams) params; CreateOrderResult r = new CreateOrderResult(); r.orderId = 'ORD-' + String.valueOf(System.currentTimeMillis()); r.status = 'CREATED'; r.createdAt = Datetime.now(); return r; } } ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.