Files
swift-aws-lambda-runtime/Examples/MultiSourceAPI/Sources/main.swift
T
Sébastien Stormacq 97583a78c2 Add Multi-Source API Example (#598)
This PR adds a new example demonstrating how to build a Lambda function
that handles requests from multiple sources (Application Load Balancer
and API Gateway V2) using a single handler.

### What's New

**New Example: `Examples/MultiSourceAPI`**

A Lambda function that:
- Implements `StreamingLambdaHandler` to accept raw `ByteBuffer` events
- Dynamically decodes events as either `ALBTargetGroupRequest` or
`APIGatewayV2Request`
- Returns appropriate responses based on the detected event source
- Demonstrates handling multiple AWS service integrations with a single
function

### Key Features

- **Type-safe event detection**: Uses Swift's `Decodable` to identify
the event source at runtime
- **Streaming response**: Implements `StreamingLambdaHandler` for
efficient response handling
- **Complete deployment**: Includes SAM template with both ALB and API
Gateway V2 infrastructure
- **Production-ready**: Full VPC setup with subnets, security groups,
and load balancer configuration

### Files Added

- `Examples/MultiSourceAPI/Sources/main.swift` - Lambda handler
implementation
- `Examples/MultiSourceAPI/Package.swift` - Swift package configuration
- `Examples/MultiSourceAPI/template.yaml` - SAM deployment template with
ALB and API Gateway V2
- `Examples/MultiSourceAPI/README.md` - Documentation with build,
deploy, and test instructions
- Updated CI to include the new example

### Use Case

This pattern is useful when you want to:
- Expose the same Lambda function through multiple AWS services
- Reduce code duplication by handling similar requests from different
sources
- Maintain a single codebase for multi-channel APIs

---------

Co-authored-by: Sebastien Stormacq <stormacq@amazon.lu>
Co-authored-by: Josh Elkins <jbelkins@users.noreply.github.com>
2025-11-02 21:58:02 +01:00

81 lines
2.7 KiB
Swift

//===----------------------------------------------------------------------===//
//
// This source file is part of the SwiftAWSLambdaRuntime open source project
//
// Copyright SwiftAWSLambdaRuntime project authors
// Copyright (c) Amazon.com, Inc. or its affiliates.
// Licensed under Apache License v2.0
//
// See LICENSE.txt for license information
// See CONTRIBUTORS.txt for the list of SwiftAWSLambdaRuntime project authors
//
// SPDX-License-Identifier: Apache-2.0
//
//===----------------------------------------------------------------------===//
import AWSLambdaEvents
import AWSLambdaRuntime
import NIOCore
#if canImport(FoundationEssentials)
import FoundationEssentials
#else
import Foundation
#endif
struct MultiSourceHandler: StreamingLambdaHandler {
func handle(
_ event: ByteBuffer,
responseWriter: some LambdaResponseStreamWriter,
context: LambdaContext
) async throws {
let decoder = JSONDecoder()
let data = Data(event.readableBytesView)
// Try to decode as ALBTargetGroupRequest first
if let albRequest = try? decoder.decode(ALBTargetGroupRequest.self, from: data) {
context.logger.info("Received ALB request to path: \(albRequest.path)")
let response = ALBTargetGroupResponse(
statusCode: .ok,
headers: ["Content-Type": "application/json"],
body: "{\"source\":\"ALB\",\"path\":\"\(albRequest.path)\"}"
)
let encoder = JSONEncoder()
let responseData = try encoder.encode(response)
try await responseWriter.write(ByteBuffer(bytes: responseData))
try await responseWriter.finish()
return
}
// Try to decode as APIGatewayV2Request
if let apiGwRequest = try? decoder.decode(APIGatewayV2Request.self, from: data) {
context.logger.info("Received API Gateway V2 request to path: \(apiGwRequest.rawPath)")
let response = APIGatewayV2Response(
statusCode: .ok,
headers: ["Content-Type": "application/json"],
body: "{\"source\":\"APIGatewayV2\",\"path\":\"\(apiGwRequest.rawPath)\"}"
)
let encoder = JSONEncoder()
let responseData = try encoder.encode(response)
try await responseWriter.write(ByteBuffer(bytes: responseData))
try await responseWriter.finish()
return
}
// Unknown event type
context.logger.error("Unable to decode event as ALB or API Gateway V2 request")
throw LambdaError.invalidEvent
}
}
enum LambdaError: Error {
case invalidEvent
}
let runtime = LambdaRuntime(handler: MultiSourceHandler())
try await runtime.run()