Skip to content

Commit 4f1ab19

Browse files
堀家隆宏堀家隆宏
堀家隆宏
authored and
堀家隆宏
committed
first commit
0 parents  commit 4f1ab19

15 files changed

+6453
-0
lines changed

.env.example

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
# Environment variables
2+
STAGE=

.eslintignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
dist

.eslintrc.yml

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
env:
2+
browser: true
3+
node: true
4+
es6: true
5+
6+
extends:
7+
- 'eslint:recommended'
8+
- 'plugin:jest/recommended'
9+
- 'plugin:@typescript-eslint/recommended'
10+
- 'plugin:@typescript-eslint/eslint-recommended'
11+
12+
parserOptions:
13+
parser: '@typescript-eslint/parser'
14+
tsconfigRootDir: ./
15+
sourceType: module
16+
17+
rules:
18+
array-bracket-spacing:
19+
- error
20+
- always
21+
max-len:
22+
- error
23+
- code: 120
24+
ignoreComments: true
25+
ignoreTrailingComments: true
26+
ignoreUrls: true
27+
ignoreTemplateLiterals: true
28+
ignoreRegExpLiterals: true
29+
no-var: error
30+
no-console: 0
31+
semi:
32+
- error
33+
- never
34+
- beforeStatementContinuationChars: never
35+
space-before-blocks:
36+
- error
37+
- always
38+
semi-spacing:
39+
- error
40+
- after: true
41+
before: false
42+
quotes:
43+
- error
44+
- single
45+
'@typescript-eslint/indent':
46+
- error
47+
- 2
48+
no-case-declarations: 0
49+
jest/no-jasmine-globals: off
50+
'@typescript-eslint/camelcase': off
51+
'@typescript-eslint/no-non-null-assertion': off
52+
'@typescript-eslint/ban-ts-ignore': off
53+
'@typescript-eslint/interface-name-prefix': off
54+
'@typescript-eslint/member-delimiter-style': off
55+
'@typescript-eslint/no-explicit-any': off
56+
'@typescript-eslint/no-unused-vars': off
57+
'@typescript-eslint/explicit-function-return-type': off
58+
'@typescript-eslint/no-var-requires': off

.gitignore

Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
# Created by .ignore support plugin (hsz.mobi)
2+
### Node template
3+
# Logs
4+
/logs
5+
*.log
6+
npm-debug.log*
7+
yarn-debug.log*
8+
yarn-error.log*
9+
10+
# Runtime data
11+
pids
12+
*.pid
13+
*.seed
14+
*.pid.lock
15+
16+
# Directory for instrumented libs generated by jscoverage/JSCover
17+
lib-cov
18+
19+
# Coverage directory used by tools like istanbul
20+
coverage
21+
22+
# nyc test coverage
23+
.nyc_output
24+
25+
# Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files)
26+
.grunt
27+
28+
# Bower dependency directory (https://bower.io/)
29+
bower_components
30+
31+
# node-waf configuration
32+
.lock-wscript
33+
34+
# Compiled binary addons (https://nodejs.org/api/addons.html)
35+
build/Release
36+
37+
# Dependency directories
38+
node_modules/
39+
jspm_packages/
40+
41+
# TypeScript v1 declaration files
42+
typings/
43+
44+
# Optional npm cache directory
45+
.npm
46+
47+
# Optional eslint cache
48+
.eslintcache
49+
50+
# Optional REPL history
51+
.node_repl_history
52+
53+
# Output of 'npm pack'
54+
*.tgz
55+
56+
# Yarn Integrity file
57+
.yarn-integrity
58+
59+
# dotenv environment variables file
60+
.env
61+
62+
# parcel-bundler cache (https://parceljs.org/)
63+
.cache
64+
65+
# next.js build output
66+
.next
67+
68+
# nuxt.js build output
69+
.nuxt
70+
71+
# Nuxt generate
72+
dist
73+
74+
# vuepress build output
75+
.vuepress/dist
76+
77+
# Serverless directories
78+
.serverless
79+
80+
# IDE / Editor
81+
.idea
82+
83+
# Service worker
84+
sw.*
85+
86+
# macOS
87+
.DS_Store
88+
89+
# Vim swap files
90+
*.swp
91+
92+
# CDK asset staging directory
93+
.cdk.staging
94+
cdk.out
95+
96+
# Test coverage
97+
.coverage

