Elm JSON-RPC
A JSON-RPC 2.0 library for Elm. You can use it to send JSON-RPC requests over HTTP.
Creating requests
A request with no parameters:
import Json.Decode as JD
import JsonRpc
currentTime : JsonRpc.Request String
currentTime =
{ method = "currentTime"
, params = JsonRpc.noParams
, result = JD.string
}
A request with positional parameters:
import Json.Encode as JE
add : Int -> Int -> JsonRpc.Request Int
add a b =
{ method = "add"
, params =
JsonRpc.positionalParams
[ JE.int a
, JE.int b
]
, result = JD.int
}
A request with named parameters:
subtract : Float -> Float -> JsonRpc.Request Float
subtract minuend subtrahend =
{ method = "subtract"
, params =
JsonRpc.namedParams
[ ( "minuend", JE.float minuend )
, ( "subtrahend", JE.float subtrahend )
]
-- No optional parameters
[]
, result = JD.float
}
intToString : Int -> Maybe Int -> JsonRpc.Request String
intToString n maybeBase =
{ method = "intToString"
, params =
JsonRpc.namedParams
[ ( "n", JE.float minuend )
]
-- 1 optional parameter
--
-- If maybeBase is Nothing then
-- the named parameter "base"
-- isn't sent over the wire
[ ( "base", Maybe.map JE.int maybeBase )
]
, result = JD.string
}
Sending requests
Basics
rpcUrl = "https://json-rpc.example.com"
type Msg
= GotCurrentTime (Result JsonRpc.Error String)
JsonRpc.send rpcUrl GotCurrentTime currentTime
This will send the JSON-RPC request:
{
"jsonrpc": "2.0",
"method": "currentTime",
"params": [],
"id": 1
}
over HTTP to the endpoint https://json-rpc.example.com
.
Changing the request identifier
To change the request identifier use sendWithId
.
Use an integer identifier:
JsonRpc.sendWithId
rpcUrl
GotCurrentTime
(JsonRpc.intId 2)
currentTime
The corresponding JSON-RPC request will be:
{
"jsonrpc": "2.0",
"method": "currentTime",
"params": [],
"id": 2
}
Use a string identifier:
JsonRpc.sendWithId
rpcUrl
GotCurrentTime
(JsonRpc.stringId "abc123")
currentTime
The corresponding JSON-RPC request will be:
{
"jsonrpc": "2.0",
"method": "currentTime",
"params": [],
"id": "abc123"
}
Want to change the HTTP settings?
Take a look at sendCustom
.
Handling errors
A JSON-RPC request can fail in many ways. Suppose the currentTime
RPC call
fails then in our update function we can handle it as follows:
import JsonRpc
GotCurrentTime (Err error) ->
case error of
JsonRpc.HttpError httpError ->
-- There was an error trying to
-- reach the server.
...
JsonRpc.UnexpectedStatus metadata body ->
-- A successful HTTP status code
-- other than 200 was returned.
...
JsonRpc.DecodeError jsonDecodeError ->
-- The Response object returned
-- by the server was malformed.
...
JsonRpc.MismatchedIds { requestId, responseId } ->
-- The id of the Request object
-- is not the same as the id of
-- the Response object.
...
JsonRpc.JsonRpcError { kind, code, message, maybeData, responseId } ->
-- The RPC call encountered an error.
-- The maybeData field may contain
-- detailed error information as
-- defined by the server.
...
Examples
The examples
directory contains:
- An Ethereum
example based on
eth_chainId
andeth_getBalance
. - A RandomOrg example based on
generateIntegers
.
To play with the examples do the following:
$ nix-shell
$ serve-examples
Then, open http://localhost:8000 in your browser and explore!