Documentation
¶
Overview ¶
Package jsonrpc provides constructs and utilities for building JSON-RPC 2.0 services with Loom. This package contains the core types, client and server implementations, and code generation support for services that communicate using the JSON-RPC protocol.
JSON-RPC is a stateless, light-weight remote procedure call (RPC) protocol. This package implements the JSON-RPC 2.0 specification as defined in https://www.jsonrpc.org/specification.
The package supports:
- Request/response method calls
- Notification requests (fire-and-forget)
- Batch requests for multiple calls
- Structured error handling with error codes
- HTTP, Server-Sent Events (SSE) and WebSocket transports
Code generated by Loom uses this package to create JSON-RPC clients and servers that seamlessly integrate with Loom's design-first approach and provide type-safe method invocation.
Index ¶
- func CompleteStream(ctx context.Context, hasID bool, id any, result any, ...) error
- func CompleteStreamError(ctx context.Context, hasID bool, send func() error) error
- func IDToString(id any) string
- func NewErrorData(err error) any
- func NewHTTPHandler(spec HTTPHandlerSpec) http.Handler
- func NewRequestID() (string, error)
- func ReceiveWebSocketRequest(ctx context.Context, stream *loomhttp.WebSocketStream, ...) error
- func ServeHTTP(w http.ResponseWriter, r *http.Request, spec HTTPHandlerSpec)
- func ServeMixed(w http.ResponseWriter, r *http.Request, spec MixedHandlerSpec)
- func ServeSSE(w http.ResponseWriter, r *http.Request, spec SSEHandlerSpec)
- func ServeWebSocket(w http.ResponseWriter, r *http.Request, spec WebSocketHandlerSpec)
- func ValidateResponseContract(observation *ResponseContractObservation, contract ResponseContractCase) error
- type Code
- type ErrorData
- type ErrorResponse
- type HTTPDispatch
- type HTTPHandlerSpec
- type MixedHandlerSpec
- type RawErrorResponse
- type RawRequest
- type RawResponse
- type Request
- type Response
- type ResponseContractCase
- type ResponseContractCaseKind
- type ResponseContractEvent
- type ResponseContractObservation
- type SSEDispatch
- type SSEErrorSender
- type SSEHandlerSpec
- type StreamConfig
- type StreamConfigOption
- func WithCloseTimeout(timeout time.Duration) StreamConfigOption
- func WithCompression(enabled bool) StreamConfigOption
- func WithConnectionTimeout(timeout time.Duration) StreamConfigOption
- func WithErrorHandler(handler StreamErrorHandler) StreamConfigOption
- func WithPingInterval(interval time.Duration) StreamConfigOption
- func WithRequestTimeout(timeout time.Duration) StreamConfigOption
- func WithResultChannelBuffer(size int) StreamConfigOption
- func WithRetryConfig(maxRetries int, baseDelay, maxDelay time.Duration) StreamConfigOption
- func WithWebSocketBuffers(readSize, writeSize int) StreamConfigOption
- type StreamErrorHandler
- type StreamErrorType
- type StreamingResponseContract
- type WebSocketDispatch
- type WebSocketErrorSender
- type WebSocketHandlerSpec
- type WebSocketMethodMatcher
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func CompleteStream ¶ added in v1.8.0
func CompleteStream( ctx context.Context, hasID bool, id any, result any, send func(*Response) error, ) error
CompleteStream sends a final JSON-RPC success response when the initiating request has an ID. Notification and GET-listener completions are suppressed.
func CompleteStreamError ¶ added in v1.8.0
CompleteStreamError sends a final JSON-RPC error response when the initiating request has an ID. Notification errors are suppressed.
func IDToString ¶
IDToString converts a JSON-RPC ID to a string. JSON unmarshaling produces string or float64 for numeric values.
func NewErrorData ¶
NewErrorData returns structured JSON-RPC error data for err when Loom error metadata is available. It returns nil when err carries no machine-usable Loom error information.
func NewHTTPHandler ¶ added in v1.8.0
func NewHTTPHandler(spec HTTPHandlerSpec) http.Handler
NewHTTPHandler creates a JSON-RPC HTTP handler. The handler owns envelope validation, batch framing, notification suppression, and request observation.
func NewRequestID ¶ added in v1.7.0
NewRequestID returns a random RFC 9562 version 4 UUID for a JSON-RPC request.
func ReceiveWebSocketRequest ¶ added in v1.8.0
func ReceiveWebSocketRequest( ctx context.Context, stream *loomhttp.WebSocketStream, matches WebSocketMethodMatcher, dispatch WebSocketDispatch, sendError WebSocketErrorSender, ) error
ReceiveWebSocketRequest reads, validates, and dispatches one JSON-RPC WebSocket request frame.
func ServeHTTP ¶ added in v1.8.0
func ServeHTTP(w http.ResponseWriter, r *http.Request, spec HTTPHandlerSpec)
ServeHTTP executes one JSON-RPC HTTP request with the supplied service adapters.
func ServeMixed ¶ added in v1.8.0
func ServeMixed(w http.ResponseWriter, r *http.Request, spec MixedHandlerSpec)
ServeMixed negotiates JSON-RPC HTTP or SSE handling for one route.
func ServeSSE ¶ added in v1.8.0
func ServeSSE(w http.ResponseWriter, r *http.Request, spec SSEHandlerSpec)
ServeSSE executes one JSON-RPC SSE request with generated typed adapters.
func ServeWebSocket ¶ added in v1.8.0
func ServeWebSocket(w http.ResponseWriter, r *http.Request, spec WebSocketHandlerSpec)
ServeWebSocket upgrades one HTTP request and runs a generated typed stream.
func ValidateResponseContract ¶ added in v1.8.0
func ValidateResponseContract(observation *ResponseContractObservation, contract ResponseContractCase) error
ValidateResponseContract validates transport-owned JSON-RPC wire invariants.
Types ¶
type Code ¶
type Code int
Code is a JSON-RPC error code, see JSON-RPC 2.0 section 5.1
func CodeForServiceError ¶ added in v1.8.0
func CodeForServiceError(err *loom.ServiceError) Code
CodeForServiceError maps framework validation failures to JSON-RPC codes.
type ErrorData ¶
type ErrorData struct {
// Name is the Loom error name when available.
Name string `json:"name,omitempty"`
// ID is the unique Loom service error instance identifier.
ID string `json:"id,omitempty"`
// Temporary reports whether the error is temporary.
Temporary bool `json:"temporary,omitempty"`
// Timeout reports whether the error is a timeout.
Timeout bool `json:"timeout,omitempty"`
// Fault reports whether the error is a server-side fault.
Fault bool `json:"fault,omitempty"`
// Remedy contains optional remediation guidance.
Remedy *loom.ErrorRemedy `json:"remedy,omitempty"`
}
ErrorData is the default structured JSON-RPC error data emitted for Loom errors. It is intended for machine consumers and carries transport-neutral error characteristics plus optional remediation guidance.
type ErrorResponse ¶
type ErrorResponse struct {
Code Code `json:"code"`
Message string `json:"message"`
Data any `json:"data,omitempty"`
}
ErrorResponse represents a JSON-RPC error response.
func (*ErrorResponse) Error ¶
func (e *ErrorResponse) Error() string
Error returns a string representation of the error.
type HTTPDispatch ¶ added in v1.8.0
type HTTPDispatch func( context.Context, *http.Request, *RawRequest, http.ResponseWriter, ) (matched bool, err error)
HTTPDispatch calls the generated typed adapter for request. matched is false when the service does not define the requested method.
type HTTPHandlerSpec ¶ added in v1.8.0
type HTTPHandlerSpec struct {
// Service is the designed service name.
Service string
// Decoder returns the decoder for one HTTP request.
Decoder func(*http.Request) loomhttp.Decoder
// Encoder returns the encoder for one JSON-RPC response.
Encoder func(context.Context, http.ResponseWriter) loomhttp.Encoder
// Dispatch calls the generated typed method adapter.
Dispatch HTTPDispatch
// HandleFailure receives transport failures that cannot become JSON-RPC
// responses.
HandleFailure func(context.Context, http.ResponseWriter, error)
}
HTTPHandlerSpec defines the service adapters used by the JSON-RPC HTTP protocol runtime.
type MixedHandlerSpec ¶ added in v1.8.0
type MixedHandlerSpec struct {
// HTTP defines the unary and batch HTTP runtime.
HTTP HTTPHandlerSpec
// SSE defines the SSE runtime.
SSE SSEHandlerSpec
// SupportsGET reports whether events/stream is designed.
SupportsGET bool
}
MixedHandlerSpec defines HTTP and SSE adapters for a service that negotiates both JSON-RPC transports on one route.
type RawErrorResponse ¶
type RawErrorResponse struct {
Code int `json:"code"`
Message string `json:"message"`
Data json.RawMessage `json:"data,omitempty"`
}
RawErrorResponse represents a JSON-RPC error response with marshalled data.
func (*RawErrorResponse) Error ¶
func (e *RawErrorResponse) Error() string
Error returns a string representation of the error.
type RawRequest ¶
type RawRequest struct {
JSONRPC string `json:"jsonrpc"`
Method string `json:"method"`
Params json.RawMessage `json:"params,omitempty"`
ID any `json:"id"`
// HasID is true when the "id" key is present in the incoming JSON (even if null).
// It is consumed by generated templates (WebSocket/SSE/HTTP) to decide whether
// to send a response for this request. Do not remove even if unused by this package.
HasID bool `json:"-"`
// Invalid is true when the JSON value is syntactically valid but not a
// valid JSON-RPC request envelope.
Invalid bool `json:"-"`
}
RawRequest represents a JSON-RPC request with a marshalled params.
func (*RawRequest) UnmarshalJSON ¶
func (r *RawRequest) UnmarshalJSON(data []byte) error
UnmarshalJSON decodes RawRequest and records whether the id field was present.
type RawResponse ¶
type RawResponse struct {
JSONRPC string `json:"jsonrpc"`
Result json.RawMessage `json:"result,omitempty"`
Error *RawErrorResponse `json:"error,omitempty"`
ID any `json:"id,omitempty"`
}
RawResponse represents a JSON-RPC response with a marshalled result and error.
type Request ¶
type Request struct {
JSONRPC string `json:"jsonrpc"`
Method string `json:"method"`
Params any `json:"params,omitempty"`
ID any `json:"id,omitempty"`
}
Request represents a JSON-RPC request.
func MakeNotification ¶
MakeNotification creates a notification.
type Response ¶
type Response struct {
JSONRPC string `json:"jsonrpc"`
Result any `json:"result,omitempty"`
Error *ErrorResponse `json:"error,omitempty"`
ID any `json:"id"`
}
Response represents a JSON-RPC response.
func MakeErrorResponse ¶
MakeErrorResponse creates an error response.
func MakeSuccessResponse ¶
MakeSuccessResponse creates a success response.
type ResponseContractCase ¶ added in v1.8.0
type ResponseContractCase struct {
// ID is stable while the service contract is unchanged.
ID string
// Kind identifies a success, service error, or notification.
Kind ResponseContractCaseKind
// ResultType is the designed success result type.
ResultType string
// HasResult reports whether the success envelope has a result member.
HasResult bool
// ErrorCode is the declared JSON-RPC error code.
ErrorCode int
// ErrorName is the declared service error name.
ErrorName string
// ErrorDataType is the designed JSON error-data type.
ErrorDataType string
// Stream describes a supported streaming terminal contract.
Stream *StreamingResponseContract
}
ResponseContractCase describes one generated JSON-RPC wire-response branch.
type ResponseContractCaseKind ¶ added in v1.8.0
type ResponseContractCaseKind string
ResponseContractCaseKind identifies a JSON-RPC response branch.
const ( // ResponseContractSuccess identifies a successful response. ResponseContractSuccess ResponseContractCaseKind = "success" // ResponseContractError identifies a service error. ResponseContractError ResponseContractCaseKind = "error" // ResponseContractNotification identifies response suppression for an ID-less request. ResponseContractNotification ResponseContractCaseKind = "notification" )
type ResponseContractEvent ¶ added in v1.8.0
type ResponseContractEvent struct {
// Type is the transport event type.
Type string
// Data is the JSON event payload.
Data json.RawMessage
}
ResponseContractEvent is one parsed streaming JSON-RPC event.
type ResponseContractObservation ¶ added in v1.8.0
type ResponseContractObservation struct {
// Response is the HTTP response for the JSON-RPC request or stream handshake.
Response *http.Response
// Events contains parsed server-SSE events in wire order.
Events []ResponseContractEvent
// TerminalError is the final server-SSE read error.
TerminalError error
}
ResponseContractObservation contains values observed from a generated handler.
type SSEDispatch ¶ added in v1.8.0
type SSEDispatch func( context.Context, *http.Request, *RawRequest, http.ResponseWriter, ) (matched bool, unary bool, err error)
SSEDispatch calls a generated typed SSE method adapter. unary reports whether an ID-less successful request must finish with HTTP 204.
type SSEErrorSender ¶ added in v1.8.0
type SSEErrorSender func( context.Context, *http.Request, http.ResponseWriter, any, Code, string, any, ) error
SSEErrorSender writes one JSON-RPC error as an SSE event.
type SSEHandlerSpec ¶ added in v1.8.0
type SSEHandlerSpec struct {
// Service is the designed service name.
Service string
// Decoder returns the decoder for one HTTP request.
Decoder func(*http.Request) loomhttp.Decoder
// Dispatch calls a generated typed SSE method adapter.
Dispatch SSEDispatch
// SendError writes one protocol error event.
SendError SSEErrorSender
// HandleFailure receives transport failures.
HandleFailure func(context.Context, http.ResponseWriter, error)
}
SSEHandlerSpec defines the generated adapters used by the JSON-RPC SSE protocol runtime.
type StreamConfig ¶
type StreamConfig struct {
// Timeouts
RequestTimeout time.Duration // Timeout for individual requests (default: 30s)
ConnectionTimeout time.Duration // Timeout for establishing connections (default: 10s)
CloseTimeout time.Duration // Timeout for graceful stream closure (default: 5s)
// Buffer Sizes
ResultChannelBuffer int // Buffer size for result channels (default: 1)
WriteBufferSize int // WebSocket write buffer size (default: 4096)
ReadBufferSize int // WebSocket read buffer size (default: 4096)
// Retry Configuration
MaxRetries int // Maximum number of connection retries (default: 3)
RetryBackoffBase time.Duration // Base delay for exponential backoff (default: 1s)
RetryBackoffMax time.Duration // Maximum retry delay (default: 30s)
// Advanced Options
EnableCompression bool // Enable WebSocket compression (default: false)
PingInterval time.Duration // Interval for sending ping frames (default: 30s)
// Error Handling
ErrorHandler StreamErrorHandler // Optional error handler for stream events (default: nil)
}
StreamConfig contains configuration options for WebSocket streams
func NewStreamConfig ¶
func NewStreamConfig(opts ...StreamConfigOption) *StreamConfig
NewStreamConfig creates a StreamConfig with the given options
func (*StreamConfig) Validate ¶
func (c *StreamConfig) Validate() *StreamConfig
Validate checks the configuration and applies constraints
type StreamConfigOption ¶
type StreamConfigOption func(*StreamConfig)
StreamConfigOption is a function that modifies StreamConfig
func WithCloseTimeout ¶
func WithCloseTimeout(timeout time.Duration) StreamConfigOption
WithCloseTimeout sets the timeout for graceful stream closure
func WithCompression ¶
func WithCompression(enabled bool) StreamConfigOption
WithCompression enables or disables WebSocket compression
func WithConnectionTimeout ¶
func WithConnectionTimeout(timeout time.Duration) StreamConfigOption
WithConnectionTimeout sets the timeout for establishing connections
func WithErrorHandler ¶
func WithErrorHandler(handler StreamErrorHandler) StreamConfigOption
WithErrorHandler sets the error handler for stream events
func WithPingInterval ¶
func WithPingInterval(interval time.Duration) StreamConfigOption
WithPingInterval sets the interval for sending ping frames
func WithRequestTimeout ¶
func WithRequestTimeout(timeout time.Duration) StreamConfigOption
WithRequestTimeout sets the timeout for individual requests
func WithResultChannelBuffer ¶
func WithResultChannelBuffer(size int) StreamConfigOption
WithResultChannelBuffer sets the buffer size for result channels
func WithRetryConfig ¶
func WithRetryConfig(maxRetries int, baseDelay, maxDelay time.Duration) StreamConfigOption
WithRetryConfig sets retry behavior parameters
func WithWebSocketBuffers ¶
func WithWebSocketBuffers(readSize, writeSize int) StreamConfigOption
WithWebSocketBuffers sets both read and write buffer sizes
type StreamErrorHandler ¶
type StreamErrorHandler func(ctx context.Context, errorType StreamErrorType, err error, response *RawResponse)
StreamErrorHandler allows users to handle stream errors
type StreamErrorType ¶
type StreamErrorType int
StreamErrorType represents different types of WebSocket stream errors
const ( StreamErrorConnection StreamErrorType = iota // WebSocket connection errors StreamErrorProtocol // Invalid JSON-RPC protocol StreamErrorParsing // Failed to parse/decode response StreamErrorOrphaned // Response with no matching request StreamErrorTimeout // Request timeout StreamErrorNotification // Server-initiated notification received )
type StreamingResponseContract ¶ added in v1.8.0
type StreamingResponseContract struct {
// Transport identifies the streaming wire protocol.
Transport string
// Terminal identifies the expected terminal behavior.
Terminal string
}
StreamingResponseContract describes a selected JSON-RPC stream terminal.
type WebSocketDispatch ¶ added in v1.8.0
type WebSocketDispatch func(context.Context, *RawRequest) error
WebSocketDispatch calls a generated typed WebSocket method adapter.
type WebSocketErrorSender ¶ added in v1.8.0
WebSocketErrorSender writes one JSON-RPC error frame.
type WebSocketHandlerSpec ¶ added in v1.8.0
type WebSocketHandlerSpec struct {
// Upgrader upgrades the HTTP connection.
Upgrader loomhttp.Upgrader
// Configure optionally configures the upgraded connection.
Configure loomhttp.ConnConfigureFunc
// WritePolicy bounds WebSocket writes.
WritePolicy loomhttp.StreamWritePolicy
// Run constructs and runs the generated typed service stream.
Run func(context.Context, context.CancelFunc, *http.Request, http.ResponseWriter, *loomhttp.WebSocketStream) error
// HandleFailure receives upgrade, stream, and close failures.
HandleFailure func(context.Context, http.ResponseWriter, error)
}
WebSocketHandlerSpec defines the generated adapters used to establish a JSON-RPC WebSocket service stream.
type WebSocketMethodMatcher ¶ added in v1.8.0
WebSocketMethodMatcher reports whether a generated WebSocket service defines a method.
Source Files
¶
Directories
¶
| Path | Synopsis |
|---|---|
|
Package codegen generates JSON-RPC 2.0 servers and clients from an evaluated Loom design.
|
Package codegen generates JSON-RPC 2.0 servers and clients from an evaluated Loom design. |