Skip to content

Commit

Permalink
feat: rpc discover
Browse files Browse the repository at this point in the history
  • Loading branch information
BelfordZ committed Jun 25, 2019
1 parent fbe0e57 commit 26506bf
Show file tree
Hide file tree
Showing 5 changed files with 71 additions and 38 deletions.
50 changes: 25 additions & 25 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@
"license": "Apache-2.0",
"dependencies": {
"@open-rpc/meta-schema": "^1.4.3",
"@open-rpc/schema-utils-js": "^1.7.0",
"@open-rpc/schema-utils-js": "^1.11.0",
"body-parser": "^1.18.3",
"commander": "^2.19.0",
"connect": "^3.6.6",
Expand Down
22 changes: 20 additions & 2 deletions src/router.test.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { Router, IMethodMapping } from "./router";
import examples from "@open-rpc/examples";
import _ from "lodash";
import { parseOpenRPCDocument } from "@open-rpc/schema-utils-js";
import { parseOpenRPCDocument, MethodNotFoundError } from "@open-rpc/schema-utils-js";
import {
OpenRPC,
ContentDescriptorObject,
Expand Down Expand Up @@ -56,6 +56,24 @@ describe("router", () => {
expect(result).toBe(4);
});

it("returns not found error when using incorrect method", async () => {
const router = new Router(parsedExample, makeMethodMapping(parsedExample.methods));
const result = await router.call("foobar", [2, 2]);
expect(result.error.code).toBe(-32601);
});

it("returns param validation error when passing incorrect params", async () => {
const router = new Router(parsedExample, makeMethodMapping(parsedExample.methods));
const result = await router.call("addition", ["123", "321"]);
expect(result.error.code).toBe(-32602);
});

it("implements service discovery", async () => {
const router = new Router(parsedExample, makeMethodMapping(parsedExample.methods));
const result = await router.call("rpc.discover", []);
expect(result).toEqual(parsedExample);
});

it("Simple math call validates params", async () => {
const router = new Router(parsedExample, makeMethodMapping(parsedExample.methods));
expect(await router.call("addition", ["2", 2])).toEqual({
Expand All @@ -75,7 +93,7 @@ describe("router", () => {

it("works in mock mode with unknown params", async () => {
const router = new Router(parsedExample, { mockMode: true });
const result = await router.call("addition", [6, 2]);
const result = await router.call("addition", [6, 2]);
expect(typeof result).toBe("number");
});
}
Expand Down
33 changes: 24 additions & 9 deletions src/router.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import {
ContentDescriptorObject,
OpenRPC,
} from "@open-rpc/meta-schema";
import { MethodCallValidator } from "@open-rpc/schema-utils-js";
import { MethodCallValidator, MethodNotFoundError, ParameterValidationError } from "@open-rpc/schema-utils-js";
const jsf = require("json-schema-faker"); // tslint:disable-line

export interface IMethodMapping {
Expand All @@ -20,6 +20,7 @@ export interface IMockModeSettings {
export type TMethodHandler = (...args: any) => Promise<any>;

export class Router {

public static methodNotFoundHandler(methodName: string) {
return {
error: {
Expand All @@ -29,7 +30,6 @@ export class Router {
},
};
}

private methods: IMethodMapping;
private methodCallValidator: MethodCallValidator;

Expand All @@ -42,21 +42,22 @@ export class Router {
} else {
this.methods = methodMapping as IMethodMapping;
}
this.methods["rpc.discover"] = this.serviceDiscoveryHandler.bind(this);

this.methodCallValidator = new MethodCallValidator(this.openrpcDocument);
}

public async call(methodName: string, params: any[]) {
const validationErrors = this.methodCallValidator.validate(methodName, params);

if (validationErrors instanceof MethodNotFoundError) {
return Router.methodNotFoundHandler(methodName);
}

if (validationErrors.length > 0) {
return {
error: {
code: -32602,
data: validationErrors,
message: "Invalid params",
},
};
return this.invalidParamsHandler(validationErrors);
}

try {
return await this.methods[methodName](...params);
} catch (e) {
Expand All @@ -68,6 +69,10 @@ export class Router {
return this.methods[methodName] !== undefined;
}

private serviceDiscoveryHandler(): Promise<OpenRPC> {
return Promise.resolve(this.openrpcDocument);
}

private buildMockMethodMapping(methods: MethodObject[]): IMethodMapping {
return _.chain(methods)
.keyBy("name")
Expand All @@ -87,4 +92,14 @@ export class Router {
.value();
}

private invalidParamsHandler(errs: ParameterValidationError[]) {
return {
error: {
code: -32602,
data: errs,
message: "Invalid params",
},
};
}

}
2 changes: 1 addition & 1 deletion src/transports/server-transport.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ export default abstract class ServerTransport {
protected async routerHandler(id: string | number, methodName: string, params: any[]) {
if (this.routers.length === 0) {
console.warn("transport method called without a router configured."); // tslint:disable-line
return Router.methodNotFoundHandler(methodName);
return new Error("No router configured");
}

const routerForMethod = _.find(
Expand Down

0 comments on commit 26506bf

Please sign in to comment.