From 3b88d967f58c7495cee58fd12ede8052c2a9b705 Mon Sep 17 00:00:00 2001 From: Julien Martin Date: Fri, 13 Mar 2020 16:33:55 +0100 Subject: [PATCH 1/2] Passthrough route mecanism added --- services/nodegate.js | 14 +++++++-- test/services/nodegate.test.js | 56 ++++++++++++++++++++++++++++++++++ 2 files changed, 68 insertions(+), 2 deletions(-) diff --git a/services/nodegate.js b/services/nodegate.js index eb7ccf9..af3e1c9 100644 --- a/services/nodegate.js +++ b/services/nodegate.js @@ -8,6 +8,7 @@ const bodyParser = require('body-parser'); const cors = require('cors'); const express = require('express'); +const request = require('request'); const { execute } = require('../entities/route'); const { getConfiguration } = require('../services/configuration'); @@ -44,12 +45,21 @@ const nodegate = () => { expressApp.handle(req, res, next); }; - // TODO: app.passthrough = (route) => {}; - app.beforeEach = (workers) => { toArray(workers).forEach((worker) => beforeEach.push(worker)); }; + app.passthrough = (routes) => { + toArray(routes).forEach((route) => { + expressApp[route.method.toLowerCase()](route.path, (req, res) => { + request[route.method.toLowerCase()](route.target, { + ...(req.headers && { headers: req.headers }), + ...(req.body && { form: req.body }), + }).pipe(res); + }); + }); + }; + app.route = (routes) => { toArray(routes).forEach((route) => { expressApp[route.method.toLowerCase()]( diff --git a/test/services/nodegate.test.js b/test/services/nodegate.test.js index fd2e86a..e0b6c24 100644 --- a/test/services/nodegate.test.js +++ b/test/services/nodegate.test.js @@ -1,3 +1,4 @@ +const nock = require('nock'); const request = require('supertest'); const WorkflowError = require('../../entities/WorkflowError'); const nodegate = require('../../services/nodegate'); @@ -83,6 +84,61 @@ describe('services/nodegate', () => { }); }); }); + describe('#passthrough', () => { + it('should call the target URL with the right verb', async () => { + nock('http://service.com').get('/').reply(200); + const gate = nodegate(); + gate.passthrough({ + method: 'get', + path: '/service', + target: 'http://service.com', + }); + await request(gate).get('/service').expect(200); + }); + it('should call the target URL with the headers', async () => { + nock('http://service.com', { + reqheaders: { + authorization: 'shu:drum', + }, + }).get('/').reply(200); + const gate = nodegate(); + gate.passthrough({ + method: 'get', + path: '/service', + target: 'http://service.com', + }); + await request(gate) + .get('/service') + .set('authorization', 'shu:drum') + .expect(200); + }); + it('should call the target URL with the body', async () => { + nock('http://service.com').get('/', { username: 'shudrum' }).reply(200); + const gate = nodegate(); + gate.passthrough({ + method: 'get', + path: '/service', + target: 'http://service.com', + }); + await request(gate) + .get('/service') + .send({ username: 'shudrum' }) + .expect(200); + }); + it('should return the raw body', async () => { + nock('http://service.com').get('/').reply(200, 'Multiline\nContent'); + const gate = nodegate(); + gate.passthrough({ + method: 'get', + path: '/service', + target: 'http://service.com', + }); + const { text } = await request(gate) + .get('/service') + .expect(200); + expect(text).toEqual('Multiline\nContent'); + }); + }); describe('HTTP status codes', () => { it('should respond a 500 error in case of error', async () => { const gate = nodegate(); From 097f4b4fd7937feedbcefbbd1d7fc1f74ba6cbf3 Mon Sep 17 00:00:00 2001 From: Julien Martin Date: Fri, 13 Mar 2020 16:34:37 +0100 Subject: [PATCH 2/2] Version 1.5.0 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 801becc..affc3bf 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "nodegate", "description": "API gateway made simple, fast and easy to configure.", - "version": "1.4.0", + "version": "1.5.0", "author": "Julien Martin ", "license": "MIT", "scripts": {