Cover authentication, routing, throttling, request validation, response shaping, caching, and rate-limiting at the gateway layer. This should show how much responsibility belongs outside the function.
API gateways are not just traffic routers. In serverless systems they often define the real edge contract: who can call the API, how requests are shaped, how aggressively traffic is limited, which responses can be cached, and which invalid requests are rejected before a function ever runs. This is one of the most important design choices in HTTP-facing serverless systems because pushing the right concerns into the gateway keeps handlers smaller, faster, and easier to govern.
The gateway should not become a hidden application server. But it should own the cross-cutting edge responsibilities that do not need to be reimplemented in every handler.
flowchart TD
A["Incoming request"] --> B["Authenticate caller"]
B --> C["Match route"]
C --> D["Validate request shape"]
D --> E["Apply throttling or rate limit"]
E --> F{"Cacheable?"}
F -->|Yes| G["Return cached response or forward"]
F -->|No| H["Forward to function"]
What to notice:
Strong gateway responsibilities often include:
These are strong gateway concerns because they are shared, cross-cutting, and often independent of core business rules.
The function should still own:
The gateway should protect and shape the edge. It should not become the place where business meaning hides.
If a team ignores gateway capabilities, every function repeats the same auth checks, rate limit behavior, and request validation patterns. That increases:
If the team pushes too much into the gateway, it risks building opaque policy and transformation layers that are hard to review. The goal is balance, not maximal edge logic.
1gateway:
2 route: GET /profiles/{id}
3 auth:
4 type: bearer
5 request_validation:
6 path_params:
7 - id: uuid
8 rate_limit:
9 burst: 100
10 requests_per_minute: 600
11 cache:
12 enabled: true
13 ttl_seconds: 30
14
15function:
16 handler: src/profiles.get
This is strong because:
This is usually the first and most important gateway capability. A function should not be spending most of its time repeatedly parsing and verifying tokens if the gateway can handle that reliably and consistently.
These are critical for protecting both the function platform and downstream dependencies. A rate limit is not only an abuse-control feature. It is also a dependency-protection feature.
The gateway can reject obviously malformed requests early, which saves cost and reduces noise in handlers. The function still handles domain-level validation, but basic structural validation usually belongs at the edge.
Caching is powerful for read-heavy safe endpoints, but it needs discipline. Teams should cache only responses whose semantics remain safe under the chosen TTL and invalidation strategy.
A team runs all authentication, schema validation, throttling, and error-envelope formatting inside every function because “we want logic in one place.” The gateway only forwards traffic. Is that a strong gateway design?
Usually no. The stronger answer is that the gateway is underused. Cross-cutting edge concerns often belong there precisely so they can be enforced consistently and keep handlers focused on business behavior. Centralizing everything inside the function may feel tidy, but it usually creates repetition and weakens the actual edge boundary.