From e065f481bd9b0132cb2f0ab850644b81c517f179 Mon Sep 17 00:00:00 2001 From: jlenon7 Date: Wed, 6 Aug 2025 12:18:51 -0300 Subject: [PATCH] feat(http): add option to run server for AWS Lambda --- package-lock.json | 12 +++--- package.json | 4 +- src/applications/Http.ts | 44 ++++++++++++++++------ src/types/HttpOptions.ts | 7 ++++ tests/unit/applications/HttpTest.ts | 11 ++++++ tests/unit/commands/BuildCommandTest.ts | 2 - tests/unit/commands/MakeTestCommandTest.ts | 2 - 7 files changed, 59 insertions(+), 23 deletions(-) diff --git a/package-lock.json b/package-lock.json index 95fe46b..2bfc188 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "@athenna/core", - "version": "5.21.0", + "version": "5.22.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@athenna/core", - "version": "5.21.0", + "version": "5.22.0", "license": "MIT", "dependencies": { "pretty-repl": "^3.1.2", @@ -17,7 +17,7 @@ "@athenna/common": "^5.14.0", "@athenna/config": "^5.4.0", "@athenna/cron": "^5.9.0", - "@athenna/http": "^5.34.0", + "@athenna/http": "^5.38.0", "@athenna/ioc": "^5.2.0", "@athenna/logger": "^5.8.0", "@athenna/test": "^5.5.0", @@ -137,9 +137,9 @@ } }, "node_modules/@athenna/http": { - "version": "5.34.0", - "resolved": "https://registry.npmjs.org/@athenna/http/-/http-5.34.0.tgz", - "integrity": "sha512-ERbm/MYDuPfV+bx0uWe1jB/1KQ+Z2q9OgREo1/SPwQDJus/8IKE0JIZ45uC9L3CRoMMIdPAc6MhbkhSYZUmgEw==", + "version": "5.38.0", + "resolved": "https://registry.npmjs.org/@athenna/http/-/http-5.38.0.tgz", + "integrity": "sha512-wMhmtUT/kZB3N4D8uTu/gKJkggjUPcu1gJsThUC72JG3P5McoWNpD9L4fcOSMgAcp0KRLmCxyi5e2tJCGzT/xg==", "dev": true, "license": "MIT", "engines": { diff --git a/package.json b/package.json index 48e333d..9070503 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@athenna/core", - "version": "5.21.0", + "version": "5.22.0", "description": "One foundation for multiple applications.", "license": "MIT", "author": "João Lenon ", @@ -85,7 +85,7 @@ "@athenna/common": "^5.14.0", "@athenna/config": "^5.4.0", "@athenna/cron": "^5.9.0", - "@athenna/http": "^5.34.0", + "@athenna/http": "^5.38.0", "@athenna/ioc": "^5.2.0", "@athenna/logger": "^5.8.0", "@athenna/test": "^5.5.0", diff --git a/src/applications/Http.ts b/src/applications/Http.ts index 48f84d5..eb6af29 100644 --- a/src/applications/Http.ts +++ b/src/applications/Http.ts @@ -18,17 +18,6 @@ export class Http { * Only initialize the server without booting it. */ public static async init(options?: HttpOptions): Promise { - options = Options.create(options, { - initOnly: false, - host: Config.get('http.host', '127.0.0.1'), - port: Config.get('http.port', 3000), - routePath: Config.get('rc.http.route', Path.routes(`http.${Path.ext()}`)), - kernelPath: Config.get( - 'rc.http.kernel', - '@athenna/http/kernels/HttpKernel' - ) - }) - const server = ioc.safeUse('Athenna/Core/HttpServer') debug('booting http application with options %o', options) @@ -46,12 +35,28 @@ export class Http { * Boot the Http application. */ public static async boot(options?: HttpOptions): Promise { + options = Options.create(options, { + initOnly: false, + isAWSLambda: false, + host: Config.get('http.host', '127.0.0.1'), + port: Config.get('http.port', 3000), + routePath: Config.get('rc.http.route', Path.routes(`http.${Path.ext()}`)), + kernelPath: Config.get( + 'rc.http.kernel', + '@athenna/http/kernels/HttpKernel' + ) + }) + const server = await this.init(options) if (options.initOnly) { return server } + if (options.isAWSLambda) { + return this.resolveAWSLambdaProxy(server) + } + await server.listen({ host: options.host, port: options.port }) if (Config.notExists('rc.bootLogs') || Config.is('rc.bootLogs', false)) { @@ -110,4 +115,21 @@ export class Http { ) } } + + /** + * Resolve the AWS Lambda proxy. + */ + private static async resolveAWSLambdaProxy(server: ServerImpl) { + const awsLambda = await Module.safeImport('@athenna/http/awslambda') + + if (awsLambda?.default) { + return awsLambda.default(server.fastify) + } + + if (!awsLambda) { + throw new Error('The library @fastify/aws-lambda is not installed') + } + + return awsLambda(server.fastify) + } } diff --git a/src/types/HttpOptions.ts b/src/types/HttpOptions.ts index 3e0f989..3152ced 100644 --- a/src/types/HttpOptions.ts +++ b/src/types/HttpOptions.ts @@ -16,6 +16,13 @@ export type HttpOptions = { */ initOnly?: boolean + /** + * If true, the server will be initialized to be consumed by AWS Lambda. + * + * @default false + */ + isAWSLambda?: boolean + /** * The host where the server will run. By default Athenna will read the "http.host" config * to get this information, but you can set here and subscribe this behavior. diff --git a/tests/unit/applications/HttpTest.ts b/tests/unit/applications/HttpTest.ts index f9ef52b..590db76 100644 --- a/tests/unit/applications/HttpTest.ts +++ b/tests/unit/applications/HttpTest.ts @@ -141,4 +141,15 @@ export default class HttpTest { assert.calledWith(successMock, 'Http server started on ({yellow} localhost:3000)') assert.calledWith(successMock, 'Kernel ({yellow} HttpKernel) successfully booted') } + + @Test() + public async shouldThrowAnErrorWhenBootingAHttpApplicationToBeConsumedByAWSLambdaAndTheLibraryIsNotInstalled({ + assert + }: Context) { + Config.set('rc.bootLogs', true) + + assert.rejects(() => Http.boot({ isAWSLambda: true }), { + message: 'The library @fastify/aws-lambda is not installed' + }) + } } diff --git a/tests/unit/commands/BuildCommandTest.ts b/tests/unit/commands/BuildCommandTest.ts index 247d5d7..1601838 100644 --- a/tests/unit/commands/BuildCommandTest.ts +++ b/tests/unit/commands/BuildCommandTest.ts @@ -16,8 +16,6 @@ export default class BuildCommandTest extends BaseCommandTest { public async shouldBeAbleToBuildTheApplicationCode({ assert, command }: Context) { const output = await command.run('build') - console.log(output.output.stdout) - console.log(output.output.stderr) output.assertSucceeded() output.assertLogged('Application successfully compiled') diff --git a/tests/unit/commands/MakeTestCommandTest.ts b/tests/unit/commands/MakeTestCommandTest.ts index 75d0dd7..82a6ad6 100644 --- a/tests/unit/commands/MakeTestCommandTest.ts +++ b/tests/unit/commands/MakeTestCommandTest.ts @@ -60,8 +60,6 @@ export default class MakeTestCommandTest extends BaseCommandTest { public async shouldBeAbleToCreateATestFileUsingCronTemplate({ assert, command }: Context) { const output = await command.run('make:test TestTest --cron') - console.log(output.output) - output.assertSucceeded() output.assertLogged('[ MAKING TEST ]') output.assertLogged('[ success ] Test "TestTest" successfully created.')