on
Serverless 101: The fastest path to your first AWS Lambda—using Function URLs
If you’re just getting into serverless, the most frictionless “hello world” you can ship today is an AWS Lambda exposed directly to the web with a Function URL. It’s a built‑in HTTPS endpoint—no API Gateway, no load balancer—so you can focus on code, not plumbing. As a bonus, Lambda now supports modern runtimes like Node.js 22 and Python 3.13, so you can start with up‑to‑date language features. (docs.aws.amazon.com)
What we’ll build:
- A tiny HTTP API on Lambda (Node.js 22) that echoes a request.
- A Function URL to make it accessible on the internet.
- Optional: flip one setting to try response streaming—a neat way to send back data as it’s ready. (docs.aws.amazon.com)
Think of it like plugging a guitar straight into a small amp. You can jam immediately. If you later need a pedalboard (auth, routing, rate limiting), you can graduate to API Gateway. (docs.aws.amazon.com)
Why Function URLs for your first Lambda?
- Dead simple: AWS generates a permanent HTTPS endpoint for one function. You can create it in the console in seconds. (docs.aws.amazon.com)
- Zero extra service to learn: You pay standard Lambda pricing; the URL itself doesn’t add new costs. (docs.aws.amazon.com)
- Built‑in CORS: Toggle cross‑origin support (handy when calling from a browser) without writing header logic in your code. (docs.aws.amazon.com)
- Optional response streaming: Stream back partial data and larger payloads (up to 200 MB) for snappier Time‑to‑First‑Byte (TTFB). (docs.aws.amazon.com)
When should you use API Gateway instead? If you need custom domains, OAuth/Cognito, request/response transformations, throttling, or usage plans, API Gateway is the right tool. Treat Function URLs as the “quick start” and API Gateway as the “full stack.” (docs.aws.amazon.com)
Prerequisites
- An AWS account and permission to create Lambda functions and Function URLs.
- A terminal with curl (or Postman). If you set the URL’s auth type to AWS_IAM, you’ll sign requests with SigV4; we’ll keep it public for a quick start, then tighten later. (docs.aws.amazon.com)
Step 1: Create a Lambda on Node.js 22
1) In the AWS Console, open Lambda and choose “Create function.” 2) Author from scratch:
- Name: echo-url
- Runtime: Node.js 22 (nodejs22.x). (docs.aws.amazon.com) 3) Create the function.
Replace the default handler with this minimal HTTP handler:
// index.mjs or index.js
export const handler = async (event) => {
const name = event.queryStringParameters?.name ?? "world";
return {
statusCode: 200,
headers: { "content-type": "application/json" },
body: JSON.stringify({
message: `Hello, ${name}!`,
method: event.requestContext?.http?.method,
path: event.rawPath,
query: event.queryStringParameters,
}),
};
};
Prefer Python? Lambda also supports Python 3.13, so you can do the same with a short Flask‑style handler. (aws.amazon.com)
Step 2: Add a Function URL (the magic switch)
1) In your function page, find “Function URL” and click “Create.” 2) Auth type: NONE (public) for the quickest test. You can switch to AWS_IAM when you’re ready. (docs.aws.amazon.com) 3) CORS: If you’ll call from a browser, configure it here (for example, AllowOrigins: *, AllowMethods: GET). Pro tip: let the URL manage CORS headers to avoid duplicate headers in responses. (docs.aws.amazon.com)
Save. You’ll get a URL that looks like: https://abc123.lambda-url.us-east-1.on.aws (docs.aws.amazon.com)
Step 3: Test it
From your terminal:
curl "https://<your-id>.lambda-url.<your-region>.on.aws/?name=Lambda"
You should see a JSON response with the greeting and details about your request.
Security note: Public URLs are great for demos and webhooks, but they are, well, public. For protected endpoints, set AuthType to AWS_IAM and sign requests with SigV4—or graduate to API Gateway for richer auth (Cognito, OAuth, custom authorizers) and traffic controls. (docs.aws.amazon.com)
Optional: Try response streaming (bigger, faster responses)
Traditional Lambda HTTP responses are buffered: you build the full payload (max 6 MB), then return it. Response streaming flips that around—you can start sending bytes immediately, and you can go up to 200 MB. It’s great for server‑rendered HTML, long‑running queries, or generating files on the fly. (docs.aws.amazon.com)
Two things to do:
- Change the Function URL “Invoke mode” from BUFFERED to RESPONSE_STREAM. (docs.aws.amazon.com)
- Wrap your handler with Lambda’s streamifyResponse helper:
// streaming.mjs
import { pipeline } from 'node:stream/promises';
import { Readable } from 'node:stream';
export const handler = awslambda.streamifyResponse(
async (event, responseStream) => {
// Stream a greeting in chunks (pretend this is a large dataset)
const chunks = [
"Hello ",
(event.queryStringParameters?.name ?? "world"),
"! Here comes some streamed data...\n",
...Array.from({ length: 5 }, (_, i) => `chunk ${i + 1}\n`)
];
await pipeline(Readable.from(chunks), responseStream);
}
);
Behind the scenes, response streaming works via the InvokeWithResponseStream API or a Function URL in ResponseStream mode; Lambda’s Node.js runtime provides the awslambda.streamifyResponse decorator. (docs.aws.amazon.com)
Pricing tip: the first 6 MB streamed per request is free; beyond that, you pay per GB streamed. The free tier also includes 100 GiB of HTTP response streaming per month. (aws.amazon.com)
Troubleshooting quick hits
- Seeing double Access‑Control headers? Remove CORS headers from your code and configure them on the Function URL instead; the URL’s CORS config takes precedence on preflight requests. (docs.aws.amazon.com)
- Getting 403s after switching to AWS_IAM? Your client must sign requests with SigV4 and the caller needs lambda:InvokeFunctionUrl permission. (docs.aws.amazon.com)
- Need custom domains, request validation, throttling, or WAF? Move to API Gateway when those show up on your checklist. (docs.aws.amazon.com)
Where to go next
- Lock it down: change AuthType to AWS_IAM and call with signed requests, or front it with API Gateway if you need advanced API features. (docs.aws.amazon.com)
- Automate deploys: package with SAM or CDK and keep the Function URL defined as infrastructure. (docs.aws.amazon.com)
- Choose your runtime wisely: Node.js 22 and Python 3.13 are available in Lambda, so you can start with modern language features from day one. (docs.aws.amazon.com)
The big picture
Function URLs remove nearly all ceremony from “hello serverless.” In a few clicks, you’ve got a live HTTPS endpoint backed by code that scales with demand and only bills while it runs. When you’re ready for the full stage rig—custom domains, auth flows, quotas, caching—API Gateway slots in neatly. Until then, enjoy the simplicity, turn up the volume slowly, and get your first tune out the door. (docs.aws.amazon.com)
Happy deploying!