Skip to content

Commit 49a3c78

Browse files
feat: pass client headers like payload, gateway cookies manipulation
1 parent 9fb6851 commit 49a3c78

File tree

8 files changed

+102
-19
lines changed

8 files changed

+102
-19
lines changed

__tests__/services/abstract-microservice-test.ts

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -336,7 +336,13 @@ describe('services/abstract-microservice', () => {
336336
// Set correctly microservice url
337337
expect(url).to.equal(`${options.connection}/${ms.getChannelPrefix()}/${microservice}`);
338338
// correctly pass params to request
339-
expect(data.params).to.deep.equal(params);
339+
expect(data.params).to.deep.equal({
340+
...params,
341+
payload: {
342+
sender: 'tests',
343+
senderStack: ['tests'],
344+
},
345+
});
340346
// correctly generate request id
341347
expect(data.id).to.not.empty;
342348
});

__tests__/services/gateway-test.ts

Lines changed: 36 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,11 @@ describe('services/gateway', () => {
3838
* Create express response
3939
*/
4040
const createResponse = () =>
41-
({ json: sinon.stub() } as unknown as Response & { json: SinonStub });
41+
({
42+
json: sinon.stub(),
43+
cookie: sinon.stub(),
44+
clearCookie: sinon.stub(),
45+
} as unknown as Response & { json: SinonStub; cookie: SinonStub; clearCookie: SinonStub });
4246

4347
const msName = 'ms1';
4448
const msName2 = 'ms2';
@@ -301,6 +305,7 @@ describe('services/gateway', () => {
301305
expect(response.getResult()).to.deep.equal({ endpointTriggerMiddleware, middleware: 'after' });
302306
expect(data.method).to.equal(endpointTriggerMiddleware);
303307
expect(data.params.middleware).to.equal('before');
308+
expect(data.params.payload.headers.type).to.equal('async'); // check pass client headers through payload
304309
expect(headers.type).to.equal('async');
305310
});
306311

@@ -386,4 +391,34 @@ describe('services/gateway', () => {
386391
expect(response).to.undefined;
387392
expect(stubbed).to.calledOnce;
388393
});
394+
395+
it('should correctly manipulation with cookie', async () => {
396+
const req = createRequest({ method: 'cookies.test-cookies' });
397+
const res = createResponse();
398+
399+
const responseAxios = new MicroserviceResponse({
400+
result: {
401+
hello: 'world',
402+
payload: {
403+
cookies: [
404+
{ action: 'add', name: 'cookie1', value: 'test1', options: { httpOnly: true } },
405+
{ action: 'remove', name: 'cookie2' },
406+
],
407+
},
408+
},
409+
});
410+
const stubbed = sinon.stub(axios, 'request').resolves({ data: responseAxios.toJSON() });
411+
412+
await handleClientRequest(req, res);
413+
414+
stubbed.restore();
415+
416+
const addCookie = res.cookie.firstCall.args;
417+
const clearCookie = res.clearCookie.firstCall.args;
418+
const result = res.json.firstCall.firstArg;
419+
420+
expect(addCookie).to.deep.equal(['cookie1', 'test1', { httpOnly: true }]);
421+
expect(clearCookie).to.deep.equal(['cookie2']);
422+
expect(result.payload).to.undefined;
423+
});
389424
});

example/index.ts

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@ import Microservice from '@services/microservice';
44
// import { Gateway, Microservice } from '../lib';
55

66
/**
7+
* THIS IS MICROSERVICE: demo
8+
*
79
* 1. Create microservice with name 'demo'
810
* 2. add 'test' endpoint handler
911
*/
@@ -21,8 +23,19 @@ microservice.addEndpoint('test-exception', () => {
2123
},
2224
});
2325
});
26+
microservice.addEndpoint('test-with-cookies-manipulations', () => ({
27+
awesome: 'result',
28+
payload: {
29+
cookies: [
30+
{ action: 'add', name: 'cookie1', value: 'test1', options: { httpOnly: true } },
31+
{ action: 'remove', name: 'cookie2' },
32+
],
33+
},
34+
}));
2435

