Update documentation

This commit is contained in:
coffeepots 2018-06-04 15:17:26 +01:00
parent a4dbb5ece4
commit 622dcc8e5c
1 changed files with 105 additions and 12 deletions

117
README.md
View File

@ -1,9 +1,9 @@
**Nim-eth-rpc**
**Json-rpc**
[![Build Status (Travis)](https://img.shields.io/travis/status-im/nim-eth-rpc/master.svg?label=Linux%20/%20macOS "Linux/macOS build status (Travis)")](https://travis-ci.org/status-im/nim-eth-rpc)
[![Windows build status (Appveyor)](https://img.shields.io/appveyor/ci/jarradh/nim-eth-rpc/master.svg?label=Windows "Windows build status (Appveyor)")](https://ci.appveyor.com/project/jarradh/nim-eth-rpc)
Nim-eth-rpc is designed to provide remote procedure calls to the Nimbus Ethereum research project.
Json-Rpc is designed to provide an easier interface for working with remote procedure calls.
# Installation
@ -18,34 +18,127 @@ Nim-eth-rpc is designed to provide remote procedure calls to the Nimbus Ethereum
## Server
```nim
import rpcserver, asyncdispatch
Remote procedure calls are created using the `rpc` macro.
This macro allows you to provide a list of native Nim type parameters and a return type, and will automatically handle all the marshalling to and from json for you, so you can concentrate on using native Nim types for your call.
when isMainModule:
var srv = newRpcServer("")
asyncCheck srv.serve()
runForever()
Here's a full example of a server with a single RPC.
```nim
import rpcserver
var srv = newRpcServer("")
# Create an RPC with a string an array parameter, that returns an int
srv.rpc("myProc") do(input: int, data: array[0..3, int]) -> string:
result = "Hello " & $input & " data: " & $data
asyncCheck srv.serve()
runForever()
```
Parameter types are recursively traversed so you can use any custom types you wish, even nested types. Ref and object types are fully supported.
```nim
type
Details = ref object
values: seq[byte]
Payload = object
x, y: float
count: int
details: Details
ResultData = object
data: array[10, byte]
srv.rpc("getResults") do(payload: Payload) -> ResultData:
# Here we can use Payload as expected, and `result` will be of type ResultData.
# Parameters and results are automatically converted to and from json
# and the call is intrinsically asynchronous.
```
Behind the scenes, all RPC calls take a single json parameter that must be defined as a `JArray`.
At runtime, the json is checked to ensure that it contains the correct number and type of your parameters to match the `rpc` definition.
The `rpc` macro takes care of the boiler plate in marshalling to and from json.
Compiling with `-d:nimDumpRpcs` will show the output code for the RPC call.
The following RPC:
```nim
srv.rpc("myProc") do(input: string, data: array[0..3, int]):
result = %("Hello " & input & " data: " & $data)
```
Will get transformed into something like this:
```nim
proc myProc*(params: JsonNode): Future[JsonNode] {.async.} =
params.kind.expect(JArray, "params")
if params.len != 2:
raise newException(ValueError, "Expected 2 Json parameter(s) but got " &
$params.len)
var input: string
input = unpackArg(params.elems[0], "input", type(string))
var data: array[0 .. 3, int]
data = unpackArg(params.elems[1], "data", type(array[0 .. 3, int]))
result = %("Hello " & input & " data: " & $data)
```
## Client
Below is the most basic way to use a remote call on the client.
Here we manually supply the name and json parameters for the call.
```nim
import rpcclient, asyncdispatch, json
proc main {.async.} =
proc main =
var client = newRpcClient()
await client.connect("localhost", Port(8545))
let response = waitFor client.web3_clientVersion(newJNull())
let response = waitFor client.call("myRpc", %[])
# the call returns a `Response` type which contains the result
echo response.result.pretty
waitFor main()
```
To make things more readable and allow better checking client side, Json-Rpc supports generating wrappers for client RPCs using `createRpcSigs`.
This macro takes the path of a file containing forward declarations of procedures that you wish to convert to client RPCs.
Because the signatures are parsed at compile time, the file will be error checked and you can use import to share common types between your client and server.
For example, to support this remote call:
```nim
server.rpc("bmi") do(height, weight: float) -> float:
result = (height * height) / weight
```
You can have the following in your rpc signature file:
```nim
proc bmi(height, weight: float): float
```
When parsed through `createRpcSigs`, you can call the RPC as if it were a normal procedure.
So instead of this:
```nim
let bmiIndex = await client.call("bmi", %[%120.5, %12.0])
```
You can use:
```nim
let bmiIndex = await client.bmi(120.5, 12.0)
```
# Contributing
Pull requests are welcome. For major changes, please open an issue first to discuss what you would like to change.
Please make sure to update tests as appropriate.
# License
[MIT](https://choosealicense.com/licenses/mit/)
[MIT](https://choosealicense.com/licenses/mit/)