Apigee Project : Enterprise API Gateway Implementation using Apigee X


Project Overview
We will design, implement, and manage an enterprise-grade API Gateway using Apigee X. Provides a multi-cloud SaaS solution for financial services, requiring a secure, scalable, and high-performance API management platform.
The project will involve:
Designing and implementing an Apigee API Gateway for managing public and private APIs.
Security enforcement through OAuth 2.0, JWT validation, and API keys.
Performance optimization using caching, rate limiting, and load balancing.
Part 1: Setting Up Apigee X and Deploying Your First API Proxy
Introduction
In this multi-part blog series, we will implement an Enterprise API Gateway using Apigee X to meet advanced requirements such as security enforcement,and traffic management. We will use free public APIs as backend targets, test with Postman and cURL, and implement OAuth 2.0, JWT validation, API keys, and monitoring.
Step 1: Setting Up Apigee X in Google Cloud
1.1 Prerequisites
Before we start, ensure you have:
A Google Cloud Project with billing enabled
Apigee X provisioned (Follow Google’s guide)
A domain mapped for Apigee (or use default endpoints)
Installed gcloud CLI
1.2 Create an Apigee Organization
gcloud config set project [PROJECT_ID]
gcloud apigee organizations create --project=[PROJECT_ID] --authorized-network=default
1.3 Enable Required APIs
gcloud services enable apigee.googleapis.com runtimeconfig.googleapis.com
Step 2: Creating an API Proxy
2.1 Choose a Free Target API
For testing, we will use the JSONPlaceholder API, a free public REST API for mock testing.
Base URL:
https://jsonplaceholder.typicode.com
Sample endpoint:
/posts/1
2.2 Create an API Proxy in Apigee X
Go to the Apigee Console
Navigate to Develop > API Proxies
Click + Create Proxy
Select Reverse Proxy
Enter:
Proxy Name:
jsonplaceholder-proxy
Base Path:
/json
Target URL:
https://jsonplaceholder.typicode.com
Click Next, then Deploy
2.3 Test the API Proxy
Using Postman
Open Postman
Make a
GET
Request to:Using cURL
curl -X GET "https://[APIGEE_HOST]/json/posts/1" -H "Accept: application/json"
Expected Response:
{
"userId": 1,
"id": 1,
"title": "sunt aut facere repellat provident occaecati excepturi optio reprehenderit",
"body": "quia et suscipit..."
}
Part 2: Implementing API Security in Apigee X
Introduction
Now that we have deployed our first API proxy, it’s time to secure our APIs. In this part, we will implement OAuth 2.0 authentication, API key validation, and JWT verification to ensure secure access control.
Step 1: Setting Up an OAuth 2.0 Proxy
1.1 Create a New OAuth 2.0 Proxy
Navigate to Develop > API Proxies
Click + Create Proxy
Select No Proxy
Enter:
Proxy Name:
oauth-proxy
Base Path:
/oauth
Click Next, then Deploy
1.2 Apply OAuth 2.0 Token Generation Policy
Open oauth-proxy in Apigee
Edit the PreFlow in
ProxyEndpoint
and add:<OAuthV2 name="OAuth-v2-Policy"> <Operation>GenerateAccessToken</Operation> <SupportedGrantTypes> <GrantType>client_credentials</GrantType> </SupportedGrantTypes> <ExpiresIn>3600</ExpiresIn> <GenerateResponse enabled="true"/> </OAuthV2>
1.3 Test OAuth 2.0 Token Generation
Using Postman
Make a
POST
request to:https://[APIGEE_HOST]/oauth/token
In Body, add:
grant_type=client_credentials&client_id=[YOUR_CLIENT_ID]&client_secret=[YOUR_CLIENT_SECRET]
Expected Response:
{ "access_token": "eyJhbGciOiJIUzI1NiIsInR5...", "token_type": "Bearer", "expires_in": 3600 }
Using cURL
curl -X POST "https://[APIGEE_HOST]/oauth/token" -d "grant_type=client_credentials&client_id=[YOUR_CLIENT_ID]&client_secret=[YOUR_CLIENT_SECRET]"
Step 2: Enforcing API Key Authentication
2.1 Generate an API Key
Navigate to Apigee Console > Publish > API Products
Click + Create Product
Set the Product Name as
TestProduct
Add
/json/*
as the API resource pathEnable Require API Key
Save and deploy the product
2.2 Create a Developer & App
Go to Publish > Developers, click + Create Developer
Create an app under Publish > Apps, and associate it with
TestProduct
Copy the generated API Key
2.3 Apply API Key Verification Policy
Open jsonplaceholder-proxy
Edit the PreFlow in
ProxyEndpoint
and add:<VerifyAPIKey name="Verify-API-Key"> <APIKey ref="request.header.x-api-key"/> </VerifyAPIKey>
Save and deploy the proxy
2.4 Test API Key Enforcement
Using Postman
Make a
GET
request:https://[APIGEE_HOST]/json/posts/1
Add
x-api-key
in Headers with the copied API keyExpected Response: 200 OK
Without API key: 403 Forbidden
Using cURL
curl -X GET "https://[APIGEE_HOST]/json/posts/1" -H "x-api-key: [YOUR_API_KEY]" -H "Accept: application/json"
Part 3: Implementing JWT Authentication and mTLS Security
Introduction
In this part, we will enhance the security of our Apigee X API Gateway by implementing JWT (JSON Web Token) authentication. JWT ensures that only authenticated clients access our APIs.
Step 1: Implementing JWT Authentication
1.1 Enable JWT Verification in Apigee
Open Apigee Console and navigate to Develop > API Proxies.
Select
jsonplaceholder-proxy
.Edit the PreFlow in
ProxyEndpoint
.Add the following policy to verify JWT tokens:
Before Verify JWT policy add an assign message policy to extract the secret.
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<AssignMessage continueOnError="false" enabled="true" name="Extract-Secret">
<DisplayName>Extract-Secret</DisplayName>
<AssignVariable>
<Name>private.secretkey</Name>
<Ref>request.queryparam.secret</Ref>
</AssignVariable>
<IgnoreUnresolvedVariables>false</IgnoreUnresolvedVariables>
<AssignTo createNew="false" transport="http" type="request"/>
</AssignMessage>
The VerifyJWT
policy
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<VerifyJWT continueOnError="false" enabled="true" name="Verify-JWT-Token">
<DisplayName>Verify-JWT-Token</DisplayName>
<Algorithm>HS256</Algorithm>
<Source>request.header.Authorization</Source>
<SecretKey>
<Value ref="private.secretkey"/>
<Id/>
</SecretKey>
<Issuer>https://dev-zao4x20.us.auth0.com</Issuer>
<Audience>audience1</Audience>
<AdditionalClaims>
<Claim name="role">admin</Claim>
<Claim name="scope">read:posts</Claim>
</AdditionalClaims>
</VerifyJWT>
1.2 Create a Separate Proxy for JWT Token Generation
Steps to Create a New Proxy for JWT Generation
Go to Apigee Console → Navigate to Develop > API Proxies.
Create a New Proxy:
Click + Create Proxy.
Select Reverse Proxy.
Set Proxy Name as
generate-jwt-proxy
.Set Base Path as
/generate-jwt
.Target Endpoint: Select No Target (Service Callout Only).
Click Next and deploy.
Add GenerateJWT Policy:
Go to Develop > Policies.
Add a new policy:
Type:
GenerateJWT
Name:
Generate-JWT-Token
Use the following configuration:\
<?xml version="1.0" encoding="UTF-8" standalone="yes"?> <GenerateJWT continueOnError="false" enabled="true" name="Generate-JWT-Token"> <DisplayName>Generate-JWT-Token</DisplayName> <Algorithm>HS256</Algorithm> <SecretKey> <Value ref="private.secretkey"/> <Id/> </SecretKey> <Issuer>https://dev-zaao4x20.us.auth0.com</Issuer> <Subject>api-client</Subject> <Audience>audience1</Audience> <ExpiresIn>3600</ExpiresIn> <AdditionalClaims> <Claim name="role">admin</Claim> <Claim name="scope">read:posts</Claim> </AdditionalClaims> <OutputVariable>jwt_token</OutputVariable> </GenerateJWT>
Accept Secret Key via Query Parameter:
Add an AssignMessage policy before GenerateJWT to extract secret from query:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?> <AssignMessage continueOnError="false" enabled="true" name="Extract-Secret"> <DisplayName>Extract-Secret</DisplayName> <AssignVariable> <Name>private.secretkey</Name> <Ref>request.queryparam.secret</Ref> </AssignVariable> <IgnoreUnresolvedVariables>false</IgnoreUnresolvedVariables> <AssignTo createNew="false" transport="http" type="request"/> </AssignMessage>
Return JWT in Response:
Add an
AssignMessage
policy to return the JWT:<?xml version="1.0" encoding="UTF-8" standalone="yes"?> <AssignMessage continueOnError="false" enabled="true" name="Return-JWT"> <Properties/> <Set> <Headers/> <QueryParams/> <FormParams/> <Verb>POST</Verb> <Payload contentType="application/json"> { "status": "generated JWT successfully", "JWT_Token": {jwt_token} } </Payload> <Path/> </Set> <IgnoreUnresolvedVariables>true</IgnoreUnresolvedVariables> <AssignTo createNew="false" transport="http" type="request"/> </AssignMessage>
Attach Policies to Flow:
In
ProxyEndpoint
PreFlow, add the policies in sequence:<?xml version="1.0" encoding="UTF-8" standalone="yes"?> <ProxyEndpoint name="default"> <PreFlow name="PreFlow"> <Request> <Step> <Name>Extract-Secret</Name> </Step> <Step> <Name>Generate-JWT-Token</Name> </Step> <Step> <Name>Log-JWT-Token</Name> </Step> <Step> <Name>Return-JWT</Name> </Step> </Request> <Response/> </PreFlow> <Flows/> <PostFlow name="PostFlow"> <Request/> <Response/> </PostFlow> <HTTPProxyConnection> <BasePath>/generate-jwt</BasePath> </HTTPProxyConnection> <RouteRule name="noroute"/> </ProxyEndpoint>
Deploy the Proxy.
1.3 Adding the Proxy to an Existing API Product
Go to Apigee Console → Publish > API Products.
Select the existing API Product where JWT should be included.
Click Edit → Add Proxy.
Select
generate-jwt-proxy
.Click Save and Deploy.
1.4 Testing in Postman
Generate Token Request
curl -X POST "https://[APIGEE_HOST]/generate-jwt?secret=client_secret" \
-H "Content-Type: application/json"
Expected Response
{
"token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
}
Step 2: Verifying JWT Token via Protected API
2.1 Call Protected Proxy with JWT Token
curl -X GET "https://[APIGEE_HOST]/jsonplaceholder/posts/1?secret=client_secret" \
-H "Authorization: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
{
"userId": 1,
"id": 1,
"title": "Sample JSONPlaceholder Post",
"body": "This is a sample post body from JSONPlaceholder API."
}
Part 4: Implementing Rate Limiting, Response Caching, and Logging in Apigee X
These features help ensure performance, security, and operational visibility for your APIs.
Step 1: Add Spike Arrest (Rate Limiting)
Spike Arrest prevents backend overloading by throttling requests.
1.1 Add Spike Arrest Policy
In your jsonplaceholder-proxy
, open the PreFlow under ProxyEndpoint
. Add:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<SpikeArrest continueOnError="false" enabled="true" name="Apply-SpikeArres">
<DisplayName>Apply-SpikeArres</DisplayName>
<Rate>5ps</Rate>
</SpikeArrest>
1.3 Test Rate Limiting in Postman
Use a script or Postman runner to send multiple rapid requests. After 5 requests per second, you'll receive:
{
"fault": {
"faultstring": "Spike arrest violation. Allowed rate : 5ps",
"detail": {
"errorcode": "policies.ratelimit.SpikeArrestViolation"
}
}
}
Step 2: Enable Response Caching
Apigee can cache responses to reduce latency and backend load.
2.1 Add ResponseCache Policy
Add this in the Response
flow of your proxy:
<ResponseCache name="Cache-JSONPlaceholder">
<CacheKey>
<KeyFragment>jsonplaceholder</KeyFragment>
<KeyFragment ref="request.uri"/>
</CacheKey>
<Scope>Exclusive</Scope>
<ExpirySettings>
<TimeoutInSec>60</TimeoutInSec>
</ExpirySettings>
</ResponseCache>
2.2 Test the Cache
Make a GET request.
Then repeat the same request. The second response will be served from Apigee cache (check headers like
X-Apigee-Cache: HIT
).
Step 3: Add Message Logging for Observability
3.1 Add MessageLogging Policy
Go to Develop > Policies
, create:
<MessageLogging name="Log-Request-Response">
<Syslog>
<Message>
Request: {request.uri}, Token: {request.header.Authorization}, ResponseCode: {response.status.code}
</Message>
<Host>syslog.example.com</Host>
<Port>514</Port>
</Syslog>
</MessageLogging>
3.2 Attach to policy Flow should look like
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<ProxyEndpoint name="default">
<PreFlow name="PreFlow">
<Request>
<Step>
<Name>Apply-SpikeArres</Name>
</Step>
<Step>
<Name>Extract-Secret</Name>
</Step>
<Step>
<Name>verify-api-key</Name>
</Step>
<Step>
<Name>Verify-JWT-Token</Name>
</Step>
</Request>
<Response>
<Step>
<Name>Log-Request-Response</Name>
</Step>
<Step>
<Name>Cache-JSONPlaceholder</Name>
</Step>
</Response>
</PreFlow>
<Flows/>
<PostFlow name="PostFlow">
<Request/>
<Response/>
</PostFlow>
<HTTPProxyConnection>
<BasePath>/json</BasePath>
</HTTPProxyConnection>
<RouteRule name="default">
<TargetEndpoint>default</TargetEndpoint>
</RouteRule>
</ProxyEndpoint>
Summary
Feature | Benefit |
Spike Arrest | Protects the backend from floods |
Response Caching | Reduces latency & backend load |
Logging | Helps with debugging & auditing |
In this blog, we learnt to develop API gateway for Enterprise API!!
Subscribe to my newsletter
Read articles from Nainaz directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by
