Describe the pattern of routing requests through an API gateway or managed HTTP entry point into function handlers. Explain the strengths and typical failure modes.
Function-backed APIs are the basic HTTP-facing serverless pattern. A managed gateway or HTTP entry point receives the request, applies routing and policy, and invokes a function handler that performs one bounded piece of application work. This is attractive because teams can expose useful APIs without running application servers directly, while still keeping durable state in managed databases, queues, object stores, or workflow services.
This pattern is strongest when the request path is thin and coherent. The function should do something specific and understandable: validate a business rule, write one authoritative state change, fetch one response shape, or accept work and hand off the rest asynchronously. It gets weaker when teams expect the function to behave like a long-running application server with many deep dependencies and several unrelated side effects in one request path.
flowchart LR
A["Client"] --> B["Gateway or managed HTTP entry point"]
B --> C["Function handler"]
C --> D["Managed data store"]
C --> E["Queue or event bus"]
B --> F["Auth, validation, rate limits, caching"]
What to notice:
This pattern is familiar. It looks like an API, behaves like an API, and still benefits from serverless deployment and scaling. It is commonly used for:
The big benefit is platform reduction. Teams can often get a useful API online with less infrastructure toil than with self-managed application servers.
Function-backed APIs are especially good when:
The closer the request path stays to one bounded business action, the stronger the pattern becomes.
The pattern becomes weaker when:
At that point, the function is no longer a clean HTTP boundary. It is acting like a mini service host with poorer runtime control.
1api:
2 route: POST /claims
3 auth: required
4 request_validation:
5 - policyId required
6 - documentKey required
7
8function:
9 handler: src/claims.submit
10 timeout_seconds: 20
11
12resources:
13 claims_store: claims
14 workflow_queue: claim-review-jobs
1type SubmitClaimRequest = {
2 policyId: string;
3 documentKey: string;
4};
5
6export async function submitClaim(request: SubmitClaimRequest) {
7 const claimId = claimIds.next();
8
9 await claimsStore.put({
10 claimId,
11 policyId: request.policyId,
12 documentKey: request.documentKey,
13 status: "submitted",
14 });
15
16 await workflowQueue.publish({
17 claimId,
18 policyId: request.policyId,
19 });
20
21 return {
22 claimId,
23 status: "submitted",
24 };
25}
This is strong because the request path is bounded:
Function-backed APIs often become unhealthy in three ways:
These are not serverless-specific bugs. They are boundary mistakes that serverless makes visible quickly.
A team built a POST /checkout handler that validates input, writes the cart state, authorizes payment, creates shipment labels, sends email, calls analytics, and updates loyalty records before returning. The function still “fits” the platform. Is this a strong function-backed API?
Usually no. The stronger answer is that the request path now contains several actions with different latency, failure, and retry characteristics. A better design usually persists the authoritative state change, maybe performs one critical synchronous dependency call if required, and pushes the rest into clearer downstream processing.