Skip to content

2.0.0-beta.1

Pre-release
Pre-release
Compare
Choose a tag to compare
@sebsto sebsto released this 30 Jul 15:12
· 5 commits to main since this release
0a6af5b

Swift AWS Lambda Runtime v2 Release Notes

Beta Release History

  • v2.0.0-beta.1: initial v2 beta. Please provide feedback about bugs, general usability, documentation, or example code. In case of a problem, please share a pull request, or open an issue.

Overview

Swift AWS Lambda Runtime v2 introduces a complete redesign of the API with async/await-first architecture, response streaming support, background task execution, and seamless integration with Swift Service Lifecycle. This release prioritizes developer experience, and structured concurrency.

🚀 v2 - Major New Features

Complete Swift 6 Concurrency Integration

  • Full async/await support throughout the entire API surface
  • Structured concurrency with proper task management and cancellation
  • Swift 6 compatibility with complete concurrency checking
  • Non-blocking I/O foundation built on SwiftNIO for optimal performance
  • Own the main() function for complete control over initialization
// Clean async/await API 
let runtime = LambdaRuntime { (event: Input, context: LambdaContext) async throws -> Output in
    let result = try await someAsyncOperation()
    return Output(data: result)
}

try await runtime.run()

Response Streaming Support

  • Stream large responses incrementally to improve time-to-first-byte (TTFB) performance
  • 20MB soft limit for streamed responses vs 6MB for buffered responses
  • Reduced memory usage for large responses
  • Support for custom HTTP status codes and headers in the streamed response
let runtime = LambdaRuntime { (event: StreamingRequest, responseWriter, context: LambdaContext) in
    for i in 1...10 {
        try await responseWriter.write(ByteBuffer(string: "Message \(i)\n"))
        try await Task.sleep(for: .milliseconds(500))
    }
    try await responseWriter.finish()
}

Background Task Execution

  • Execute code after returning response without affecting response latency
  • Structured concurrency approach following Swift best practices
let runtime = LambdaRuntime { (event: Input, outputWriter: some LambdaResponseWriter<Output>, context: LambdaContext) in
    // Return response immediately
    try await output.write(Greeting(message: event.message))
    
    // Execute background work
    try await performAnalytics(event)
    try await updateCache()
}

Swift Service Lifecycle Integration

  • Structured dependency with ServiceGroup
  • Graceful shutdown handling with proper resource cleanup
  • Eliminate LambdaTerminator complexity
let postgresClient = PostgresClient()
let runtime = LambdaRuntime { (event: Input, context: LambdaContext) in
    try await postgresClient.query("SELECT * FROM users")
}

let serviceGroup = ServiceGroup(
    services: [postgresClient, runtime],
    configuration: .init(gracefulShutdownSignals: [.sigterm])
)
try await serviceGroup.run()

🔄 API Changes

  • Only supports Swift 6.0 or more recent

New Handler Protocols

StreamingLambdaHandler (Base Protocol)

  • Handles raw ByteBuffer input/output
  • Full control over response streaming
  • Support for background task execution

LambdaHandler (Simplified)

  • Generic Event and Output types
  • Automatic JSON encoding/decoding
  • Clean handle(event, context) -> Output signature

LambdaWithBackgroundProcessingHandler

  • Combines type safety with background task support
  • Uses LambdaResponseWriter for structured response handling

Closure-Based API

// Simple JSON in/out
let runtime = LambdaRuntime { (event: HelloRequest, context: LambdaContext) in
    HelloResponse(greetings: "Hello \(event.name)")
}

// Streaming with JSON input
let runtime = LambdaRuntime { (event: StreamingRequest, responseWriter, context: LambdaContext) in
    // Stream response while maintaining type safety
}

Simplified Local Testing

  • Automatic local server when AWS_LAMBDA_RUNTIME_API is not set
  • No environment variables required for local development
  • Port 7000 for local invocations on /invoke (configurable via LOCAL_LAMBDA_SERVER_INVOCATION_ENDPOINT)

🛠 Breaking Changes

Removed APIs

  • LambdaTerminator (replaced by ServiceLifecycle)
  • EventLoop interfaces (replaced by async/await)
  • ByteBufferAllocator from LambdaContext
  • Protocol-based @main implementations

Migration Path

  1. Replace protocol conformance with closure-based handlers or create your own handler function.
  2. Update to async/await throughout your codebase
  3. Use ServiceGroup for dependency management, if needed
  4. Use Swift 6.x

📦 Enhanced Codable Support

Generic Adapters

  • LambdaCodableAdapter: Wraps any handler with encoding/decoding
  • LambdaHandlerAdapter: Adapts simple handlers for background processing
  • Custom encoders/decoders: Support for any format beyond JSON

Protocol-Based Encoding

public protocol LambdaEventDecoder {
    func decode<Event: Decodable>(_ type: Event.Type, from buffer: ByteBuffer) throws -> Event
}

public protocol LambdaOutputEncoder {
    func encode<Output: Encodable>(_ value: Output, into buffer: inout ByteBuffer) throws
}

🧪 Examples and Documentation

New Examples

  • ServiceLifecycle + PostgreSQL: Complete database integration example, with Swift Service Lifecycle
  • Streaming responses: Multiple streaming patterns
  • Background tasks: Post-response processing examples
  • API Gateway integration: HTTP API with Lambda
  • Security best practices implementations
  • and more...

Comprehensive Documentation

  • A quick start guide.
  • A deployment guide covering deployment with the AWS Console, the AWS Command Line Interface (CLI), the Simple Application Model (SAM) and the Cloud Development Kit (CDK).
  • A tutorial with step by step instructions

📋 Requirements

  • Swift 6.x toolchain
  • macOS 15 (Sequoia) or later for development on macOS.
  • Docker for building Lambda functions
  • AWS CLI configured with appropriate permissions

🚧 Beta Limitations

  • API may change based on community feedback
  • Documentation in progress for advanced use cases

🔄 Migration Guide

From v1 to v2

  1. Update Package.swift to use v2.0.0-beta.1 version
  2. Replace handler protocols with closure-based approach
  3. Integrate ServiceLifecycle for dependency management, if needed
  4. Test thoroughly with new local server

Compatibility

  • v1 and v2 can coexist in different projects
  • No automatic migration - manual code changes required

🤝 Community Feedback

This beta release incorporates extensive community feedback from the Swift forums discussion. We encourage continued feedback on:

  • API ergonomics and developer experience
  • Performance characteristics
  • Integration patterns with other Swift libraries
  • Documentation clarity and completeness

📚 Resources

New Contributors

Full Changelog: 1.0.0-alpha.3...2.0.0-beta.1

Note: This is a beta release intended for testing and feedback. Production use should carefully evaluate stability and performance characteristics.