Another rework
This commit is contained in:
@@ -1,13 +0,0 @@
|
|||||||
import { defineBackend } from '@aws-amplify/backend'
|
|
||||||
import { goFunction } from './functions/go/resource.ts'
|
|
||||||
import { pythonFunction } from './functions/python/resource.ts'
|
|
||||||
import { rustFunction } from './functions/rust/resource.ts'
|
|
||||||
|
|
||||||
defineBackend({
|
|
||||||
goFunction,
|
|
||||||
pythonFunction,
|
|
||||||
rustFunction
|
|
||||||
})
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -1,9 +0,0 @@
|
|||||||
import { defineFunction } from '@aws-amplify/backend'
|
|
||||||
|
|
||||||
export const goFunction = defineFunction({
|
|
||||||
name: 'go-functions',
|
|
||||||
entry: '../../../functions/go-functions/main.go', // ← Points to your Go file
|
|
||||||
runtime: 'provided.al2023' // ← Custom runtime for Go
|
|
||||||
})
|
|
||||||
|
|
||||||
|
|
||||||
@@ -1,8 +0,0 @@
|
|||||||
import { defineFunction } from '@aws-amplify/backend'
|
|
||||||
|
|
||||||
export const pythonFunction = defineFunction({
|
|
||||||
name: 'python-function',
|
|
||||||
entry: '../../../functions/python-function/handler.py', // ← Points to external folder
|
|
||||||
runtime: 'python3.12'
|
|
||||||
})
|
|
||||||
|
|
||||||
@@ -1,8 +0,0 @@
|
|||||||
import { defineFunction } from '@aws-amplify/backend'
|
|
||||||
|
|
||||||
export const rustFunction = defineFunction({
|
|
||||||
name: 'rust-function',
|
|
||||||
entry: '../../../functions/rust-function/src/main.rs', // ← Points to external folder
|
|
||||||
runtime: 'provided.al2'
|
|
||||||
})
|
|
||||||
|
|
||||||
@@ -0,0 +1,190 @@
|
|||||||
|
// infrastructure/api-gateway-stack.ts
|
||||||
|
import { Stack, StackProps, CfnOutput } from 'aws-cdk-lib'
|
||||||
|
import { Construct } from 'constructs'
|
||||||
|
import * as apigateway from 'aws-cdk-lib/aws-apigateway'
|
||||||
|
import * as lambda from 'aws-cdk-lib/aws-lambda'
|
||||||
|
import * as logs from 'aws-cdk-lib/aws-logs'
|
||||||
|
import * as iam from 'aws-cdk-lib/aws-iam'
|
||||||
|
|
||||||
|
export interface ApiGatewayStackProps extends StackProps {
|
||||||
|
// Reference to your Lambda functions from another stack
|
||||||
|
goFunction: lambda.Function
|
||||||
|
pythonFunction: lambda.Function
|
||||||
|
rustFunction: lambda.Function
|
||||||
|
}
|
||||||
|
|
||||||
|
export class ApiGatewayStack extends Stack {
|
||||||
|
public readonly api: apigateway.RestApi
|
||||||
|
public readonly apiUrl: string
|
||||||
|
|
||||||
|
constructor(scope: Construct, id: string, props: ApiGatewayStackProps) {
|
||||||
|
super(scope, id, props)
|
||||||
|
|
||||||
|
// Create CloudWatch Log Group for API Gateway
|
||||||
|
const logGroup = new logs.LogGroup(this, 'ApiGatewayLogGroup', {
|
||||||
|
logGroupName: `/aws/apigateway/${id}`,
|
||||||
|
retention: logs.RetentionDays.ONE_WEEK,
|
||||||
|
})
|
||||||
|
|
||||||
|
// Create API Gateway
|
||||||
|
this.api = new apigateway.RestApi(this, 'MyApi', {
|
||||||
|
restApiName: 'My Multi-Language API',
|
||||||
|
description: 'API Gateway for Go, Python, and Rust Lambda functions',
|
||||||
|
|
||||||
|
// Enable CORS for frontend integration
|
||||||
|
defaultCorsPreflightOptions: {
|
||||||
|
allowOrigins: [
|
||||||
|
'http://localhost:3000', // Local development
|
||||||
|
'https://your-amplify-domain.amplifyapp.com', // Your Amplify domain
|
||||||
|
],
|
||||||
|
allowMethods: ['GET', 'POST', 'PUT', 'DELETE', 'OPTIONS'],
|
||||||
|
allowHeaders: [
|
||||||
|
'Content-Type',
|
||||||
|
'X-Amz-Date',
|
||||||
|
'Authorization',
|
||||||
|
'X-Api-Key',
|
||||||
|
'X-Amz-Security-Token',
|
||||||
|
],
|
||||||
|
},
|
||||||
|
|
||||||
|
// Deploy automatically
|
||||||
|
deploy: true,
|
||||||
|
deployOptions: {
|
||||||
|
stageName: 'prod',
|
||||||
|
loggingLevel: apigateway.MethodLoggingLevel.INFO,
|
||||||
|
dataTraceEnabled: true,
|
||||||
|
metricsEnabled: true,
|
||||||
|
accessLogDestination: new apigateway.LogGroupLogDestination(logGroup),
|
||||||
|
accessLogFormat: apigateway.AccessLogFormat.jsonWithStandardFields(),
|
||||||
|
},
|
||||||
|
|
||||||
|
// Enable endpoint configuration
|
||||||
|
endpointConfiguration: {
|
||||||
|
types: [apigateway.EndpointType.REGIONAL],
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
// Create API resources and methods
|
||||||
|
this.createGoEndpoints(props.goFunction)
|
||||||
|
this.createPythonEndpoints(props.pythonFunction)
|
||||||
|
this.createRustEndpoints(props.rustFunction)
|
||||||
|
|
||||||
|
// Add a health check endpoint
|
||||||
|
this.createHealthEndpoint()
|
||||||
|
|
||||||
|
// Store API URL for output
|
||||||
|
this.apiUrl = this.api.url
|
||||||
|
|
||||||
|
// Output the API URL
|
||||||
|
new CfnOutput(this, 'ApiUrl', {
|
||||||
|
value: this.apiUrl,
|
||||||
|
description: 'API Gateway URL',
|
||||||
|
exportName: `${this.stackName}-ApiUrl`,
|
||||||
|
})
|
||||||
|
|
||||||
|
// Output individual endpoint URLs
|
||||||
|
new CfnOutput(this, 'GoEndpoint', {
|
||||||
|
value: `${this.apiUrl}go`,
|
||||||
|
description: 'Go Lambda endpoint',
|
||||||
|
})
|
||||||
|
|
||||||
|
new CfnOutput(this, 'PythonEndpoint', {
|
||||||
|
value: `${this.apiUrl}python`,
|
||||||
|
description: 'Python Lambda endpoint',
|
||||||
|
})
|
||||||
|
|
||||||
|
new CfnOutput(this, 'RustEndpoint', {
|
||||||
|
value: `${this.apiUrl}rust`,
|
||||||
|
description: 'Rust Lambda endpoint',
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
private createGoEndpoints(goFunction: lambda.Function) {
|
||||||
|
// Create /go resource
|
||||||
|
const goResource = this.api.root.addResource('go')
|
||||||
|
|
||||||
|
// Create Lambda integration
|
||||||
|
const goIntegration = new apigateway.LambdaIntegration(goFunction, {
|
||||||
|
requestTemplates: { 'application/json': '{ "statusCode": "200" }' },
|
||||||
|
proxy: true, // Enable Lambda proxy integration
|
||||||
|
})
|
||||||
|
|
||||||
|
// Add methods
|
||||||
|
goResource.addMethod('GET', goIntegration)
|
||||||
|
goResource.addMethod('POST', goIntegration)
|
||||||
|
|
||||||
|
// Add sub-resources if needed
|
||||||
|
const goHealthResource = goResource.addResource('health')
|
||||||
|
goHealthResource.addMethod('GET', goIntegration)
|
||||||
|
}
|
||||||
|
|
||||||
|
private createPythonEndpoints(pythonFunction: lambda.Function) {
|
||||||
|
// Create /python resource
|
||||||
|
const pythonResource = this.api.root.addResource('python')
|
||||||
|
|
||||||
|
// Create Lambda integration
|
||||||
|
const pythonIntegration = new apigateway.LambdaIntegration(pythonFunction, {
|
||||||
|
proxy: true,
|
||||||
|
})
|
||||||
|
|
||||||
|
// Add methods
|
||||||
|
pythonResource.addMethod('GET', pythonIntegration)
|
||||||
|
pythonResource.addMethod('POST', pythonIntegration)
|
||||||
|
pythonResource.addMethod('PUT', pythonIntegration)
|
||||||
|
|
||||||
|
// Add sub-resources
|
||||||
|
const pythonDataResource = pythonResource.addResource('data')
|
||||||
|
pythonDataResource.addMethod('GET', pythonIntegration)
|
||||||
|
pythonDataResource.addMethod('POST', pythonIntegration)
|
||||||
|
}
|
||||||
|
|
||||||
|
private createRustEndpoints(rustFunction: lambda.Function) {
|
||||||
|
// Create /rust resource
|
||||||
|
const rustResource = this.api.root.addResource('rust')
|
||||||
|
|
||||||
|
// Create Lambda integration
|
||||||
|
const rustIntegration = new apigateway.LambdaIntegration(rustFunction, {
|
||||||
|
proxy: true,
|
||||||
|
})
|
||||||
|
|
||||||
|
// Add methods
|
||||||
|
rustResource.addMethod('GET', rustIntegration)
|
||||||
|
rustResource.addMethod('POST', rustIntegration)
|
||||||
|
rustResource.addMethod('DELETE', rustIntegration)
|
||||||
|
|
||||||
|
// Add sub-resources
|
||||||
|
const rustProcessResource = rustResource.addResource('process')
|
||||||
|
rustProcessResource.addMethod('POST', rustIntegration)
|
||||||
|
}
|
||||||
|
|
||||||
|
private createHealthEndpoint() {
|
||||||
|
// Create a simple health check endpoint
|
||||||
|
const healthResource = this.api.root.addResource('health')
|
||||||
|
|
||||||
|
// Mock integration for health check (no Lambda needed)
|
||||||
|
const healthIntegration = new apigateway.MockIntegration({
|
||||||
|
integrationResponses: [{
|
||||||
|
statusCode: '200',
|
||||||
|
responseTemplates: {
|
||||||
|
'application/json': JSON.stringify({
|
||||||
|
status: 'healthy',
|
||||||
|
timestamp: '$context.requestTime',
|
||||||
|
requestId: '$context.requestId'
|
||||||
|
})
|
||||||
|
},
|
||||||
|
}],
|
||||||
|
requestTemplates: {
|
||||||
|
'application/json': '{ "statusCode": 200 }'
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
healthResource.addMethod('GET', healthIntegration, {
|
||||||
|
methodResponses: [{
|
||||||
|
statusCode: '200',
|
||||||
|
responseModels: {
|
||||||
|
'application/json': apigateway.Model.EMPTY_MODEL,
|
||||||
|
},
|
||||||
|
}],
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,28 @@
|
|||||||
|
// infrastructure/app.ts
|
||||||
|
import * as cdk from 'aws-cdk-lib'
|
||||||
|
import { LambdaStack } from './lambda-stack'
|
||||||
|
import { ApiGatewayStack } from './api-gateway-stack'
|
||||||
|
|
||||||
|
const app = new cdk.App()
|
||||||
|
|
||||||
|
// Create Lambda functions first
|
||||||
|
const lambdaStack = new LambdaStack(app, 'LambdaStack', {
|
||||||
|
env: {
|
||||||
|
account: process.env.CDK_DEFAULT_ACCOUNT,
|
||||||
|
region: process.env.CDK_DEFAULT_REGION,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
// Create API Gateway and connect to Lambda functions
|
||||||
|
const apiStack = new ApiGatewayStack(app, 'ApiGatewayStack', {
|
||||||
|
goFunction: lambdaStack.goFunction,
|
||||||
|
pythonFunction: lambdaStack.pythonFunction,
|
||||||
|
rustFunction: lambdaStack.rustFunction,
|
||||||
|
env: {
|
||||||
|
account: process.env.CDK_DEFAULT_ACCOUNT,
|
||||||
|
region: process.env.CDK_DEFAULT_REGION,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
// Ensure Lambda stack is deployed before API Gateway
|
||||||
|
apiStack.addDependency(lambdaStack)
|
||||||
@@ -0,0 +1,42 @@
|
|||||||
|
// infrastructure/lambda-stack.ts
|
||||||
|
import { Stack, StackProps, Duration } from 'aws-cdk-lib'
|
||||||
|
import { Construct } from 'constructs'
|
||||||
|
import * as lambda from 'aws-cdk-lib/aws-lambda'
|
||||||
|
|
||||||
|
export class LambdaStack extends Stack {
|
||||||
|
public readonly goFunction: lambda.Function
|
||||||
|
public readonly pythonFunction: lambda.Function
|
||||||
|
public readonly rustFunction: lambda.Function
|
||||||
|
|
||||||
|
constructor(scope: Construct, id: string, props?: StackProps) {
|
||||||
|
super(scope, id, props)
|
||||||
|
|
||||||
|
// Go function
|
||||||
|
this.goFunction = new lambda.Function(this, 'GoFunction', {
|
||||||
|
runtime: lambda.Runtime.PROVIDED_AL2023,
|
||||||
|
handler: 'bootstrap',
|
||||||
|
code: lambda.Code.fromAsset('../functions/go-functions'),
|
||||||
|
timeout: Duration.minutes(15),
|
||||||
|
memorySize: 1024,
|
||||||
|
})
|
||||||
|
|
||||||
|
// Python function
|
||||||
|
this.pythonFunction = new lambda.Function(this, 'PythonFunction', {
|
||||||
|
runtime: lambda.Runtime.PYTHON_3_12,
|
||||||
|
handler: 'handler.handler',
|
||||||
|
code: lambda.Code.fromAsset('../functions/python-function'),
|
||||||
|
timeout: Duration.minutes(5),
|
||||||
|
memorySize: 512,
|
||||||
|
})
|
||||||
|
|
||||||
|
// Rust function
|
||||||
|
this.rustFunction = new lambda.Function(this, 'RustFunction', {
|
||||||
|
runtime: lambda.Runtime.PROVIDED_AL2023,
|
||||||
|
handler: 'bootstrap',
|
||||||
|
code: lambda.Code.fromAsset('../functions/rust-function'),
|
||||||
|
timeout: Duration.minutes(10),
|
||||||
|
memorySize: 2048,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
+17
@@ -0,0 +1,17 @@
|
|||||||
|
// In your frontend
|
||||||
|
const API_BASE_URL = 'https://your-api-id.execute-api.region.amazonaws.com/prod'
|
||||||
|
|
||||||
|
// Call Go function
|
||||||
|
const goResponse = await fetch(`${API_BASE_URL}/go/health`)
|
||||||
|
|
||||||
|
// Call Python function
|
||||||
|
const pythonResponse = await fetch(`${API_BASE_URL}/python/data`, {
|
||||||
|
method: 'POST',
|
||||||
|
body: JSON.stringify({ data: 'example' })
|
||||||
|
})
|
||||||
|
|
||||||
|
// Call Rust function
|
||||||
|
const rustResponse = await fetch(`${API_BASE_URL}/rust/process`, {
|
||||||
|
method: 'POST',
|
||||||
|
body: JSON.stringify({ input: 'process this' })
|
||||||
|
})
|
||||||
@@ -1,2 +0,0 @@
|
|||||||
def test_placeholder():
|
|
||||||
assert True
|
|
||||||
@@ -1,3 +0,0 @@
|
|||||||
pytest>=8.0.0
|
|
||||||
requests>=2.31.0
|
|
||||||
httpx>=0.27.0
|
|
||||||
Reference in New Issue
Block a user