.vscode/settings.json

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
{
2+
"editor.codeActionsOnSave": {
3+
"source.fixAll.eslint": true
4+
},
5+
"eslint.packageManager": "yarn",
6+
"eslint.validate": [
7+
"javascript",
8+
"typescript",
9+
"vue"
10+
],
11+
"files.associations": {
12+
"*.vue": "vue"
13+
}
14+
}

README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
## CDK HTTPAPI Lambda with OpenAPI
2+
This is a sample which you can deploy your app uging API of API Gateway(HTTPAPI + Lambda) with Open API deninition.

cdk.json

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
{
2+
"app": "npx ts-node --prefer-ts-exts deploy/cdk-deploy.ts",
3+
"context": {}
4+
}

deploy/api-definition.yaml

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
---
2+
openapi: 3.0.1
3+
info:
4+
title: Hello API
5+
description: An api always returns HELLO
6+
version: 1.0.0
7+
8+
paths:
9+
/hello:
10+
get:
11+
summary: Returning Hello.
12+
responses:
13+
200:
14+
$ref: '#/components/responses/GetHelloResponse'
15+
500:
16+
$ref: '#/components/responses/InternalServerError'
17+
18+
components:
19+
schemas:
20+
Error:
21+
type: object
22+
required:
23+
- error
24+
- message
25+
properties:
26+
error:
27+
type: string
28+
description: Error code
29+
message:
30+
type: string
31+
description: Error message
32+
Hello:
33+
type: object
34+
required:
35+
- message
36+
properties:
37+
message:
38+
type: string
39+
description: message
40+
responses:
41+
InternalServerError:
42+
description: Unexpected error
43+
content:
44+
application/json:
45+
schema:
46+
$ref: '#/components/schemas/Error'
47+
GetHelloResponse:
48+
description: Get hello response.
49+
content:
50+
application/json:
51+
schema:
52+
$ref: '#/components/schemas/Hello'

deploy/api-stack.ts

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
import * as cdk from '@aws-cdk/core'
2+
import { Code, Function, Runtime } from '@aws-cdk/aws-lambda'
3+
import { CfnApi, CfnStage } from '@aws-cdk/aws-apigatewayv2'
4+
import { ServicePrincipal } from '@aws-cdk/aws-iam'
5+
6+
export interface ApiProps extends cdk.StackProps {
7+
stage: string
8+
openApi: any
9+
}
10+
11+
interface IntegrationSetting {
12+
readonly type: string
13+
readonly httpMethod: string
14+
readonly uri: string
15+
readonly payloadFormatVersion: string
16+
}
17+
18+
export class ApiStack extends cdk.Stack {
19+
20+
constructor(scope: cdk.Construct, id: string, props: ApiProps) {
21+
super(scope, id, props)
22+
23+
const myFunction = new Function(this, 'myFunction', {
24+
code: Code.fromAsset('dist/handler'),
25+
handler: 'index.handler',
26+
runtime: Runtime.NODEJS_14_X
27+
})
28+
29+
const integrationSetting: IntegrationSetting = {
30+
type: 'AWS_PROXY',
31+
httpMethod: 'POST',
32+
uri: myFunction.functionArn,
33+
payloadFormatVersion: '2.0'
34+
}
35+
36+
Object.entries(props.openApi.paths).forEach(([ path ]) => {
37+
Object.entries(props.openApi.paths[path]).forEach(([ method ]) => {
38+
props.openApi.paths[path][method]['x-amazon-apigateway-integration'] = integrationSetting
39+
})
40+
})
41+
42+
const api = new CfnApi(this, 'httpApi', {
43+
body: props.openApi
44+
})
45+
46+
new CfnStage(this, `api-${props.stage}`, {
47+
apiId: api.ref,
48+
stageName: '$default',
49+
autoDeploy: true,
50+
})
51+
52+
myFunction.addPermission(
53+
'myFunctionPermission',
54+
{
55+
principal: new ServicePrincipal('apigateway.amazonaws.com'),
56+
action: 'lambda:InvokeFunction',
57+
sourceArn: `arn:aws:execute-api:${cdk.Stack.of(this).region}:${cdk.Stack.of(this).account}:${api.ref}/*/*/*`
58+
}
59+
)
60+
61+
new cdk.CfnOutput(this, 'HTTP API Url', {
62+
value: api.attrApiEndpoint ?? 'Something went wrong with the deploy'
63+
})
64+
}
65+
}

