AWS API Gateway from Beginner to Expert ?
Table of Contents
- What is API Gateway? Why and How?
- Understanding API Methods
- Tutorial: Creating Your First API with Lambda
- Proxy vs. Non-Proxy Lambda Integration
- Bonus: Request Validation
- HTTP API vs. REST API
- Securing Your API
- Custom Authorization with Lambda Authorizers
- Conclusion
Your In-Depth Guide to AWS API Gateway: From Zero to Hero
Welcome! If you're looking to build, manage, and secure APIs at any scale, you've come to the right place. In this guide, we'll dive deep into AWS API Gateway, the powerful service that acts as the "front door" for your applications. We'll cover everything from the basics to advanced security and monitoring configurations.
What is API Gateway? Why and How?
What is it?
AWS API Gateway is a fully managed service that makes it easy for developers to create, publish, maintain, monitor, and secure APIs at any scale. Think of it as a smart receptionist for your backend services. It handles all the tasks involved in accepting and processing up to hundreds of thousands of concurrent API calls.
Why use it?
- Scalability: Automatically scales to handle incoming traffic.
- Security: Offers throttling, authorization, and access control.
- Efficiency: Supports multiple API versions for iterative development.
- Monitoring: Integrated with Amazon CloudWatch.
How does it work?
API Gateway acts as a reverse proxy, accepting API calls from clients and routing them to the appropriate backend serviceLambda, EC2, HTTP endpoint, or other AWS services.
Understanding API Methods
| Method | Description |
|---|---|
| GET | Retrieves data (read-only) |
| POST | Submits data to create resources |
| PUT | Updates or creates a resource |
| DELETE | Removes a resource |
| PATCH | Applies partial updates |
Tutorial: Creating Your First API with Lambda
Step 1: Create a Simple Lambda Function
In the AWS Lambda Console, create a new Python function and use this code:
1import json
2
3def lambda_handler(event, context):
4 name = "World"
5 if event.get('queryStringParameters'):
6 name = event.get('queryStringParameters').get('name', name)
7
8 response_data = {
9 "message": f"Hello, {name}! Your request was successful.",
10 "status": "success"
11 }
12
13 return {
14 "statusCode": 200,
15 "headers": {"Content-Type": "application/json"},
16 "body": json.dumps(response_data)
17 }
Step 2: Create a REST API in API Gateway
- Go to the API Gateway Console and click Create API.
- Choose REST API, then click Build.
- Select New API, name it (e.g.,
MyFirstAPI), and click Create API.
Step 3: Create a Resource and Method
- Click Actions Create Resource.
- Name it
/proxy-demo. - With the resource selected, click Actions Create Method GET.
- Configure the method:
- Integration Type: Lambda Function
- Use Lambda Proxy Integration: checked
- Lambda Function: Select the one you created earlier
- Click Save and accept the permissions prompt.
Step 4: Deploy Your API
- Click Actions Deploy API.
- Choose
[New Stage]and name itdev. - After deployment, you'll see your Invoke URL:
1https://{api-id}.execute-api.{region}.amazonaws.com/dev
To test it, go to:
1https://{api-id}.execute-api.{region}.amazonaws.com/dev/proxy-demo?name=Rahul
Sample response:
1{
2 "message": "Hello, Rahul! Your request was successful.",
3 "status": "success"
4}
Proxy vs. Non-Proxy Lambda Integration
Lambda Proxy Integration (The Easy Way)
In this mode, the entire HTTP request is passed to the Lambda function as an event. The response must include statusCode, headers, and body.
Example:
1import json
2
3def lambda_handler(event, context):
4 name = event['queryStringParameters'].get('name', 'World')
5 return {
6 "statusCode": 200,
7 "headers": {"Content-Type": "application/json"},
8 "body": json.dumps({"message": f"Hello, {name}!"})
9 }
Lambda Non-Proxy Integration (The Custom Way)
Gives you fine-grained control using Mapping Templates.
Mapping Template Example (VTL syntax):
1#set($inputRoot = $input.json('$'))
2#set($originalParam = $inputRoot.name)
3#set($prefix = "non_proxy_")
4#if(!$originalParam.startsWith($prefix))
5 #set ($originalParam = $prefix + $originalParam)
6#end
7{
8 "name": "$originalParam"
9}
Lambda Function Example:
1import json
2
3def lambda_handler(event, context):
4 name = event.get('name', 'World')
5 return {
6 "greeting": f"Hello from non-proxy, {name}!"
7 }
Bonus: Request Validation
Create a Model in API Gateway
Use this JSON Schema for request validation:
1{
2 "$schema": "http://json-schema.org/draft-04/schema#",
3 "title": "RequestModel",
4 "type": "object",
5 "required": ["name", "email", "mobile-number"],
6 "properties": {
7 "name": { "type": "string", "minLength": 1 },
8 "email": { "type": "string", "format": "email" },
9 "mobile-number": { "type": "integer", "minimum": 1000000000, "maximum": 9999999999 }
10 },
11 "additionalProperties": false
12}
Apply it in Method Request Request Validator Validate body.
HTTP API vs. REST API
| Feature | HTTP API | REST API |
|---|---|---|
| Best For | Serverless, HTTP proxies | Advanced features |
| Cost | Lower | Higher |
| Performance | Faster | Slightly slower |
| Features | JWT/OIDC, simple setup | Request validation, usage plans, API keys |
Verdict: Use HTTP API for simple workloads, REST API for complex, production-grade APIs.
Securing Your API
IAM Resource Policy
Example: Deny access from a specific IP
1{
2 "Version": "2012-10-17",
3 "Statement": [
4 {
5 "Effect": "Deny",
6 "Principal": "*",
7 "Action": "execute-api:Invoke",
8 "Resource": "arn:aws:execute-api:eu-central-1:ACCOUNT_ID:API_ID/dev/GET/proxy-demo",
9 "Condition": {
10 "IpAddress": {
11 "aws:SourceIp": ["94.234.83.13"]
12 }
13 }
14 },
15 {
16 "Effect": "Allow",
17 "Principal": "*",
18 "Action": "execute-api:Invoke",
19 "Resource": "arn:aws:execute-api:eu-central-1:ACCOUNT_ID:API_ID/dev/GET/proxy-demo"
20 }
21 ]
22}
Note: An explicit Deny always overrides Allow in IAM evaluation.
Custom Authorization with Lambda Authorizers
How it Works
- Client sends request with
Authorizationheader. - API Gateway invokes a Lambda Authorizer.
- Authorizer returns an IAM policy.
- API Gateway allows or denies the request.
Authorizer Lambda Example
1import json
2
3def generate_policy(principal_id, effect, resource):
4 return {
5 "principalId": principal_id,
6 "policyDocument": {
7 "Version": "2012-10-17",
8 "Statement": [{
9 "Action": "execute-api:Invoke",
10 "Effect": effect,
11 "Resource": resource
12 }]
13 }
14 }
15
16def lambda_handler(event, context):
17 token = event['authorizationToken']
18 method_arn = event['methodArn']
19
20 if token == "Bearer mysecrettoken":
21 return generate_policy("user", "Allow", method_arn)
22 else:
23 return generate_policy("user", "Deny", method_arn)
Conclusion
AWS API Gateway is an essential tool for building scalable, secure, and monitored APIs. Whether you're creating a simple Lambda-backed HTTP endpoint or deploying a complex API with validation and custom authentication, API Gateway gives you the power and flexibility to build with confidence.
Start small with HTTP APIs and grow into REST APIs as your needs evolve.
Happy Building!