Skip to content

API Gateway example code not working #480

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
klsetzer opened this issue Feb 17, 2025 · 5 comments
Closed

API Gateway example code not working #480

klsetzer opened this issue Feb 17, 2025 · 5 comments
Assignees
Labels
kind/bug Feature doesn't work as expected.
Milestone

Comments

@klsetzer
Copy link

Expected behavior

Running curl against local API Gateway example from README.md, when running with swift run or running from Xcode

Expect the curl to return with an HTTP 200 response and a valid API Gateway response json

Actual behavior

  1. First curl request to the API at http://127.0.0.1:7000/invoke hangs (curl blocks)
  2. Error emitted in Xcode console (also on terminal, if using swift run
2025-02-17T14:16:29-0500 info LocalServer : host="127.0.0.1" port=7000 [AWSLambdaRuntimeCore] Server started and listening
2025-02-17T14:17:27-0500 error LocalServer : [AWSLambdaRuntimeCore] Hit error: CancellationError()
  1. Subsequent curl requests yield a 403 error.

Steps to reproduce

  1. Create Package.swift, main.swift per the example in this repo's README.md
  2. Run via Xcode or via swift run
  3. Run curl: curl --header 'Content-Type: application/json' --request POST --data @event2.json --verbose http://127.0.0.1:7000/invoke

NB: Deploying to AWS and curling against the created API gateway endpoint produces 502 errors with no application output visible in CloudWatch logs - although the lambda START/END/REPORT message appear.

If possible, minimal yet complete reproducer code (or URL to code)

Package.swift

// swift-tools-version:6.0
// The swift-tools-version declares the minimum version of Swift required to build this package.

import PackageDescription

let package = Package(
    name: "Palindrome",
    platforms: [
        .macOS(.v15)
    ],
    products: [
        .executable(name: "PalindromeLambda", targets: ["PalindromeLambda"])
    ],
    dependencies: [
        .package(
            url: "https://github.com/swift-server/swift-aws-lambda-runtime.git", branch: "main"),
        .package(url: "https://github.com/swift-server/swift-aws-lambda-events.git", from: "1.0.0"),
    ],
    targets: [
        .executableTarget(
            name: "PalindromeLambda",
            dependencies: [
                .product(name: "AWSLambdaRuntime", package: "swift-aws-lambda-runtime"),
                .product(name: "AWSLambdaEvents", package: "swift-aws-lambda-events"),
            ],
            path: "Sources"
        )
    ]
)

main.swift

import AWSLambdaEvents
import AWSLambdaRuntime

let runtime = LambdaRuntime {
    (event: APIGatewayV2Request, context: LambdaContext) -> APIGatewayV2Response in

    var header = HTTPHeaders()
    context.logger.debug("HTTP API Message received")

    header["content-type"] = "application/json"

    // echo the request in the response
    return try APIGatewayV2Response(statusCode: .ok, headers: header, encodableBody: event)
}

try await runtime.run()

What version of this project (swift-aws-lambda-runtime) are you using?

main

Swift version

swift-driver version: 1.115.1 Apple Swift version 6.0.3 (swiftlang-6.0.3.1.10 clang-1600.0.30.1)
Target: arm64-apple-macosx15.0
Darwin Mac-R4DKJYX9 24.1.0 Darwin Kernel Version 24.1.0: Thu Oct 10 21:03:15 PDT 2024; root:xnu-11215.41.3~2/RELEASE_ARM64_T6000 arm64

Amazon Linux 2 docker image version

No response

@sebsto
Copy link
Contributor

sebsto commented Feb 27, 2025

Thank you for having reported this.
This is probably fixed by #486

I will test on my side and report back

@sebsto sebsto self-assigned this Feb 27, 2025
@sebsto sebsto added the kind/bug Feature doesn't work as expected. label Feb 27, 2025
@sebsto sebsto added this to the 2.0 milestone Feb 27, 2025
@sebsto
Copy link
Contributor

sebsto commented Feb 27, 2025

This error is caused by a JSON fromat error when the Lambda runtime tries to decode the payload.
I can't access event2.json but I would bet it is not a valid API Gateway v2 payload.

You can find a valid payload example here https://docs.aws.amazon.com/apigateway/latest/developerguide/http-api-develop-integrations-lambda.html (copied below for convenience).

Can you test with this payload and report back ?
I will create a separate issue to track the error reporting in the Local Lambda Server

Deploying on the cloud works for me however.

{
  "version": "2.0",
  "routeKey": "$default",
  "rawPath": "/my/path",
  "rawQueryString": "parameter1=value1&parameter1=value2&parameter2=value",
  "cookies": [
    "cookie1",
    "cookie2"
  ],
  "headers": {
    "header1": "value1",
    "header2": "value1,value2"
  },
  "queryStringParameters": {
    "parameter1": "value1,value2",
    "parameter2": "value"
  },
  "requestContext": {
    "accountId": "123456789012",
    "apiId": "api-id",
    "authentication": {
      "clientCert": {
        "clientCertPem": "CERT_CONTENT",
        "subjectDN": "www.example.com",
        "issuerDN": "Example issuer",
        "serialNumber": "a1:a1:a1:a1:a1:a1:a1:a1:a1:a1:a1:a1:a1:a1:a1:a1",
        "validity": {
          "notBefore": "May 28 12:30:02 2019 GMT",
          "notAfter": "Aug  5 09:36:04 2021 GMT"
        }
      }
    },
    "authorizer": {
      "jwt": {
        "claims": {
          "claim1": "value1",
          "claim2": "value2"
        },
        "scopes": [
          "scope1",
          "scope2"
        ]
      }
    },
    "domainName": "id.execute-api.us-east-1.amazonaws.com",
    "domainPrefix": "id",
    "http": {
      "method": "POST",
      "path": "/my/path",
      "protocol": "HTTP/1.1",
      "sourceIp": "192.0.2.1",
      "userAgent": "agent"
    },
    "requestId": "id",
    "routeKey": "$default",
    "stage": "$default",
    "time": "12/Mar/2020:19:03:58 +0000",
    "timeEpoch": 1583348638390
  },
  "body": "Hello from Lambda",
  "pathParameters": {
    "parameter1": "value1"
  },
  "isBase64Encoded": false,
  "stageVariables": {
    "stageVariable1": "value1",
    "stageVariable2": "value2"
  }
}

@sebsto
Copy link
Contributor

sebsto commented Feb 27, 2025

See #488

@klsetzer
Copy link
Author

klsetzer commented Mar 3, 2025

Thank you so much! Looks like user (my!) error. The example payload you sent works when running locally with swift run and when deployed to AWS.

The event json I was sending was taken from somewhere in the AWS docs that I can no longer find. Here is the event json I was using that generated the [AWSLambdaRuntimeCore] Hit error: CancellationError() I originally reported.

{
    "version": "2.0",
    "routeKey": "ANY /nodejs-apig-function-1G3XMPLZXVXYI",
    "rawPath": "/default/nodejs-apig-function-1G3XMPLZXVXYI",
    "rawQueryString": "",
    "cookies": [
        "s_fid=7AABXMPL1AFD9BBF-0643XMPL09956DE2",
        "regStatus=pre-register"
    ],
    "headers": {
        "accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9",
        "accept-encoding": "gzip, deflate, br",
        "accept-language": "en-US,en;q=0.9",
        "content-length": "0",
        "host": "r3pmxmplak.execute-api.us-east-2.amazonaws.com",
        "sec-fetch-dest": "document",
        "sec-fetch-mode": "navigate",
        "sec-fetch-site": "cross-site",
        "sec-fetch-user": "?1",
        "upgrade-insecure-requests": "1",
        "user-agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.132 Safari/537.36",
        "x-amzn-trace-id": "Root=1-5e6722a7-cc56xmpl46db7ae02d4da47e",
        "x-forwarded-for": "205.255.255.176",
        "x-forwarded-port": "443",
        "x-forwarded-proto": "https"
    },
    "requestContext": {
        "accountId": "123456789012",
        "apiId": "r3pmxmplak",
        "domainName": "r3pmxmplak.execute-api.us-east-2.amazonaws.com",
        "domainPrefix": "r3pmxmplak",
        "http": {
            "method": "GET",
            "path": "/default/nodejs-apig-function-1G3XMPLZXVXYI",
            "protocol": "HTTP/1.1",
            "sourceIp": "205.255.255.176",
            "userAgent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.132 Safari/537.36"
        },
        "requestId": "JKJaXmPLvHcESHA=",
        "routeKey": "ANY /nodejs-apig-function-1G3XMPLZXVXYI",
        "stage": "default",
        "time": "10/Mar/2020:05:16:23 +0000",
        "timeEpoch": 1583817383220
    },
    "isBase64Encoded": true
}

@sebsto
Copy link
Contributor

sebsto commented Mar 4, 2025

It was not only a user error, the local server was not reporting the error correctly, leaving you in the dark.
Now, it reports the error that happened on the server side. In your case, it will be a KeyError indicating which key can not be decoded.

Closing this for now, feel free to reopen if your issue is not solved (be sure to force download the latest from the main branch)

@sebsto sebsto closed this as completed Mar 4, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
kind/bug Feature doesn't work as expected.
Projects
None yet
Development

No branches or pull requests

2 participants