
Security News
Deno 2.2 Improves Dependency Management and Expands Node.js Compatibility
Deno 2.2 enhances Node.js compatibility, improves dependency management, adds OpenTelemetry support, and expands linting and task automation for developers.
@stackspot/cdk-component-openapi-typescript
Advanced tools
A CDK construct for Typescript that can be used to create the AWS infrastructure to support a API Gateway to Lambda integration based on an OpenAPI specification.
A CDK construct for Typescript that can be used to create the AWS infrastructure to support a API Gateway to Lambda integration based on an OpenAPI specification.
When CDK commands are executed all boilerplate code for API endpoints implementation is also created abstracting this complexity from the developer and letting him focus only on service funcionality implementation.
git clone https://github.com/stack-spot/domainservices-cdk-openapi-lambda.git
cd omainservices-cdk-openapi-lambda
npm install
npm run build
npm run package
cdk-component-openapi-typescript@<version>.jsii.tgz
will be generated in dist/js
folderThe below example will generate a simple hello world service to ilustrate the library usage.
mkdir hello-world-service
cd hello-world-service
cdk init --language=typescript
cdk-component-openapi-typescript@@<version>.jsii.tgz
and @types/aws-lambda
as project dependenciesnpm install @types/aws-lambda <@stackspot/cdk-component-openapi-typescript location>/dist/js/cdk-component-openapi-typescript@<version>.jsii.tgz
hello-world-service/spec/hello-world.yaml
with the OpenAPI specification of hello world serviceopenapi: 3.0.3
info:
title: hello-world
version: '1.0'
description: A simple hello-world REST service
contact:
email: user@stackspot.com.br
servers:
- url: 'http://localhost:3000'
tags:
- name: hello
description: Hello world services
paths:
/hello:
post:
tags:
- hello
description: Receive a name in request body and respond with a greeting message for the name informed
operationId: post-hello
responses:
'200':
description: OK
content:
application/json:
schema:
$ref: '#/components/schemas/HelloResponse'
examples:
example-1:
value:
greeting: Hello John!
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/HelloRequest'
examples:
example-1:
value:
name: John
components:
schemas:
HelloRequest:
title: HelloRequest
type: object
properties:
name:
type: string
required:
- name
HelloResponse:
title: HelloResponse
type: object
properties:
greeting:
type: string
required:
- greeting
hello-world-service/lib/hello-world-service-stack.ts
, import StackSpotOpenApiServices
and create the construct pointing to service spec yamlimport * as cdk from '@aws-cdk/core';
// import StackSpotOpenApiServices
import { StackSpotOpenApiServices } from '@stackspot/cdk-component-openapi-typescript';
export class HelloWorldServiceStack extends cdk.Stack {
constructor(scope: cdk.Construct, id: string, props?: cdk.StackProps) {
super(scope, id, props);
// Create StackSpotOpenApiServices pointing to spec file
new StackSpotOpenApiServices(this, 'HelloWorldServiceApi', {
specPath: 'spec/hello-world.yaml',
});
}
}
cdk bootstrap --profile <your-aws-profile>
If you have permissions problems related to S3 public access block configuration permissions on bootstrap you could add the option --public-access-block-configuration false
to the bootstrap command as shown below:
cdk bootstrap --profile <your-aws-profile> --public-access-block-configuration false
After bootstrap service controller and usecase stubs will be generated at path src/post-hello
.
src/post-hello/usecase.ts
) and implement the code to generate the expected response imported from src/api-models.ts
as shown below:import { HelloRequest, HelloResponse } from '../api-schemas';
export type PostHelloParams = {
requestBody: HelloRequest,
};
export const postHello = async ({ requestBody }: PostHelloParams): Promise<HelloResponse> => {
return {
greeting: `Hello ${requestBody.name}!`,
};
};
npm run build
, cdk deploy
and call api at the endpoint created with an appropriate payload.npm run build
cdk deploy
curl -X POST -H 'Content-Type: application/json' -d '{"name": "StackSpot"}' https://mhi8zrb3c7.execute-api.us-east-1.amazonaws.com/prod/hello
Congratulations! You created your API based on an OpenAPI specification and deployed it at AWS with API Gateway and Lambda!
npm run build
compile typescript to jsiinpm run watch
watch for changes and compilenpm run test
perform the jest unit testsnpm run package
package library using jsiinpm run coverage
run tests with coverage reportsThe generated source code is organized in a layered archicture with some basic components: Core components, API Schemas and Errors, Parameters Configurations, Operation Controllers and Operation Use Cases.
Core components are responsible to provide utilities and base classes for other components.
You can create you own files in core components but the files created by the CDK Construction are overwrited when a cdk command is runned by the user. DON'T change the core generated files or your changes WILL BE LOST.
You can customize the base components like Controller extending them and adding/changing behaviours as you need.
The base classes provides some template methods to customize their behaviour in subclasses.
All schemas defined in OpenAPI components section are parsed and represented as typescript interfaces in `src/api-schemas.ts.
All changes made to the schemas are reflected to this file when use execute cdk synth and the file is overwrited, so DON'T change this file or your changes WILL BE LOST.
The construct also create an error structure that is used as base class for errors in api.
All responses of api operations that are not 2xx response codes generates an Error subclass representing this return code. When you need to return this response to user you can throw the corresponding error and the controller will convert the response accordingly.
All operations defined in OpenAPI operations objects generates a JSON file with the parameters defined by the operation.
The operation controller uses this configuration to know how to parse the parameters from API Gateway event and convert them to API schema objects and parameters to operation use case responsible to process the request.
Parameters configurations are overwrited every time the user execute a cdk command so DON'T change this file or your changes WILL BE LOST.
There are some known limitations in parameters definitions in your OpenAPI spec:
cookie
parameters are not supported.arrays
are not supported in path or header parameters.object
parameters are not supported.style
an explode
parameters modifiers are not supported.arrays
of arrays
.Controllers are responsible to convert API Gateway event to parameters and API schemas representations a to execute use cases with the parameters already converted.
They also can be responsible to validate resource access using an use case and throwing AccessDeniedError when necessary.
Controllers have some template methods that can be use to customize their behaviour:
buildUseCaseArgs
can be ovewrited to customize use case arguments when needed.transformUseCaseResponse
can be overwrited to transform use case response before converting it to success response.convertResponseToApiGatewayResponse
can be overwrited to customize the response creation. A common usecase is to return binary data instead of JSON.Controllers are generated when user executes a cdk command but don't ovewrite already generated controllers, so you can safelly modify controllers source code as you need.
Use cases are responsible to implement the business rules of API.
We recomend to isolate database interactions in repositories to abstract database acesss.
Error codes represented by operation responses are generated as error classes in usecase file and this errors can be throw to generate the non success response of API.
The requestBody when exists is converted by controllers and received as use case parameter.
When JWT authentication is enabled jwtTokenPayload
is passed as parameter for use case so they can do security assertions.
Use cases are generated when user executes a cdk command but don't ovewrite already generated use cases, so you can safelly modify use case source code as you need.
components:
securitySchemes:
jwtAuth:
type: http
scheme: bearer
bearerFormat: JWT
# root level
security:
- jwtAuth: []
paths:
/auctions/{id}:
parameters:
- $ref: '#/components/parameters/AuctionId'
- $ref: '#/components/parameters/Authorization'
get:
operationId: get-auction
description: Get auction data by id
# operation level
security:
- jwtAuth: []
tags:
- Auction services
responses:
'200':
description: Auction returned successfully
content:
application/json:
schema:
$ref: '#/components/schemas/Auction'
'404':
description: Auction not found
const api = new StackSpotOpenApiServices(this, 'StackSampleAPI', {
specPath: 'spec/auction-api.yaml',
jwksUri: 'https://some.idm.provider/auth/realms/some-realm/protocol/openid-connect/certs',
});
If you are using an IDM that supports OpenID connect you can get JWKS_URI endpoint in well-known endpoint of OpenID connect provider.
When you enable JWT authorization your controllers will extend JWTAuthorizationController
class and you can override the authorizeResourceAccess
method to do some custom authorization logic. The JWT token payload can be accessed using this.jwtTokenPayload
protected property. Controlles already generated before JWT authorization will not be overwrited an must be changed by the user.
With JWT Authorization enabled an API Gateway Lambda authorizer will be configured to validate the token.
Authorization logic is not made by this lambda only the authenticity and validity of token is verified. You need to implement your authorization logic using token claims in operations controllers or create a new base constroller class based on JWTAuthorizationControler
to use as base class of your controllers and implement authorization logic on it.
It's possible to configure properties on the construct as shown below:
export interface StackSpotOpenAPIServicesProps {
readonly specPath: string;
readonly sourceDir?: string;
readonly enableValidation?: boolean;
readonly enableTracing?: boolean;
readonly jwksUri?: string;
readonly endpointTypes?: apigateway.EndpointType;
}
export declare enum EndpointType {
/**
* For an edge-optimized API and its custom domain name.
*
* @stability stable
*/
EDGE = 'EDGE',
/**
* For a regional API and its custom domain name.
*
* @stability stable
*/
REGIONAL = 'REGIONAL',
/**
* For a private API and its custom domain name.
*
* @stability stable
*/
PRIVATE = 'PRIVATE',
}
const serviceProps: StackSpotOpenAPIServicesProps = {
specPath: 'spec/auction-api.yaml',
sourceDir: 'app/src',
enableValidation: true,
enableTracing: true,
jwksUri: 'https://some.idm.provider/auth/realms/some-realm/protocol/openid-connect/certs',
endpointTypes: EndpointType.EDGE,
};
const api = new StackSpotOpenApiServices(this, 'StackSpotOpenApiServicesID', serviceProps);
specPath: Defines the path to OpenAPI specification file.
sourceDir: Defines the path to the source code generated based on OpenAPI specification file. Default: 'src'
enableValidation: If true, enable validators config in OpenAPI specification
enableTracing: If true, enable Amazon X-Ray tracing for ApiGateway and Lambda Function
jwksUri: JWKS URI to verify JWT Token signatures
endpointTypes: Defines the ApiGateway endpoint type. Default: EndpointType.EDGE
FAQs
A CDK construct for Typescript that can be used to create the AWS infrastructure to support a API Gateway to Lambda integration based on an OpenAPI specification.
We found that @stackspot/cdk-component-openapi-typescript demonstrated a not healthy version release cadence and project activity because the last version was released a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Security News
Deno 2.2 enhances Node.js compatibility, improves dependency management, adds OpenTelemetry support, and expands linting and task automation for developers.
Security News
React's CRA deprecation announcement sparked community criticism over framework recommendations, leading to quick updates acknowledging build tools like Vite as valid alternatives.
Security News
Ransomware payment rates hit an all-time low in 2024 as law enforcement crackdowns, stronger defenses, and shifting policies make attacks riskier and less profitable.