2536
/**
37+
* THIS IS MICROSERVICE: gateway
38+
*
2639
* 1. Create gateway (auto registration microservices enabled)
2740
*/
2841
const gateway = Gateway.create();

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@lomray/microservice-nodejs-lib",
3-
"version": "2.3.0",
3+
"version": "2.4.0",
44
"description": "Package for create microservice architecture based on NodeJS & inverted json.",
55
"main": "lib/index.js",
66
"types": "lib/index.d.ts",

src/interfaces/core/i-microservice-request.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ interface IMicroserviceRequestPayload {
55
sender?: string;
66
isInternal?: boolean;
77
senderStack?: string[];
8+
headers?: Record<string, any>;
89
}
910

1011
type PayloadExtends<TParams> = TParams & IMicroserviceRequestPayload;

src/interfaces/core/i-microservice-response.ts

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,17 @@
1+
import type { CookieOptions } from 'express-serve-static-core';
12
import BaseException from '@core/base-exception';
23

34
/**
45
* Microservices data
56
*/
6-
// eslint-disable-next-line @typescript-eslint/no-empty-interface
7-
interface IMicroserviceResponsePayload {}
7+
interface IMicroserviceResponsePayload {
8+
cookies?: {
9+
action: 'add' | 'remove';
10+
name: string;
11+
value?: string;
12+
options?: CookieOptions;
13+
}[];
14+
}
815

916
type PayloadExtends<TParams> = TParams & IMicroserviceResponsePayload;
1017

src/services/abstract-microservice.ts

Lines changed: 5 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -393,20 +393,16 @@ abstract class AbstractMicroservice {
393393
logPadding = ' ',
394394
reqParams = {},
395395
} = params;
396-
396+
const requestParams = { ...data };
397397
const sender = this.options.name;
398-
const senderStack = [...(data.payload?.senderStack ?? []), sender];
398+
399+
_.set(requestParams, 'payload.sender', sender);
400+
_.set(requestParams, 'payload.senderStack', [...(data.payload?.senderStack ?? []), sender]);
399401

400402
const request = new MicroserviceRequest({
401403
...(shouldGenerateId || reqId ? { id: reqId ?? uuidv4() } : {}),
402404
method: endpoint.join('.'),
403-
params: _.merge(data, {
404-
payload: {
405-
sender,
406-
senderStack,
407-
isInternal,
408-
},
409-
}),
405+
params: requestParams,
410406
});
411407

412408
this.logDriver(

src/services/gateway.ts

Lines changed: 30 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -234,6 +234,30 @@ class Gateway extends AbstractMicroservice {
234234
this.logDriver(() => `End batch request: ${body.length} (${id}).`, LogType.RES_EXTERNAL, id);
235235
}
236236

237+
// cookie manipulations
238+
(Array.isArray(response) ? response : [response]).forEach((msRes) => {
239+
const reqPayload = msRes?.getResult()?.payload;
240+
const cookies = reqPayload?.cookies;
241+
242+
if (Array.isArray(cookies)) {
243+
_.unset(reqPayload, 'cookies');
244+
245+
cookies.forEach((cookie) => {
246+
switch (cookie.action) {
247+
case 'add':
248+
res.cookie(cookie.name, cookie.value, cookie.options ?? {});
249+
break;
250+
case 'remove':
251+
res.clearCookie(cookie.name);
252+
}
253+
});
254+
255+
if (reqPayload && Object.keys(reqPayload).length === 0) {
256+
_.unset(msRes?.getResult(), 'payload');
257+
}
258+
}
259+
});
260+
237261
res.json(response);
238262
}
239263

@@ -264,11 +288,12 @@ class Gateway extends AbstractMicroservice {
264288
});
265289
}
266290

267-
const request = new MicroserviceRequest(
268-
_.merge(body, {
269-
params: { payload: { sender: 'client', senderStack: ['client'], isInternal: false } },
270-
}),
271-
);
291+
_.set(body, 'params.payload.sender', 'client');
292+
_.set(body, 'params.payload.senderStack', ['client']);
293+
_.set(body, 'params.payload.isInternal', false);
294+
_.set(body, 'params.payload.headers', headers);
295+
296+
const request = new MicroserviceRequest(body);
272297
const [microservice] = request.getMethod().split('.');
273298
const clientHandler = this.microservices[microservice];
274299

0 commit comments

Comments
 (0)