API Gateway Advanced: VTL Templates, Direct Service Integrations & WAF
The most impactful API Gateway optimization is removing Lambda from routes that don't require it. This article covers VTL mapping templates, direct service integrations (API GW → DynamoDB, SQS, EventBridge without Lambda), WebSocket connection tracking, request-parameter Lambda Authorizers, IAM SigV4 for machine-to-machine APIs, and WAF wiring for rate-based and managed rule groups.
Every AWS primitive is a tradeoff surface, not a feature toggle. The most expensive Lambda function in a serverless architecture is sometimes one that does nothing except call another AWS service — reading an HTTP body, constructing an SQS message, and returning a 202. Every one of those invocations pays a cold-start risk, a billing dimension, and a failure surface that does not need to exist. API Gateway's VTL mapping templates enable direct integrations with DynamoDB, SQS, EventBridge, and other AWS services, removing Lambda from the hot path entirely. This article closes the gap between "I use Lambda Proxy for everything" and "I know which routes genuinely require Lambda and which can be served faster and cheaper by a direct integration."
VTL (Velocity Template Language) is the transformation engine built into REST API. A mapping template receives the incoming HTTP request and transforms it into the payload the integration target expects. It has three namespaces:
Namespace
Purpose
Key methods
$input
Access the raw request body and path/query parameters
VTL templates have no network access, no state, no loops (beyond #foreach over arrays), and no conditionals beyond #if/#else. They are pure transformation functions. Any operation requiring an external API call, database lookup, or complex business logic requires Lambda — VTL cannot replace that.
## Access Authorization header (useful in custom integration auth flows)
#set($token = $input.params('Authorization'))
## Access query string parameter
#set($page = $input.params('page'))
#set($limit = $input.params('limit'))
## URL-encode a value for use in a downstream URL (e.g., EventBridge detail)
$util.urlEncode($input.json('$.callbackUrl'))
## Escape a value for safe inclusion in a JSON string
"message": "$util.escapeJavaScript($input.json('$.userInput'))"
Direct service integrations wire API Gateway directly to an AWS service using VTL to transform the request. The integration target is the AWS service API endpoint — not a Lambda function.
## Request template: POST /events → EventBridge PutEvents
## Transforms HTTP body into EventBridge event format
{
"Entries": [{
"Source": "com.myapp.api",
"DetailType": "$input.json('$.eventType')",
"Detail": "$util.escapeJavaScript($input.body)",
"EventBusName": "myapp-events"
}]
}
Expand
Before (Client→REST API→Lambda→SQS, 4 failure surfaces) vs After (Client→REST API→SQS direct via VTL, 2 failure surfaces) with cost delta and latency improve…
WebSocket API provides persistent bidirectional connections. Unlike REST/HTTP APIs, the connection lifecycle is stateful — each client gets a unique connectionId that persists for the connection lifetime.
WebSocket connections that close without triggering $disconnect (network drop, tab close) leave stale connectionId records in DynamoDB. Attempting to push to a stale connection returns GoneException (HTTP 410). Handle 410 responses by deleting the stale record. Set a DynamoDB TTL on connection records (2–4 hours) as a safety net for orphaned connections.
WAF rate-based rules count by IP by default. Attackers using rotating residential proxies or VPNs bypass per-IP rules trivially. For APIs that require abuse-resistant rate limiting, add a JA3 fingerprint-based rule (available via AWS WAF Fraud Control) or rate-limit on a custom header that is harder to rotate than an IP address (e.g., a stable device fingerprint token).
In Part 5: AppSync Foundations — Schema, Unit Resolvers & Direct Data Sources, we shift from REST to managed GraphQL: why wiring every AppSync operation to a Lambda resolver is the same anti-pattern as using Lambda as a SQS pass-through, and how unit resolvers connect AppSync directly to DynamoDB with zero Lambda code and sub-10ms data access latency.
Research & Synthesis Note
This article was developed with AI-assisted deep search, specification cross-referencing, and technical research synthesis.