1import * as Alchemy from "alchemy";
2import * as AWS from "alchemy/AWS";
3import * as Output from "alchemy/Output";
4import * as Effect from "effect/Effect";
5import JobFunction from "./src/JobFunction.ts";
6
7const aws = AWS.providers();
8
9export default Alchemy.Stack(
10 "AwsRestApiProxy",
11 {
12 providers: aws,
13 state: Alchemy.localState(),
14 },
15 Effect.gen(function* () {
16 const { region, accountId } = yield* AWS.AWSEnvironment.current;
17
18 const fn = yield* JobFunction;
19
20 const api = yield* AWS.ApiGateway.RestApi("PublicApi", {
21 name: "alchemy-example-rest-api",
22 endpointConfiguration: { types: ["REGIONAL"] },
23 });
24
25 const proxyResource = yield* AWS.ApiGateway.Resource("Proxy", {
26 restApiId: api.restApiId,
27 parentId: api.rootResourceId,
28 pathPart: "{proxy+}",
29 });
30
31 const invokeUri = Output.interpolate`arn:aws:apigateway:${region}:lambda:path/2015-03-31/functions/${fn.functionArn}/invocations`;
32
33 yield* AWS.ApiGateway.Method("RootAny", {
34 restApiId: api.restApiId,
35 resourceId: api.rootResourceId,
36 httpMethod: "ANY",
37 authorizationType: "NONE",
38 integration: {
39 type: "AWS_PROXY",
40 integrationHttpMethod: "POST",
41 uri: invokeUri,
42 },
43 });
44
45 yield* AWS.ApiGateway.Method("ProxyAny", {
46 restApiId: api.restApiId,
47 resourceId: proxyResource.resourceId,
48 httpMethod: "ANY",
49 authorizationType: "NONE",
50 integration: {
51 type: "AWS_PROXY",
52 integrationHttpMethod: "POST",
53 uri: invokeUri,
54 },
55 });
56
57 const deployment = yield* AWS.ApiGateway.Deployment("Release", {
58 restApiId: api.restApiId,
59 description: "initial",
60 triggers: {
61 rootMethod: "ANY",
62 proxyMethod: "ANY",
63 },
64 });
65
66 const stage = yield* AWS.ApiGateway.Stage("ProdStage", {
67 restApiId: api.restApiId,
68 stageName: "prod",
69 deploymentId: deployment.deploymentId,
70 });
71
72 yield* AWS.Lambda.Permission("ApiGatewayInvoke", {
73 action: "lambda:InvokeFunction",
74 functionName: fn.functionName,
75 principal: "apigateway.amazonaws.com",
76 sourceArn: Output.interpolate`arn:aws:execute-api:${region}:${accountId}:${api.restApiId}/*/*/*`,
77 });
78
79 return {
80 invokeUrl: Output.interpolate`https://${api.restApiId}.execute-api.${region}.amazonaws.com/${stage.stageName}/`,
81 restApiId: api.restApiId,
82 };
83 }),
84);