This is an implementation of the JSON-RPC protocol.
Example:
import jaysonrpc import std/sugar # for collect: var rpc = initExecutor[JsonNode, void]() rpc.on("hello") do (x: string) -> string: return x # Data then needs to come in as a string let rawJson = $ %* {"jsonrpc": "2.0", "method": "hello", "params": ["world"], "id": 1} # You get a series of calls from the json let calls = rpc.getCalls(rawJson) assert calls.len == 1 # This is not a batch call, so we have one call # These functions can be called however you want, they are thread safe and handle everything themselves let responses = collect: for call in calls: call() # Once you collect them back, you can send back a response echo calls.dump(responses)
Types
ConstructedCall[R] = object
- Call that has parameters applied, can then be called without needing the original request. If this returns none then a response shouldn't be sent Source Edit
Error = object code*: RPCErrorCode ## Code relating to the error message*: string ## Message providing a human description of the message data*: JsonNode ## Extra metadata to store about the message
- Error object. Can store extra metadata in data that is understood by the handler Source Edit
Executor[R; C] = object
- Executor stores all the functions, this can then be queried later to get the function to then pass to your favourite executor Source Edit
ID {..} = object of CaseObject[IDTag_553648149] case kind*: IDTag_553648149 of Numeric: numeric*: tuple[Numeric: int] of String: string*: tuple[String: string] of Null: null*: tuple[]
- Source Edit
IDTag_553648149 = enum Numeric, String, Null
- Source Edit
MethodDef[A; R] = object name*: string ## Name of the method getting called
-
This is a definition of a method. Used to enforce a spec or for calling a pre-defined method. This has the benefit of being able to share defintions between server and client.
- A tuple representing the args to send
Request = object jsonrpc* = "2.0" ## Version, only 2.0 is implemented id*: Option[ID] ## ID of the request. If missing then its a notification meth*: string ## Method getting called params*: SentParameters
- A request sent to the server Source Edit
Response = object id*: ID ## A response always has an ID since notifications have nothing sent result*: RPCResult ## Either the result of the call or any error that occured
- Response sent back to the caller. Is possible that it contains an error Source Edit
RPCError = object of CatchableError code*: RPCErrorCode ## Corresponding error code defined in the spec id*: Option[ID] ## Request that the failure occured in. ## "If there was an error in detecting the id in the Request object (e.g. Parse error/Invalid Request), it MUST be Null."
- Exception to throw about an error Source Edit
RPCErrorCode = distinct int
- Error codes for JSONRPC. Stored as distinct int instead of enum so that it can be extended Source Edit
TypedRequest[R] = distinct Request
- Request but has type info associated on what the expected return type is. Used when sending a call to a remote server Source Edit
Consts
InvalidParams = -32602
- Parameters passed were invalid Source Edit
InvalidRequest = -32600
- Request object was invalid Source Edit
MethodNotFound = -32601
- Executor couldn't find the method Source Edit
ParseError = -32700
- Error when trying to parse incoming JSON Source Edit
ServerError = -32603
- Error from internal handler Source Edit
Procs
proc `$`(code: RPCErrorCode): string {.borrow, ...raises: [], tags: [], forbids: [].}
- Source Edit
proc `%`(code: RPCErrorCode): JsonNode {.borrow, ...raises: [], tags: [], forbids: [].}
- Source Edit
func `()`[R](call: ConstructedCall[R]): Option[R]
- Helper function that calls the internal proc Source Edit
func `==`(a, b: RPCErrorCode): bool {.borrow, ...raises: [], tags: [], forbids: [].}
- Source Edit
proc call[A, R](def: MethodDef[A, R]; args: A): TypedRequest[R] {.inline.}
- Returns the proc for calling a method Source Edit
func call[R](call: ConstructedCall[R]): ConstructedCallProc[R]
- Returns the proc that you call to get the response Source Edit
func checkedGet[T](data: JsonNode; key: string; into: typedesc[T]): T
- Performs a checked get to access key from data and converts into T Source Edit
func fromJsonHook(id: out ID; data: JsonNode) {....raises: [RPCError], tags: [], forbids: [].}
- Hook for parsing an ID Source Edit
func fromJsonHook(params: out SentParameters; data: JsonNode) {. ...raises: [ValueError], tags: [], forbids: [].}
- Source Edit
func fromJsonHook(request: out Request; data: JsonNode) {. ...raises: [RPCError, KeyError, Exception, ValueError], tags: [RootEffect], forbids: [].}
- Hook for parsing the JSON Source Edit
func fromJsonHook(response: out Response; data: JsonNode) {. ...raises: [RPCError, KeyError, ValueError, JsonKindError], tags: [RootEffect], forbids: [].}
- Source Edit
func id=[R](request: var TypedRequest[R]; id: int | string)
- Sets the ID for a request Source Edit
func initExecutor[R, C](): Executor[R, C]
- Source Edit
func inProgress(exec: Executor): int
- Returns the number of requests that are registered to be executed Source Edit
func isCancelled(ctx: Context): bool
- Checks if the current request has been cancelled. Source Edit
func isCancelled(ctx: Context; requestId: ID): bool
- Source Edit
func isNotification(x: Request): bool {....raises: [], tags: [], forbids: [].}
- Checks if a request is a notification Source Edit
func name(call: ConstructedCall): string
- Returns the method that a constructed call handles Source Edit
func toJsonHook(id: sink ID): JsonNode {....raises: [], tags: [], forbids: [].}
- Converts an ID to JSON Source Edit
func toJsonHook(parameters: SentParameters): JsonNode {....raises: [], tags: [], forbids: [].}
- Source Edit
func toJsonHook(request: sink Request): JsonNode {....raises: [], tags: [], forbids: [].}
- Source Edit
func toJsonHook(response: sink Response): JsonNode {....raises: [KeyError], tags: [], forbids: [].}
- Source Edit
Iterators
iterator items[R](calls: RPCCalls[R]): ConstructedCall[R]
- Source Edit