tsoa
tsoa copied to clipboard
Middleware: AWS API Gateway V2 Support
Sorting
-
I'm submitting a ...
- [ ] bug report
- [x] feature request
- [ ] support request
-
I confirm that I
- [x] used the search to make sure that a similar issue hasn't already been submit
Replaces: https://github.com/lukeautry/tsoa/issues/971 Enables: https://github.com/lukeautry/tsoa/issues/1105
Background
AWS APIGateway V2 is a high availability API as a Service that provides:
- Authentication
- Authorisation
- Routing
It has native support for uploading an OPENAPI declaration as shown in https://github.com/lukeautry/tsoa/issues/1012
Proposal
This issue proposes supporting API Gateway V2 natively with the following API:
Generation of routes for an Lambda handler that supports TSOA
{
"basePath": "/v1",
"entryFile": "./src/handler.ts",
"middleware": "api-gateway-v2"
}
Creation of the src/handler.ts
import { RegisteredRoutes } form './routes'
// A single lambda for all routes
export const handler = (event, context) => RegisteredRoutes
// A lambda solely for the get user route, which invokes the appropriate controller
const getUserHandler = (event, context) => RegisteredRoutes['GET /user/:userId']
The Lambda code above for NodeJS is deployed behind an AWS API Gateway V2 instance.
Justification
API Gateway V2 backed by Lambda is a very popular stack for constructing high availability (10,000 req/s) APIs. These API's are 100% free at low volume making them a good candidate for Start-ups, and established players alike.
There are few frameworks existing designed to make:
- Type safety guarantees
- Payload validation
- Documentation generation
Easy for this environment.
As such users have previously attempted to use TSOA to enable a better developer experience. Those users and potential new users attracted to the framework by its support of lambda would be the target.
Alternatives
- Just use express with Vendias serverless express https://github.com/vendia/serverless-express
- Use NestJS with standalone deployment to serverless https://docs.nestjs.com/faq/serverless
API Gateway & Lambda Integration
AWS API Gateway handles authentication, authorisation, and routing. The template required for lambda would therefore not include those concerns.
Additionally an assumption would be made that File handling would be outside the scope of the initial implementation
API Gateway provides the (event, context) where event is basically (req) in javascript middleware frameworks.
Interfaces
Since API Gateway is mature and versioned semantically by AWS, it is a good candidate for an integration template.
Request/Response formats are typed by the @types/aws-lambda library as:
export interface APIGatewayProxyEventV2 {
version: string;
routeKey: string;
rawPath: string;
rawQueryString: string;
cookies?: string[] | undefined;
headers: APIGatewayProxyEventHeaders;
queryStringParameters?: APIGatewayProxyEventQueryStringParameters | undefined;
requestContext: {
accountId: string;
apiId: string;
authorizer?: {
jwt: {
claims: { [name: string]: string | number | boolean | string[] };
scopes: string[];
};
} | undefined;
domainName: string;
domainPrefix: string;
http: {
method: string;
path: string;
protocol: string;
sourceIp: string;
userAgent: string;
};
requestId: string;
routeKey: string;
stage: string;
time: string;
timeEpoch: number;
};
body?: string | undefined;
pathParameters?: APIGatewayProxyEventPathParameters | undefined;
isBase64Encoded: boolean;
stageVariables?: APIGatewayProxyEventStageVariables | undefined;
}
Response:
export interface APIGatewayProxyStructuredResultV2 {
statusCode?: number | undefined;
headers?: {
[header: string]: boolean | number | string;
} | undefined;
body?: string | undefined;
isBase64Encoded?: boolean | undefined;
cookies?: string[] | undefined;
}
Hello there simonireilly 👋
Thank you for opening your very first issue in this project.
We will try to get back to you as soon as we can.👀
+1
Being able to automatically ship to Lambda/API Gateway would be awesome!
Seconding the above. Right now it looks like we'll be manipulating the YAML in Jenkins or Terraform during deploy.. which is exactly what the old system did that pushed us to move away from it 😂 Thanks for your work on this.