Skip to content

Commit

Permalink
Introduce custom extensions for JSON-RPC 2.0 Response
Browse files Browse the repository at this point in the history
  • Loading branch information
sergeyfast authored and dizzyfool committed Sep 13, 2019
1 parent 4b07723 commit 10f2c48
Show file tree
Hide file tree
Showing 2 changed files with 71 additions and 0 deletions.
67 changes: 67 additions & 0 deletions handlers_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ package zenrpc_test

import (
"bytes"
"context"
"encoding/json"
"io/ioutil"
"log"
"net/http"
Expand Down Expand Up @@ -309,6 +311,71 @@ func TestServer_ServeHTTPWithErrors(t *testing.T) {
}
}

func TestServer_Extensions(t *testing.T) {
middleware := func(h zenrpc.InvokeFunc) zenrpc.InvokeFunc {
return func(ctx context.Context, method string, params json.RawMessage) zenrpc.Response {
r := h(ctx, method, params)

// ignore multiply method
if method != testdata.RPC.ArithService.Multiply {
r.Extensions = map[string]interface{}{"debug": "true"}
}

return r
}
}

server := zenrpc.NewServer(zenrpc.Options{AllowCORS: true, HideErrorDataField: true})
server.Register("arith", &testdata.ArithService{})
server.Use(middleware)

ts := httptest.NewServer(http.HandlerFunc(server.ServeHTTP))
defer ts.Close()

var tc = []struct {
url string
in, out string
}{
{
url: ts.URL,
in: `{"jsonrpc": "2.0", "method": "multiple1", "id": 1 }`,
out: `{"jsonrpc":"2.0","id":1,"error":{"code":-32601,"message":"Method not found"}}`},
{
url: ts.URL,
in: `{"jsonrpc": "2.0", "method": "arith.divide", "params": { "a": 1, "b": 24 }}`,
out: ``},
{
url: ts.URL,
in: `{"jsonrpc": "2.0", "method": "arith.divide", "params": { "a": 1, "b": 24 }, "id": 1 }`,
out: `{"jsonrpc":"2.0","id":1,"result":{"Quo":0,"rem":1},"extensions":{"debug":"true"}}`},
{
url: ts.URL,
in: `{"jsonrpc": "2.0", "method": "arith.multiply", "params": { "a": 1, "b": 24 }, "id": 1 }`,
out: `{"jsonrpc":"2.0","id":1,"result":24}`},
{
url: ts.URL,
in: `{"jsonrpc": "2.0", "method": "arith.checkerror", "params": [ true ], "id": 1 }`,
out: `{"jsonrpc":"2.0","id":1,"error":{"code":-32603,"message":"test"},"extensions":{"debug":"true"}}`},
}

for _, c := range tc {
res, err := http.Post(c.url, "application/json", bytes.NewBufferString(c.in))
if err != nil {
log.Fatal(err)
}

resp, err := ioutil.ReadAll(res.Body)
res.Body.Close()
if err != nil {
log.Fatal(err)
}

if string(resp) != c.out {
t.Errorf("Input: %s\n got %s expected %s", c.in, resp, c.out)
}
}
}

func TestServer_ServeWS(t *testing.T) {
ts := httptest.NewServer(http.HandlerFunc(rpc.ServeWS))
defer ts.Close()
Expand Down
4 changes: 4 additions & 0 deletions jsonrpc2.go
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,9 @@ type Response struct {
// This member MUST NOT exist if there was no error triggered during invocation.
// The value for this member MUST be an Object as defined in section 5.1.
Error *Error `json:"error,omitempty"`

// Extensions is additional field for extending standard response. It could be useful for tracing, method execution, etc...
Extensions map[string]interface{} `json:"extensions,omitempty"`
}

// JSON is temporary method that silences error during json marshalling.
Expand All @@ -120,6 +123,7 @@ type Error struct {
// The value of this member is defined by the Server (e.g. detailed error information, nested errors etc.).
Data interface{} `json:"data,omitempty"`

// Err is inner error.
Err error `json:"-"`
}

Expand Down

0 comments on commit 10f2c48

Please sign in to comment.