From c4d431ffa920a0e8c369bc3d0e69bddcf57e031c Mon Sep 17 00:00:00 2001 From: Xavier Redondo Bolet Date: Tue, 31 Jan 2023 21:54:23 +0100 Subject: [PATCH] fix(bautajs-express-example, bautajs-fastify-example): add service to showcase request cancellation (#72) --- packages/bautajs-express-example/README.md | 2 + .../api-definition.json | 32 ++++++++++++++ .../resolvers/cancel-request-resolver.js | 43 +++++++++++++++++++ packages/bautajs-fastify-example/README.md | 3 ++ .../api-definition.json | 32 ++++++++++++++ .../resolvers/cancel-request-resolver.js | 43 +++++++++++++++++++ 6 files changed, 155 insertions(+) create mode 100644 packages/bautajs-express-example/server/resolvers/cancel-request-resolver.js create mode 100644 packages/bautajs-fastify-example/server/resolvers/cancel-request-resolver.js diff --git a/packages/bautajs-express-example/README.md b/packages/bautajs-express-example/README.md index 6b83825d..5ca6bb1e 100644 --- a/packages/bautajs-express-example/README.md +++ b/packages/bautajs-express-example/README.md @@ -37,6 +37,8 @@ - GET `api/multiple-path/{key}` - GET `api/multiple-path/specific` - These two endpoints help understand how the route ordering works +- GET `api/cancel/{number}` + - Returns a string if number is less than 10 seconds. Aborts after 10 seconds in the rest of the cases. ## Custom Logger example diff --git a/packages/bautajs-express-example/api-definition.json b/packages/bautajs-express-example/api-definition.json index a088643d..ed2381bc 100644 --- a/packages/bautajs-express-example/api-definition.json +++ b/packages/bautajs-express-example/api-definition.json @@ -30,6 +30,38 @@ } } }, + "/cancel/{number}": { + "get": { + "summary": "service to test cancel request. Waits number seconds until an answer is given but cancel if number is greather than 10 seconds", + "operationId": "cancelRequest", + "parameters": [ + { + "name": "number", + "in": "path", + "description": "The number of seconds to wait", + "required": true, + "schema": { + "type": "number" + } + } + ], + "responses": { + "200": { + "description": "Something!" + }, + "default": { + "description": "unexpected error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + } + } + } + }, "/randomYear": { "get": { "summary": "Provides information about a random year", diff --git a/packages/bautajs-express-example/server/resolvers/cancel-request-resolver.js b/packages/bautajs-express-example/server/resolvers/cancel-request-resolver.js new file mode 100644 index 00000000..f95cd05c --- /dev/null +++ b/packages/bautajs-express-example/server/resolvers/cancel-request-resolver.js @@ -0,0 +1,43 @@ +const { resolver, pipe, step } = require('@axa/bautajs-core'); +const { getRequest } = require('@axa/bautajs-express'); + +const transformResponse = step(response => { + return { + message: response + }; +}); + +function getNumberFromRequestStep(_prev, ctx) { + const req = getRequest(ctx); + + const { number } = req.params; + + return number; +} + +function giveAnswerAfterWaitingWithTimeout() { + return step(async (number, ctx) => { + const timeout = number * 1000; + const promiseAnswer = new Promise(resolve => + setTimeout(() => { + resolve(`We have waited for ${number} seconds`); + }, timeout) + ); + + const cancelator = new Promise(resolve => + setTimeout(() => { + ctx.token.cancel(); // If this triggers the promise does not resolve but it is cancelled + resolve('ended'); + }, 10000) + ); + + return Promise.race(await [promiseAnswer, cancelator]); + }); +} + +module.exports = resolver(operations => { + operations.cancelRequest + .validateRequest(false) + .validateResponse(false) + .setup(pipe(getNumberFromRequestStep, giveAnswerAfterWaitingWithTimeout(), transformResponse)); +}); diff --git a/packages/bautajs-fastify-example/README.md b/packages/bautajs-fastify-example/README.md index 4dbd8a5a..5292c276 100644 --- a/packages/bautajs-fastify-example/README.md +++ b/packages/bautajs-fastify-example/README.md @@ -37,6 +37,9 @@ - GET `api/multiple-path/{key}` - GET `api/multiple-path/specific` - These two endpoints help understand how the route ordering works +- GET `api/cancel/{number}` + - Returns a string if number is less than 10 seconds. Aborts after 10 seconds in the rest of the cases. + ## Third party dependencies licenses diff --git a/packages/bautajs-fastify-example/api-definition.json b/packages/bautajs-fastify-example/api-definition.json index a088643d..ed2381bc 100644 --- a/packages/bautajs-fastify-example/api-definition.json +++ b/packages/bautajs-fastify-example/api-definition.json @@ -30,6 +30,38 @@ } } }, + "/cancel/{number}": { + "get": { + "summary": "service to test cancel request. Waits number seconds until an answer is given but cancel if number is greather than 10 seconds", + "operationId": "cancelRequest", + "parameters": [ + { + "name": "number", + "in": "path", + "description": "The number of seconds to wait", + "required": true, + "schema": { + "type": "number" + } + } + ], + "responses": { + "200": { + "description": "Something!" + }, + "default": { + "description": "unexpected error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + } + } + } + }, "/randomYear": { "get": { "summary": "Provides information about a random year", diff --git a/packages/bautajs-fastify-example/server/resolvers/cancel-request-resolver.js b/packages/bautajs-fastify-example/server/resolvers/cancel-request-resolver.js new file mode 100644 index 00000000..b37988d6 --- /dev/null +++ b/packages/bautajs-fastify-example/server/resolvers/cancel-request-resolver.js @@ -0,0 +1,43 @@ +const { resolver, pipe, step } = require('@axa/bautajs-core'); +const { getRequest } = require('@axa/bautajs-fastify'); + +const transformResponse = step(response => { + return { + message: response + }; +}); + +function getNumberFromRequestStep(_prev, ctx) { + const req = getRequest(ctx); + + const { number } = req.params; + + return number; +} + +function giveAnswerAfterWaitingWithTimeout() { + return step(async (number, ctx) => { + const timeout = number * 1000; + const promiseAnswer = new Promise(resolve => + setTimeout(() => { + resolve(`We have waited for ${number} seconds`); + }, timeout) + ); + + const cancelator = new Promise(resolve => + setTimeout(() => { + ctx.token.cancel(); // If this triggers the promise does not resolve but it is cancelled + resolve('ended'); + }, 10000) + ); + + return Promise.race(await [promiseAnswer, cancelator]); + }); +} + +module.exports = resolver(operations => { + operations.cancelRequest + .validateRequest(false) + .validateResponse(false) + .setup(pipe(getNumberFromRequestStep, giveAnswerAfterWaitingWithTimeout(), transformResponse)); +});