
This post is for whom want to use AWS Lambda with OpenAPI Generator. Official guide is useful but I felt there are some missing information. So I wrote this post. You can successfully run AWS Lambda function on your local machine and debug your code.
Let’s start from very simple example. You only need 4 files. I’ll explain details. (Ignore Tests folder, no need it in this tutorial)
- Package.swift
- NativeMobileServer.swift
- openapi.yaml
- openapi-generator-config.yaml

Step 1. Define OpenAPI Spec
This OpenAPI spec is for tutorial.
Please check folder and file structure. Create an openapi.yaml
openapi: 3.1.0info: title: MobileJobService version: 1.0.0paths: /jobs/fetch: post: summary: Fetch job data from external source description: > This endpoint is called by a scheduled Lambda or backend service. It fetches job data from the given URL and processes it using the provided prompt. operationId: fetchJobs tags: - jobs requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/FetchJobsRequest' responses: '200': description: Successfully fetched and processed job data content: application/json: schema: $ref: '#/components/schemas/JobListResponse' '400': description: Invalid input parameters '500': description: Internal error during job fetch or processingcomponents: schemas: FetchJobsRequest: type: object required: - url - prompt properties: url: type: string format: uri description: Target URL to scrape or fetch job data from prompt: type: string description: Instruction / extraction prompt used to parse the fetched page JobListResponse: type: array items: $ref: '#/components/schemas/Job' Job: type: object required: - id - title properties: id: type: string description: Unique identifier for the job title: type: string description: Job title country: type: string description: Country code (e.g. SG, US, TW) city: type: string description: City name (e.g. Singapore) postedAt: type: string format: date-time description: When this job was posted, if known company: type: string description: Company name team: type: string description: Team / department (e.g. Mobile, Backend, Growth) jobDescriptionLink: type: string format: uri description: Public link to full job description jobApplyLink: type: string format: uri description: Public link to apply salary: $ref: '#/components/schemas/Salary' description: type: string description: Cleaned / extracted full-text description for the role Salary: type: object properties: min: type: number description: Minimum compensation max: type: number description: Maximum compensation basis: type: string enum: [year, month] description: Salary period basis (yearly or monthly)
And then create openapi-generator-config.yaml
generate: - types - server
Step 2. Create a Swift Package Manager Project
Package.swift
// swift-tools-version: 6.2// The swift-tools-version declares the minimum version of Swift required to build this package.import PackageDescriptionlet package = Package( name: "NativeMobileServer", platforms: [ .macOS(.v15) ], products: [ .executable(name: "NativeMobileServer", targets: ["NativeMobileServer"]) ], dependencies: [ .package(url: "https://github.com/apple/swift-openapi-generator.git", from: "1.10.3"), .package(url: "https://github.com/apple/swift-openapi-runtime.git", from: "1.8.2"), .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"), .package(url: "https://github.com/swift-server/swift-service-lifecycle.git", from: "2.0.0"), ], targets: [ .executableTarget( name: "NativeMobileServer", dependencies: [ .product(name: "OpenAPIRuntime", package: "swift-openapi-runtime"), .product(name: "AWSLambdaRuntime", package: "swift-aws-lambda-runtime"), .product(name: "AWSLambdaEvents", package: "swift-aws-lambda-events"), .product(name: "OpenAPILambda", package: "swift-openapi-lambda"), .product(name: "ServiceLifecycle", package: "swift-service-lifecycle"), ], path: "Sources/NativeMobileServer", resources: [ .copy("openapi.yaml"), .copy("openapi-generator-config.yaml") ], plugins: [ .plugin(name: "OpenAPIGenerator", package: "swift-openapi-generator") ] ), .testTarget( name: "NativeMobileServerTests", dependencies: ["NativeMobileServer"] ), ])
You can remove .testTarget if you don’t need to write test cases.
Step 3. Write a main function
//// NativeMobileServer.swift// NativeMobileServer//// Created by Shawn Sungwook Baek on 10/26/25.//import Foundationimport Loggingimport OpenAPILambdaimport OpenAPIRuntime@mainstruct JobServiceImpl: APIProtocol, OpenAPILambdaHttpApi { func fetchJobs(_ input: Operations.fetchJobs.Input) async throws -> Operations.fetchJobs.Output { logger.info("fetchJobs invoked") let requestBody = input if case let .json(request) = requestBody.body { logger.info("Fetching jobs from \(request.url) with prompt: \(request.prompt)") } let mockJobs: [Components.Schemas.Job] = [ .init( id: "job-001", title: "iOS Developer", country: "SG", postedAt: Date(), company: "Apple", team: "Mobile", jobDescriptionLink: "https://example.com/job/1", jobApplyLink: "https://example.com/apply/1", salary: .init(min: 6000, max: 9000, basis: .month), description: "Develop and maintain the iOS application." ), .init( id: "job-002", title: "Backend Engineer", country: "TW", postedAt: Date(), company: "Uber", team: "Server", jobDescriptionLink: "https://example.com/job/2", jobApplyLink: "https://example.com/apply/2", salary: .init(min: 7000, max: 10000, basis: .month), description: "Build API services and integrations." ), ] return .ok(.init(body: .json(mockJobs))) } let logger: Logger func register(transport: OpenAPILambdaTransport) throws { try transport.router.get("/health") { _, _ in "OK" } logger.trace("Available Routes\n\(transport.router)") // to log all requests and their responses, add a logging middleware let loggingMiddleware = LoggingMiddleware(logger: logger) // MANDATORY (middlewares are optional) try self.registerHandlers(on: transport, middlewares: [loggingMiddleware]) } static func main() async throws { let openAPIService = JobServiceImpl(loggerLabel: "JobService") try await openAPIService.run() } init(loggerLabel: String) { var logger = Logger(label: loggerLabel) logger.logLevel = .trace self.logger = logger }}
Step 4. Check Scheme in Xcode

