| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
| Name | Name | Last commit date | ||
|---|---|---|---|---|
This library provides an AWS Lambda transport for Swift OpenAPI generator
This library allows you to expose server-side Swift OpenAPI implementations as AWS Lambda functions with minimal code changes.
The library provides:
We strongly recommend never deploying an openly available API. The QuoteAPI example project shows you how to add a Lambda Authorizer function to the API Gateway.
If you already have an OpenAPI definition, you already generated the server stubs, and wrote an implementation, here are the additional steps to expose your OpenAPI service implementation as a AWS Lambda function and an Amazon API Gateway HTTP API (aka APIGatewayV2).
To expose your OpenAPI implementation as an AWS Lambda function:
dependencies: [
.package(url: "https://github.com/apple/swift-openapi-generator.git", from: "1.4.0"),
.package(url: "https://github.com/apple/swift-openapi-runtime.git", from: "1.8.2"),
// add these three dependencies
.package(url: "https://github.com/awslabs/swift-aws-lambda-runtime.git", from: "2.0.0"),
.package(url: "https://github.com/awslabs/swift-aws-lambda-events.git", from: "1.2.0"),
.package(url: "https://github.com/awslabs/swift-openapi-lambda.git", from: "2.0.0"),
],
targets: [
.executableTarget(
name: "YourOpenAPIService",
dependencies: [
.product(name: "OpenAPIRuntime", package: "swift-openapi-runtime"),
// add these three products
.product(name: "AWSLambdaRuntime", package: "swift-aws-lambda-runtime"),
.product(name: "AWSLambdaEvents", package: "swift-aws-lambda-events"),
.product(name: "OpenAPILambda", package: "swift-openapi-lambda"),
]
)
]Add a protocol and a constructor to your existing OpenAPI service implementation
There are only five changes to make to your existing implementation:
import OpenAPIRuntime
import OpenAPILambda // <-- 1. import this library
@main // <-- 2. flag this struct as the executable target entrypoint
struct QuoteServiceImpl: APIProtocol, OpenAPILambdaHttpApi { // <-- 3. add the OpenAPILambdaHttpApi protocol
// The registration of your OpenAPI handlers
func register(transport: OpenAPILambdaTransport) throws { // <-- 4. add this method (calls registerHandlers)
try self.registerHandlers(on: transport)
}
// the entry point for your Lambda function
static func main() async throws { // <-- 5. add this entry point to start the lambdaRuntime
let openAPIService = QuoteServiceImpl()
try await openAPIService.run()
}
// Your existing OpenAPI implementation
func getQuote(_ input: Operations.getQuote.Input) async throws -> Operations.getQuote.Output {
let symbol = input.path.symbol
let price = Components.Schemas.quote(
symbol: symbol,
price: Double.random(in: 100..<150).rounded(),
change: Double.random(in: -5..<5).rounded(),
changePercent: Double.random(in: -0.05..<0.05),
volume: Double.random(in: 10000..<100000).rounded(),
timestamp: Date()
)
return .ok(.init(body: .json(price)))
}
}sam build && sam deploy --guidedSee the Examples/quoteapi directory for a complete working example that includes:
# Run locally with built-in development server
swift run QuoteService
# Test from another terminal
curl -H 'Authorization: Bearer 123' -X POST \
--data @events/GetQuote.json \
http://127.0.0.1:7000/invoke# Test deployed API (replace with your endpoint)
curl -H 'Authorization: Bearer 123' \
https://your-api-id.execute-api.region.amazonaws.com/stocks/AAPLNew AWS accounts get 1 million Lambda invocations and 1 million API Gateway requests free per month. After the free tier, costs are approximately $1.00 per million API calls.
sam deleteThe library supports Lambda authorizers for API protection. See Examples/quoteapi/Sources/LambdaAuthorizer for a complete implementation that validates a Bearer token.
let simpleAuthorizerHandler: (APIGatewayLambdaAuthorizerRequest, LambdaContext) async throws -> APIGatewayLambdaAuthorizerSimpleResponse = {
guard let authToken = $0.headers["authorization"],
authToken == "Bearer 123" else {
return .init(isAuthorized: false, context: [:])
}
return .init(isAuthorized: true, context: ["user": "authenticated"])
}To support other Lambda event types beyond API Gateway, implement the OpenAPILambda protocol:
@main
struct CustomServiceLambda: OpenAPILambda {
typealias Event = YourCustomEvent
typealias Output = YourCustomResponse
func register(transport: OpenAPILambdaTransport) throws {
let handler = YourServiceImpl()
try handler.registerHandlers(on: transport)
}
func request(context: LambdaContext, from event: Event) throws -> OpenAPILambdaRequest {
// Transform your event to HTTPRequest
}
func output(from response: OpenAPILambdaResponse) -> Output {
// Transform HTTPResponse to your output type
}
}import ServiceLifecycle
// In your OpenAPI service, explicitly create and manage the LambdaRuntime
static func main() async throws {
let lambdaRuntime = try LambdaRuntime(body: Self.handler())
let serviceGroup = ServiceGroup(
services: [lambdaRuntime],
gracefulShutdownSignals: [.sigterm],
cancellationSignals: [.sigint],
logger: Logger(label: "ServiceGroup")
)
try await serviceGroup.run()
}For advanced use cases requiring dependency injection:
@main
struct QuoteServiceImpl: APIProtocol, OpenAPILambdaHttpApi {
let customDependency: Int
init(customDependency: Int = 0) {
self.customDependency = customDependency
}
// the entry point can be in another file / struct as well.
static func main() async throws {
let service = QuoteServiceImpl(customDependency: 42)
let lambda = try OpenAPILambdaHandler(service: service)
let lambdaRuntime = LambdaRuntime(body: lambda.handler)
try await lambdaRuntime.run()
}
func register(transport: OpenAPILambdaTransport) throws {
try self.registerHandlers(on: transport)
}
}| Back | FazBrowse Home | New Git URL |