You've built your first Lambda behind API Gateway and it works for one method. Now your /video resource needs to support the full set: create, read, update, delete. The question every serverless API runs into is: do you write one Lambda per method, or one Lambda that handles them all?
Both are valid. Here is how each works, how to wire the single-handler version, and how to choose.
Two ways to support CRUD
Say your API has a /video resource and you need GET, POST, PUT and DELETE on it.
Option 1: one Lambda per method
- ▸GET goes to getHandler, POST to postHandler, and so on
- ▸Each function does one job
- ▸More functions to create and deploy
- ▸Permissions and scaling can be set per method
Option 2: one CRUD Lambda
- ▸Every method on /video goes to one handler
- ▸The handler reads the HTTP method and decides what to do
- ▸Fewer functions, one place for shared code
- ▸One set of permissions covers everything
In the VidShare project we start with a Lambda that only handles PUT. The course then renames it to a general CRUD handler and teaches the single-function approach on purpose, so you see a different way of building the same API.
Wiring it in API Gateway: the ANY method
In the API Gateway console for a REST API:
- Create a resource, for example
/video. - Create a method on that resource, but instead of choosing GET, POST or DELETE, choose ANY. Now every HTTP method on
/videogoes to the same target. - Pick your Lambda function as the target and turn on Lambda proxy integration. With proxy integration, API Gateway passes the whole request straight through to your function instead of reshaping it.
- Deploy the API to a stage.
Look at what Lambda actually receives
Before writing logic, make the function return the raw event so you can see it. A quick test handler is enough:
export const handler = async (event: unknown) => ({
statusCode: 200,
body: JSON.stringify(event),
});Send a GET, then a POST with a JSON body from Postman or curl, and compare. You'll find:
- The event includes the resource path and an HTTP method field, so the handler can tell a GET from a POST.
- Query string values arrive in a query string parameters object. A request to
/video?id=123gives youid: "123". - A request body arrives as a JSON string, so you parse it yourself.
That HTTP method field is the whole trick.
Branch on the HTTP method
Inside the handler, read the method and route to a small function per case. This is a simplified sketch of the idea, not the exact course code:
import type { APIGatewayProxyEvent, APIGatewayProxyResult } from "aws-lambda";
export const handler = async (
event: APIGatewayProxyEvent,
): Promise<APIGatewayProxyResult> => {
switch (event.httpMethod) {
case "GET":
return handleGet(event);
case "POST":
return handlePost(event);
case "PUT":
return handlePut(event);
case "DELETE":
return handleDelete(event);
default:
return { statusCode: 405, body: JSON.stringify({ message: "Method not allowed" }) };
}
};For the GET case, the VidShare design is straightforward: if the client sends ?id=video123, return that video; if they send a user ID such as ?userId=user1, return the list of that user's videos; if neither is sent, return an error.
Testing it properly
A single handler is easy to test if you add a small helper that builds a fake event for a given method and body, and calls the handler with it. Then each method gets its own describe block, with mocks reset between tests. We go deeper on this style in Test-driven development for AWS Lambda with Jest.
So which should you choose?
There is no single right answer. These are the trade-offs to weigh.
A single Lambda tends to win when:
- The methods share a lot of code and the same data access.
- You want less infrastructure to define and maintain.
- The API is small and every method needs the same permissions.
Separate Lambdas tend to win when:
- Methods need different permissions. A read-only GET should not carry delete rights.
- You want to scale, monitor or log each method separately.
- One method is much heavier than the others, and you don't want it to bloat the rest.
A common middle path is one Lambda per resource (all /video methods together) with different functions for different resources.
Key takeaways
- ✓You can give each HTTP method its own Lambda, or one Lambda can serve all of them. Both are valid.
- ✓In API Gateway, the ANY method with Lambda proxy integration sends every method on a resource to one function.
- ✓Return the raw event once to see it: the HTTP method, query string parameters and a JSON-string body.
- ✓Branch on the HTTP method in a switch; choose separate functions when methods need different permissions or scaling.
Build the whole thing, end to end
VidShare: Build a Video Streaming Platform on AWS is 109 lessons that take you from architecture to a working system: API Gateway, Lambda, DynamoDB, S3, MediaConvert, OpenSearch and CDK, with tests along the way. Lifetime access, and three lessons are free to watch.
