From e2f6c5f7980b388b6f28e655db1711ef7a2c4f84 Mon Sep 17 00:00:00 2001 From: Jerko Steiner Date: Sun, 4 Aug 2019 14:07:25 +0700 Subject: [PATCH] Encode JSON-RPC GET request params as JSON --- packages/jsonrpc/src/express.ts | 12 +++-- packages/jsonrpc/src/jsonrpc.ts | 84 +++++++++++++++-------------- packages/jsonrpc/src/remote.test.ts | 12 +++-- packages/jsonrpc/src/remote.ts | 4 +- 4 files changed, 64 insertions(+), 48 deletions(-) diff --git a/packages/jsonrpc/src/express.ts b/packages/jsonrpc/src/express.ts index a89b2e3..863eb99 100644 --- a/packages/jsonrpc/src/express.ts +++ b/packages/jsonrpc/src/express.ts @@ -50,7 +50,7 @@ export function jsonrpc( service: T, methods: F[], ) { - const callRpcService = createRpcService(service, methods) + const rpcService = createRpcService(service, methods) const router = Router() @@ -76,13 +76,19 @@ export function jsonrpc( }) throw err } - callRpcService(req.query, getContext(req)) + const request = { + id: req.query.id, + jsonrpc: req.query.jsonrpc, + method: req.query.method, + params: JSON.parse(req.query.params), + } + rpcService.invoke(request, getContext(req)) .then(response => handleResponse(response, res)) .catch(next) }) router.post('/', (req, res, next) => { - callRpcService(req.body, getContext(req)) + rpcService.invoke(req.body, getContext(req)) .then(response => handleResponse(response, res)) .catch(next) }) diff --git a/packages/jsonrpc/src/jsonrpc.ts b/packages/jsonrpc/src/jsonrpc.ts index f2ee8c8..46eeb11 100644 --- a/packages/jsonrpc/src/jsonrpc.ts +++ b/packages/jsonrpc/src/jsonrpc.ts @@ -69,51 +69,57 @@ export function createSuccessResponse(id: number | string, result: T) } } -export const createRpcService = - >( - service: T, - methods: M[], - ) => async (req: IRequest>, context: Context) - : Promise> | null> => { - const {id, method, params} = req +export const createRpcService = >( + service: T, + methods: M[], +) => { + return { + async invoke( + req: IRequest>, + context: Context, + ): Promise> | null> { + const {id, method, params} = req - if ( - req.jsonrpc !== '2.0' || - typeof method !== 'string' || - !Array.isArray(params) - ) { - throw createError(ERROR_INVALID_REQUEST, { - id, - data: null, - statusCode: 400, - }) - } + if ( + req.jsonrpc !== '2.0' || + typeof method !== 'string' || + !Array.isArray(params) + ) { + console.log(req.jsonrpc, method, params) + throw createError(ERROR_INVALID_REQUEST, { + id, + data: null, + statusCode: 400, + }) + } - const isNotification = req.id === null || req.id === undefined + const isNotification = req.id === null || req.id === undefined - const rpcService = pick(service, methods) + const rpcService = pick(service, methods) - if ( - !rpcService.hasOwnProperty(method) || - typeof rpcService[method] !== 'function' - ) { - throw createError(ERROR_METHOD_NOT_FOUND, { - id, - data: null, - statusCode: 404, - }) - } + if ( + !rpcService.hasOwnProperty(method) || + typeof rpcService[method] !== 'function' + ) { + throw createError(ERROR_METHOD_NOT_FOUND, { + id, + data: null, + statusCode: 404, + }) + } - let retValue = (rpcService[method] as any)(...params) + let retValue = (rpcService[method] as any)(...params) - if (typeof retValue === 'function') { - retValue = retValue(context) - } + if (typeof retValue === 'function') { + retValue = retValue(context) + } - if (!isPromise(retValue) && isNotification) { - return null - } + if (!isPromise(retValue) && isNotification) { + return null + } - retValue = await retValue - return createSuccessResponse(req.id as any, retValue) + retValue = await retValue + return createSuccessResponse(req.id as any, retValue) + }, } +} diff --git a/packages/jsonrpc/src/remote.test.ts b/packages/jsonrpc/src/remote.test.ts index dfd3d3f..acf7f1b 100644 --- a/packages/jsonrpc/src/remote.test.ts +++ b/packages/jsonrpc/src/remote.test.ts @@ -15,7 +15,8 @@ describe('remote', () => { interface IService { add(a: number, b: number): number - fetchItem(id: number): Promise + fetchItem(obj1: {a: number}, obj2: {b: number}) + : Promise<{a: number, b: number}> } const IServiceKeys = keys() @@ -23,8 +24,9 @@ describe('remote', () => { add(a: number, b: number) { return a + b } - async fetchItem(id: number): Promise { - return Promise.resolve('id:' + id) + async fetchItem(obj1: {a: number}, obj2: {b: number}) + : Promise<{a: number, b: number}> { + return Promise.resolve({...obj1, ...obj2}) } } @@ -60,8 +62,8 @@ describe('remote', () => { it('creates a proxy for remote service', async () => { const rpc = createRemoteClient( baseUrl, '/myService', IServiceKeys) - const result = await rpc.fetchItem(5) - expect(result).toBe('id:5') + const result = await rpc.fetchItem({a: 10}, {b: 20}) + expect(result).toEqual({a: 10, b: 20}) }) }) diff --git a/packages/jsonrpc/src/remote.ts b/packages/jsonrpc/src/remote.ts index 5dec6a3..62a58b0 100644 --- a/packages/jsonrpc/src/remote.ts +++ b/packages/jsonrpc/src/remote.ts @@ -33,7 +33,9 @@ export function createRemoteClient( id, jsonrpc: '2.0', method, - params, + params: reqMethod === 'post' + ? params + : JSON.stringify(params), }, }) if (response.data.error) {