Repository navigation
Expand file tree
/
Copy pathMyStack.ts
More file actions
122 lines (109 loc) · 3.67 KB
/
Copy pathMyStack.ts
File metadata and controls
122 lines (109 loc) · 3.67 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
import { StackContext, Api, Function, Config } from "sst/constructs";
import * as openapix from "@alma-cdk/openapix";
import * as yaml from "yaml";
import * as apigateway from "aws-cdk-lib/aws-apigateway";
import * as iam from "aws-cdk-lib/aws-iam";
import { OpenApiService } from "../packages/core/src/openApi/openApiService";
export function API({ stack }: StackContext) {
const openApiFunction = new Function(stack, "open-api", {
handler: "packages/functions/src/openApi.handler",
});
const openApiDocsFunction = new Function(stack, "open-api-docs", {
handler: "packages/functions/src/openApiDocs.handler",
copyFiles: [
{
from: "packages/functions/src/openApi.html",
to: "packages/functions/src/openApi.html",
},
],
});
const httpApi = new Api(stack, "api", {
routes: {
"GET /openapi.json": openApiFunction,
"GET /openapi.yaml": openApiFunction,
"GET /docs": openApiDocsFunction,
"PUT /customer/{id}": "packages/functions/src/updateCustomerHttp.handler",
},
});
const updateCustomerFunction = new Function(stack, "update-customer", {
handler: "packages/functions/src/updateCustomerRest.handler",
});
const openApiYaml = yaml.stringify(
OpenApiService.createOpenApiSchema([], "rest")
);
const restApi = new openapix.Api(stack, "rest-api", {
source: openapix.Schema.fromInline(openApiYaml),
validators: {
all: {
validateRequestBody: true,
validateRequestParameters: true,
default: true,
},
},
paths: {
"/openapi.json": {
get: new openapix.LambdaIntegration(stack, openApiFunction),
},
"/openapi.yaml": {
get: new openapix.LambdaIntegration(stack, openApiFunction),
},
"/docs": {
get: new openapix.LambdaIntegration(stack, openApiDocsFunction),
},
"/customer/{id}": {
put: new openapix.LambdaIntegration(stack, updateCustomerFunction),
},
},
});
// Add Gateway Responses to get more detailed error messages
restApi.addGatewayResponse("BadRequestBody", {
type: apigateway.ResponseType.BAD_REQUEST_BODY,
responseHeaders: {
"Access-Control-Allow-Origin": "'*'",
},
templates: {
"application/json": JSON.stringify({
message: "$context.error.validationErrorString",
}),
},
});
restApi.addGatewayResponse("BadRequestParameters", {
type: apigateway.ResponseType.BAD_REQUEST_PARAMETERS,
responseHeaders: {
"Access-Control-Allow-Origin": "'*'",
},
templates: {
"application/json": JSON.stringify({
message: "$context.error.validationErrorString",
}),
},
});
const cfnRestApi = restApi.node.defaultChild as apigateway.CfnRestApi;
const restApiUrl = `https://${cfnRestApi.ref}.execute-api.${stack.region}.${stack.urlSuffix}/${restApi.deploymentStage.stageName}`;
const httpApiUrlConfig = new Config.Parameter(stack, "HTTP_API", {
value: httpApi.url,
});
new Config.Parameter(stack, "REST_API", {
value: restApiUrl,
});
openApiFunction.bind([httpApiUrlConfig]);
// Can not set REST_API as environment variable because of circular dependency issue.
// I read it from SSM Parameter Store instead.
// I need to grant access:
openApiFunction.role?.attachInlinePolicy(
new iam.Policy(stack, "ssm-policy", {
statements: [
new iam.PolicyStatement({
actions: ["ssm:GetParameter"],
resources: [
`arn:aws:ssm:${stack.region}:${stack.account}:parameter/sst/openapi-zod-api-gateway/marko/Parameter/REST_API/value`,
],
}),
],
})
);
stack.addOutputs({
HttpApi: httpApi.url,
RestApi: restApiUrl,
});
}