Skip to content

Commit

Permalink
rework to prevent major changeset
Browse files Browse the repository at this point in the history
  • Loading branch information
Nigui committed Oct 9, 2023
1 parent 56f9cb9 commit 58e99f1
Show file tree
Hide file tree
Showing 5 changed files with 30 additions and 13 deletions.
2 changes: 1 addition & 1 deletion .changeset/brave-birds-report.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
---
'@talend/http': major
'@talend/http': minor
---

feat(TDP-12106): improve interceptors to return a promise, have access to request and a business context from caller
6 changes: 3 additions & 3 deletions packages/http/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ You can add global response interceptors to catch or modify responses before res
import { addHttpResponseInterceptor, http, HTTP_METHODS } from '@talend/http';
import type { TalendRequest } from '@talend/http';

addHttpResponseInterceptor('my-interceptor', async (request: TalendRequest, response: Response) => {
addHttpResponseInterceptor('my-interceptor', async (response: Response, request: TalendRequest) => {
if (request.method === HTTP_METHODS.GET) {
// your custom logic here
}
Expand All @@ -65,7 +65,7 @@ addHttpResponseInterceptor('my-interceptor', async (request: TalendRequest, resp
});
```

You can add multiple interceptors. Each will be called in the order of registration and will receive the same request parameter, but response parameter will be the one returned by previous interceptor.
You can add multiple interceptors. Each will be called in the order of registration and will receive the same request parameter, but response parameter will be the one returned by previous interceptor. If interceptor returns void, then it'll return received response.

Once your interceptor is not needed anymore, you can unregister it with `removeHttpResponseInterceptor` function of `@talend/http` package.

Expand All @@ -76,7 +76,7 @@ import { addHttpResponseInterceptor, http, HTTP_METHODS } from '@talend/http';

http.get('/api/v1/data', { context: { intercept: true } });

addHttpResponseInterceptor('my-interceptor', async (request: TalendRequest, response: Response) => {
addHttpResponseInterceptor('my-interceptor', async (response: Response, request: TalendRequest) => {
const { context } = request;
if (request.method === HTTP_METHODS.GET && context.intercept) {
// your custom logic here
Expand Down
24 changes: 20 additions & 4 deletions packages/http/src/config.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -109,10 +109,10 @@ describe('Configuration service', () => {

const interceptor1 = jest
.fn()
.mockImplementation((_, resp) => Promise.resolve({ ...resp, body: [...resp.body, 4] }));
.mockImplementation((resp, _) => Promise.resolve({ ...resp, body: [...resp.body, 4] }));
addHttpResponseInterceptor('interceptor-1', interceptor1);

const interceptor2 = jest.fn().mockImplementation((req, resp) =>
const interceptor2 = jest.fn().mockImplementation((resp, req) =>
Promise.resolve({
...resp,
body: { interceptor: `interceptor2-${req.method}`, original: resp.body },
Expand All @@ -122,10 +122,10 @@ describe('Configuration service', () => {

const interceptedResponse = await applyInterceptors(request, response);

expect(interceptor1).toHaveBeenCalledWith(request, response);
expect(interceptor1).toHaveBeenCalledWith(response, request);
expect(interceptor2).toHaveBeenLastCalledWith(
request,
expect.objectContaining({ body: [1, 2, 3, 4] }),
request,
);
expect(interceptedResponse).toEqual({
...response,
Expand All @@ -145,5 +145,21 @@ describe('Configuration service', () => {

expect(applyInterceptors(request, response)).resolves.toEqual(response);
});
it('should return response if interceptor returns void', async () => {
const request: TalendRequest = {
url: '/api/v1/data',
method: HTTP_METHODS.GET,
};
const response = {
ok: true,
status: HTTP_STATUS.OK,
body: [1, 2, 3],
} as unknown as Response;
const interceptor = jest.fn().mockImplementation(() => {});
addHttpResponseInterceptor('interceptor', interceptor);
const gotResponse = await applyInterceptors(request, response);
expect(gotResponse).toEqual(response);
expect(interceptor).toHaveBeenCalledWith(response, request);
});
});
});
5 changes: 3 additions & 2 deletions packages/http/src/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ export const HTTP: { defaultConfig?: TalendRequestInit | null } = {
defaultConfig: null,
};

export type Interceptor = (request: TalendRequest, response: Response) => Promise<Response>;
export type Interceptor = (response: Response, request: TalendRequest) => Promise<Response> | void;

export const HTTP_RESPONSE_INTERCEPTORS: Record<string, Interceptor> = {};

Expand All @@ -27,7 +27,8 @@ export function removeHttpResponseInterceptor(name: string) {

export function applyInterceptors(request: TalendRequest, response: Response): Promise<Response> {
return Object.values(HTTP_RESPONSE_INTERCEPTORS).reduce(
(promise, interceptor) => promise.then(resp => interceptor(request, resp)),
(promise, interceptor) =>
promise.then(resp => interceptor(resp, request) || Promise.resolve(response)),
Promise.resolve(response),
);
}
Expand Down
6 changes: 3 additions & 3 deletions packages/http/src/http.common.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -349,7 +349,7 @@ describe('#httpFetch with interceptors', () => {
});

it('should call interceptor', async () => {
const interceptor = jest.fn().mockImplementation((_, res) => res);
const interceptor = jest.fn().mockImplementation((res, _) => res);
addHttpResponseInterceptor('interceptor', interceptor);

const url = '/foo';
Expand All @@ -360,7 +360,7 @@ describe('#httpFetch with interceptors', () => {
});

it('should have access to context in interceptor', async () => {
const interceptor = jest.fn().mockImplementation((_, res) => res);
const interceptor = jest.fn().mockImplementation((res, _) => res);
addHttpResponseInterceptor('interceptor', interceptor);

const url = '/foo';
Expand All @@ -370,8 +370,8 @@ describe('#httpFetch with interceptors', () => {

await httpFetch(url, { context }, HTTP_METHODS.GET, {});
expect(interceptor).toHaveBeenCalledWith(
expect.objectContaining({ url, context, method: HTTP_METHODS.GET }),
expect.anything(),
expect.objectContaining({ url, context, method: HTTP_METHODS.GET }),
);
});
});

0 comments on commit 58e99f1

Please sign in to comment.