Check Executable Target.

Important!
You need to set Environment Variables
- LOCAL_LAMBDA_SERVER_ENABLED
- LOCAL_LAMBDA_PORT <- Optional! Default port is 7000
Try build and run and check which pid is using 7000 port.
lsof -i :7000
If other program uses that port, you can change default port by setting LOCAL_LAMBDA_PORT

When you run it, you will see the message. (In my case, I changed the default port 8000)
Step 5. Invoke Lambda function
This part you may confusing because you can’t call lambda like
curl -v -X POST http://127.0.0.1:8000/jobs/fetch \ -H "Content-Type: application/json" \ -d '{ "url": "https://example.com/jobs", "prompt": "Extract latest mobile job listings" }'

If you want to see more detail information, check this out
To invoke and debug our code, we should invoke function like this.
If you want to learn more about this payload structure v2.0 in API Gateway check here
curl -X "POST" "http://127.0.0.1:8000/invoke" \ -H 'Content-Type: application/json; charset=utf-8' \ -d $'{ "requestContext": { "accountId": "", "time": "", "http": { "path": "/jobs/fetch", "userAgent": "", "method": "POST", "protocol": "HTTP/1.1", "sourceIp": "127.0.0.1" }, "domainName": "", "timeEpoch": 0, "domainPrefix": "", "apiId": "", "requestId": "", "stage": "$default" }, "rawPath": "/jobs/fetch", "rawQueryString": "", "version": "2.0", "routeKey": "$default", "isBase64Encoded": true, "body": "{\\"url\\":\\"https://jobs.apple.com/en-sg/search\\", \\"prompt\\":\\"Extract latest mobile job listings\\"}"}'
I’ve set breakpoint at here.

Let’s invoke function.

Ok, breakpoint is working.

And I can see the results from AWS Lambda function
Conclusion
Swift is very powerful for developing server-side applications. There a lot of great open source projects. In Part 2, I’ll explain how to deploy AWS Lambda Swift function to the AWS using SAM CLI.

Leave a Reply