14 Commits

Author SHA1 Message Date
Sébastien Stormacq bd7d9ee38a Add ResourcesPackaging README and update dependencies (#669)
Two small housekeeping changes:

- Added a README for the ResourcesPackaging example explaining how to
use Swift package resources with Lambda.
- Updated dependency versions in Package.swift to avoid CI errors on
current toolchains.
2026-05-14 12:20:34 +02:00
Sébastien Stormacq 3ddd64087d Add Streaming Lambda Examples with API Gateway and Function URL (#615)
## Overview

This PR reorganizes and enhances the streaming Lambda examples by
splitting them into two distinct examples that demonstrate different
invocation methods:

1. **Streaming+FunctionUrl** - Streaming responses via Lambda Function
URLs
2. **Streaming+APIGateway** - Streaming responses via API Gateway REST
API

## Changes

### 🔄 Restructured Examples

- **Renamed**: `Examples/Streaming/` → `Examples/Streaming+FunctionUrl/`
  - Maintains the original streaming example using Lambda Function URLs
  - Updated documentation to clarify Function URL-specific configuration
  - Improved AWS credentials handling in curl examples

- **New**: `Examples/Streaming+APIGateway/`
- Comprehensive example demonstrating API Gateway REST API with response
streaming
- Complete SAM template with proper IAM roles and streaming
configuration
  - Detailed documentation covering API Gateway-specific setup

### 📚 Documentation Improvements

#### Streaming+FunctionUrl
- Clarified that this example uses Lambda Function URLs
- Updated curl examples to use `eval $(aws configure export-credentials
--format env)` for cleaner credential handling
- Maintained all existing functionality and deployment instructions

#### Streaming+APIGateway (New)
- **316-line comprehensive README** covering:
  - Response streaming concepts and benefits
  - HTTP status code and header configuration
  - Streaming response body patterns
  - Local testing instructions
  - Complete SAM deployment guide with detailed template explanation
  - API Gateway-specific invocation with AWS Sigv4 authentication
  - Payload format documentation with example JSON
  - Security and reliability best practices
  - How API Gateway streaming works under the hood

### 🛠️ Technical Details

#### API Gateway Streaming Configuration
The new example demonstrates:
- Special Lambda URI: `/response-streaming-invocations` endpoint
- `responseTransferMode: STREAM` configuration
- IAM role with both `lambda:InvokeFunction` and
`lambda:InvokeWithResponseStream` permissions
- Proper timeout configuration (60s) to accommodate streaming duration

#### SAM Template Features
```yaml
- Lambda function with streaming support (arm64, provided.al2)
- API Gateway REST API with OpenAPI 3.0 definition
- IAM execution role for API Gateway to invoke Lambda with streaming
- Complete outputs for easy testing (API URL and Lambda ARN)
```

### 🔐 Security Enhancements

Both examples now include comprehensive security best practices:
- API Gateway access logging
- Throttling configuration
- AWS WAF integration recommendations
- Lambda concurrent execution limits
- Environment variable encryption
- Dead Letter Queue (DLQ) configuration
- VPC configuration guidance

### 🧪 Testing

Both examples support:
- **Local testing**: `swift run` with curl invocation on port 7000
- **AWS deployment**: Complete SAM templates with deployment
instructions
- **Authenticated invocation**: AWS Sigv4 examples with proper
credential handling

## Benefits

1. **Clearer separation**: Developers can now easily choose between
Function URLs and API Gateway based on their use case
2. **Better documentation**: Each example has tailored documentation for
its specific invocation method
3. **Production-ready**: Includes security best practices and proper IAM
configuration
4. **Easier testing**: Improved credential handling in curl examples

## Breaking Changes

None - this is purely additive. The original streaming example is
preserved as `Streaming+FunctionUrl`.

## Testing Checklist

- [x] Local testing works for both examples
- [x] SAM deployment templates are valid
- [x] Documentation is comprehensive and accurate
- [x] Security best practices are documented
- [x] Curl examples work with proper authentication

## Related Documentation

- [AWS Lambda Response
Streaming](https://docs.aws.amazon.com/lambda/latest/dg/configuration-response-streaming.html)
- [API Gateway Lambda Proxy Integration with
Streaming](https://docs.aws.amazon.com/apigateway/latest/developerguide/response-streaming-lambda-configure.html)
- [Lambda Function
URLs](https://docs.aws.amazon.com/lambda/latest/dg/lambda-urls.html)
EOF

---------

Co-authored-by: Sebastien Stormacq <stormacq@amazon.lu>
2025-12-05 16:38:50 -08:00
Sébastien Stormacq dee635267b change references from /swift-server to /awslabs (#591)
Change Examples, README, and doc to refer to https://github.org/awslabs
instead of https://github.org/swift-server

---------

Co-authored-by: Sebastien Stormacq <stormacq@amazon.lu>
2025-10-17 16:46:58 +02:00
Sébastien Stormacq 8cfd36a30d Rename APIGateway example to APIGatewayV2 (#575)
Now that we have an APIGatewayV1 example, rename the existing APIGateway
examples to APIGatewayV2.

Fix https://github.com/transfer-aws/swift-aws-lambda-runtime/issues/572
2025-09-29 10:37:30 +02:00
Sébastien Stormacq 74e4efdbac Apply recommendation for security and reliability (#573)
Apply recommendations in code and documentation

- [CI] restrict permissions to read-all instead of the default write-all
- All examples README.md : add a note about Lambda functions
configuration with improved security and scalability changes for
production environment
- Swift docc documentation: add a note about Lambda functions
configuration with improved security and scalability changes for
production environment

---------

Co-authored-by: Sebastien Stormacq <stormacq@amazon.lu>
2025-09-27 12:39:16 +02:00
Sébastien Stormacq 262c3b539a Revert streaming codable handler and provide it as an example, not an API (#549)
Revert streaming codable handler change and propose it as an example
instead of an handler API.

**Motivation:**
I made a mistake when submitting this PR 
https://github.com/swift-server/swift-aws-lambda-runtime/pull/532

It provides a Streaming+Codable handler that conveniently allows
developers to write handlers with `Codable` events for streaming
functions.

This is a mistake for three reasons:

- This is the only handler that assumes a Lamba Event structure as
input. I added a minimal `FunctionUrlRequest` and `FunctionURLResponse`
to avoid importing the AWS Lambda Events library. It is the first
handler to be event-specific. I don't think the runtime should introduce
event specific code.

- The handler only works when Lambda functions are exposed through
Function URLs. Streaming functions can also be invoke by API or CLI.

- The handler hides `FunctionURLRequest` details (HTTP headers, query
parameters, etc.) from developers

Developers were unaware they were trading flexibility for convenience

The lack of clear documentation about these limitations led to incorrect
usage patterns and frustrated developers who needed full request control
or were using other invocation methods.

**Modifications:**
- Removed the Streaming+Codable API from the library
- Moved the Streaming+Codable code to an example
- Added prominent warning section in the example README explaining the
limitations
- Clarified when to use Streaming+Codable vs ByteBuffer approaches
- Added decision rule framework to help developers choose the right
approach

**Result:**
The only API provided by the library to use Streaming Lambda functions
is exposing the raw `ByteBuffer` as input, there is no more `Codable`
handler for Streaming functions available in the API. I kept the
`Streaming+Codable` code an example.

After this change, developers have clear guidance on when to use each
streaming approach:

- Use streaming codable for Function URL + JSON payload + no request
details needed
- Use ByteBuffer StreamingLambdaHandler for full control, other
invocation methods, or request metadata access

This prevents misuse of the API and sets proper expectations about the
handler's capabilities and limitations, leading to better developer
experience and fewer integration issues.
2025-08-07 10:51:21 +02:00
Sébastien Stormacq a5ff8e5c00 Add hummingbird Lambda example (#544)
Add Hummingbird web framework integration example for AWS Lambda

**Motivation:**
Developers using the Hummingbird web framework need a clear example of
how to integrate it with AWS Lambda. The existing examples focus on
basic Lambda handlers, but don't demonstrate how to use popular Swift
web frameworks like Hummingbird in a serverless context.

**Modifications:**
Added a complete Hummingbird Lambda example in Examples/Hummingbird/
including Package.swift with Hummingbird Lambda dependencies, main.swift
demonstrating router setup with API Gateway V2 integration, SAM template
for deployment, and comprehensive README documentation with build,
deploy, and usage instructions.

**Result:**
Developers can now easily create AWS Lambda functions using the
Hummingbird web framework, with a working example that shows router
configuration, API Gateway integration, and complete deployment workflow
using familiar Hummingbird syntax.
2025-08-05 15:13:13 +02:00
Sébastien Stormacq 412a345bdd [core] Add user-facing API for Streaming Lambda functions that receive JSON events (#532)
Add user-facing API for Streaming Lambda functions that receives JSON
events

### Motivation:

Streaming Lambda functions developed by developers had no choice but to
implement a handler that receives incoming data as a `ByteBuffer`. While
this is useful for low-level development, I assume most developers will
want to receive a JSON event to trigger their streaming Lambda function.

Going efficiently from a `ByteBuffer` to a Swift struct requires some
code implemented in the `JSON+ByteBuffer.swift` file of the librray. We
propose to further help developers by providing them with a new
`handler()` function that directly receives their `Decodable` type.

### Modifications:

This PR adds a public facing API (+ unit test + updated README) allowing
developers to write a handler method accepting any `Decodable` struct as
input.

```swift
import AWSLambdaRuntime
import NIOCore

// Define your input event structure
struct StreamingRequest: Decodable {
    let count: Int
    let message: String
    let delayMs: Int?
}

// Use the new streaming handler with JSON decoding
let runtime = LambdaRuntime { (event: StreamingRequest, responseWriter, context: LambdaContext) in
    context.logger.info("Received request to send \(event.count) messages")
    
    // Stream the messages
    for i in 1...event.count {
        let response = "Message \(i)/\(event.count): \(event.message)\n"
        try await responseWriter.write(ByteBuffer(string: response))
        
        // Optional delay between messages
        if let delay = event.delayMs, delay > 0 {
            try await Task.sleep(for: .milliseconds(delay))
        }
    }
    
    // Finish the stream
    try await responseWriter.finish()
    
    // Optional: Execute background work after response is sent
    context.logger.info("Background work: processing completed")
}

try await runtime.run()
```

This interface provides:
- **Type-safe JSON input**: Automatic decoding of JSON events into Swift
structs
- **Streaming responses**: Full control over when and how to stream data
back to clients
- **Background work support**: Ability to execute code after the
response stream is finished
- **Familiar API**: Uses the same closure-based pattern as regular
Lambda handlers

Because streaming Lambda functions can be invoked either directly
through the API or through Lambda Function URL, this PR adds the
decoding logic to support both types, shielding developers from working
with Function URL requests and base64 encoding.

We understand these choice will have an impact on the raw performance
for event handling. Those advanced users that want to get the maximum
might use the existing `handler(_ event: ByteBuffer, writer:
LambaStreamingWriter)` function to implement their own custom decoding
logic.

This PR provides a balance between ease of use for 80% of the users vs
ultimate performance, without closing the door for the 20% who need it.

### Result:

Lambda function developers can now use arbitrary `Decodable` Swift
struct or Lambda events to trigger their streaming functions. 🎉

---------

Co-authored-by: Tim Condon <0xTim@users.noreply.github.com>
2025-07-23 19:03:25 +04:00
Paul Toffoloni 0777c80172 Add S3EventNotifier example (#477)
Add `S3EventNotifier` example

### Motivation:

There is currently no example regarding an AWS event triggered lambda,
such as a lambda that gets invoked on an S3 object upload. I've had to
look for a while to figure out that the `AWSLambdaEvents` exists and
that it can be used for that (had to find out via a Java example! 😜) so
I think this could be useful and a somewhat common use case

### Modifications:

Added an example of a lambda that gets triggered when an object gets
uploaded to an S3 bucket.

I have not described how to set up the actual S3 event in AWS because I
figured if you needed such a lambda you'd know, but I can describe that
too in the README if needed

---------

Co-authored-by: Sébastien Stormacq <sebastien.stormacq@gmail.com>
2025-02-11 17:22:12 +01:00
Sébastien Stormacq 051029fc0f [examples] Add an example of an APIGateway Lambda Authorizer (#453)
Add an example of an APIGateway Lambda Authorizer

### Motivation:

Lambda Authorizers allow developers to write custom logic to validate
HTTP REST requests.
This example shows how to write a Lambda Authorizer in Swift and how to
configure an API Gateway to use a Lambda Authorizer.

This example use a SAM template to deploy the resources.

### Modifications:

- Add `Examples/APIGateway+LambdaAuthorizer` directory with the source
code, a `template.yaml`, and a `README` file.
- Add a reference to the new example in `Examples/README`
- Modify CI to build the new example 

### Result:

There is a new example showing how to develop a Lambda authorizer in
Swift and how to attach it to an APIGateway with SAM
2025-01-06 16:44:13 +01:00
Sébastien Stormacq cef85b9fe8 [examples] add an example project to show test strategies (#438)
This new example project show four testing strategies for Swift Lambda
function

- Unit testing the business logic (not specific to Swift Lambda) 
- Integration testing the handler method 
- Local invocation with the Swift Lambda Runtime 
- Local invocation with SAM 

**[IMPORTANT]**
To allow testing the handler, I had to change visibility of a method in
the Runtime project. This method is clearly marked for testing only, so
it should not be a problem. Happy to read feedback and discuss however.
2024-12-25 07:43:20 +01:00
Sébastien Stormacq 18660fcdd1 [examples] Add CDK deployment example (#431)
added an example showing how to deploy with the CDK
This code is the basis for the upcoming CDK section in the deployment
guide
2024-12-21 10:39:13 +01:00
Sébastien Stormacq c22f5271a0 add HelloJSON example + README (#424)
* add HelloJSON example + README

* multiple corrections of typos and grammatical errors

Co-authored-by: Tim Condon <0xTim@users.noreply.github.com>
2024-11-13 13:53:19 +01:00
Sébastien Stormacq 54fd25bdad Add example and README for a streaming Lambda function (#415)
* add streaming example and doc

* add streaming example to CI

* fix soundness

* remove unused files

* correct usage of zsh env var

* typo

Co-authored-by: Tim Condon <0xTim@users.noreply.github.com>

* typo

Co-authored-by: Tim Condon <0xTim@users.noreply.github.com>

* add comments

Co-authored-by: Tim Condon <0xTim@users.noreply.github.com>

* typo

Co-authored-by: Tim Condon <0xTim@users.noreply.github.com>

* add an example README with common sections + link to each example

---------

Co-authored-by: Tim Condon <0xTim@users.noreply.github.com>
2024-11-07 14:55:37 +01:00