deploy/cdk-deploy.ts

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
#!/usr/bin/env node
2+
import 'source-map-support/register'
3+
import * as cdk from '@aws-cdk/core'
4+
import { ApiStack } from './api-stack'
5+
import * as dotenv from 'dotenv'
6+
dotenv.config()
7+
8+
const SwaggerParser = require('@apidevtools/swagger-parser')
9+
10+
const {
11+
STAGE = 'dev'
12+
} = process.env
13+
14+
async function createApp(): Promise<cdk.App> {
15+
const openApi: any = await SwaggerParser.dereference('./deploy/api-definition.yaml')
16+
const app = new cdk.App()
17+
18+
19+
new ApiStack(app, `MyApiStack-${STAGE}`, {
20+
stage: STAGE,
21+
openApi: openApi,
22+
})
23+
24+
return app
25+
}
26+
createApp()

package.json

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
{
2+
"name": "cdk-httpapi-lambda-with-openapi",
3+
"version": "1.0.0",
4+
"scripts": {
5+
"build": "webpack",
6+
"deploy": "cdk deploy --all",
7+
"test": "jest --coverage",
8+
"lint": "eslint --ext \".js,.ts\" --ignore-path .gitignore ."
9+
},
10+
"devDependencies": {
11+
"@apidevtools/swagger-parser": "^10.0.2",
12+
"@aws-cdk/aws-apigatewayv2": "^1.91.0",
13+
"@aws-cdk/aws-lambda": "^1.91.0",
14+
"@aws-cdk/aws-iam": "^1.91.0",
15+
"@types/aws-lambda": "^8.10.72",
16+
"@types/jest": "^26.0.10",
17+
"@types/node": "10.17.27",
18+
"@typescript-eslint/eslint-plugin": "^4.16.1",
19+
"@typescript-eslint/parser": "^4.16.1",
20+
"aws-cdk": "1.91.0",
21+
"dotenv": "^8.2.0",
22+
"eslint": "^7.21.0",
23+
"eslint-plugin-jest": "^24.1.5",
24+
"jest": "^26.4.2",
25+
"ts-jest": "^26.2.0",
26+
"ts-loader": "^8.0.17",
27+
"ts-node": "^9.0.0",
28+
"typescript": "~3.9.7",
29+
"webpack": "^5.24.2",
30+
"webpack-cli": "^4.5.0",
31+
"webpack-node-externals": "^2.5.2"
32+
},
33+
"dependencies": {
34+
"source-map-support": "^0.5.16"
35+
}
36+
}
37+

src/handler.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
import { APIGatewayProxyHandlerV2 } from 'aws-lambda'
2+
3+
export const handler: APIGatewayProxyHandlerV2 = async (event) => {
4+
return {
5+
statusCode: 200,
6+
body: JSON.stringify({message: 'HELLO'})
7+
}
8+
}

0 commit comments

Comments
 (0)