API / APIGEE Gateway Interview Questions
1. What is Apigee and what problem does it solve for organisations?
Apigee is Google Cloud's native, full-lifecycle API management platform. It sits between backend services and the clients that consume them, acting as a secure, observable, and policy-enforcing proxy layer. Apigee handles traffic routing, authentication, rate limiting, analytics, developer portal hosting, and the complete lifecycle work of getting an API from design to deprecation.
The core problem it solves: as organisations expose more backend services as APIs -- to partners, mobile apps, third-party developers, and internal consumers -- they face a consistent set of cross-cutting concerns that should not live inside each service:
- Security -- authentication, authorisation, token validation, and protection from abuse
- Traffic management -- rate limiting, quotas, spike arrest, and load balancing
- Observability -- access logs, latency metrics, error rates, and developer analytics
- Mediation -- transforming request/response formats, header manipulation, protocol bridging
- Developer experience -- self-service portals, API discovery, and API product packaging
| Property | Detail |
|---|---|
| Product type | Full-lifecycle API management platform |
| Vendor | Google Cloud |
| Supported protocols | REST, SOAP, GraphQL, gRPC, OpenAPI |
| Deployment models | Apigee (SaaS), Apigee hybrid, Apigee Adapter for Envoy |
| Core unit | API Proxy |
| Policy engine | XML-based declarative policies + JavaScript/Java callouts |
Apigee is one of the four or five names that consistently appear on enterprise API management shortlists alongside WSO2, Kong, MuleSoft, and AWS API Gateway.
2. What are the deployment models available in Apigee?
Apigee offers three deployment models to accommodate different infrastructure requirements, data residency rules, and latency constraints.
| Model | Management plane | Runtime plane | Best for |
|---|---|---|---|
| Apigee (SaaS / cloud-native) | Google-managed | Google-managed | Cloud-first; simplest to operate; no infrastructure to maintain |
| Apigee hybrid | Google-managed | Customer-managed (own DC, AWS, Azure, GKE) | Data residency; latency to on-prem backends; regulatory compliance |
| Apigee Adapter for Envoy | Google-managed (central Apigee control) | Envoy sidecar inside service mesh | East-West traffic; service-to-service security within Kubernetes |
Apigee (SaaS): the fully cloud-native version where both the management and runtime planes are managed by Google. Ideal for cloud-first organisations that want to minimise operational overhead.
Apigee hybrid: the management plane (the UI, analytics storage, and policy configuration) stays in Google Cloud, while the runtime plane (the message processors that actually execute policy and proxy traffic) is deployed in the customer's own environment -- on-premises, AWS, Azure, or any Kubernetes cluster. Under the hood, the runtime uses a Kubernetes cluster for scalability and high availability.
Apigee Adapter for Envoy: an advanced model for managing East-West (service-to-service) traffic within a microservices architecture. Apigee acts as the central policy authority while Envoy sidecars enforce those policies locally in the service mesh, providing fast, decentralised security checks without routing each request through a central gateway.
3. What is an API proxy in Apigee and what are its main components?
An API proxy is the primary unit of deployment in Apigee. It creates an abstraction layer between API consumers and backend services, so backend URLs, authentication schemes, and data formats can change without affecting consumers. Every request from a client hits the proxy first; the proxy applies policies, then forwards to the backend.
| Component | Description |
|---|---|
| ProxyEndpoint | The client-facing endpoint: defines the URL clients call, the HTTP verbs accepted, and the flows that execute on incoming requests |
| TargetEndpoint | The backend-facing endpoint: defines where Apigee forwards the request after applying PreFlow/PostFlow policies |
| Flows | Ordered sequences of policy steps: PreFlow, ConditionalFlows, PostFlow |
| Policies | Reusable, declarative processing steps (XML) attached to flow steps |
| Resources | JavaScript, Java, Python, XSLT, or other files used by callout policies |
| API Bundle | The ZIP archive containing all proxy configuration files, deployed to an environment |
<!-- Simplified proxy structure --> apigee-proxy/ apiproxy/ my-proxy.xml <!-- root proxy descriptor --> proxies/ default.xml <!-- ProxyEndpoint definition --> targets/ default.xml <!-- TargetEndpoint definition --> policies/ VerifyAPIKey.xml Quota.xml AssignMessage.xml resources/ jsc/ transform.js
A proxy is deployed to an environment (such as test or prod). The same proxy bundle can be deployed to multiple environments with environment-specific configuration, enabling a standard test-to-production promotion workflow.
4. What are Flows in Apigee and what is the request/response processing pipeline?
A Flow is an ordered sequence of policy steps that Apigee executes as a request travels from client to backend and back. Understanding the flow pipeline is fundamental to knowing where to attach each policy.
| Phase | Direction | Description |
|---|---|---|
| ProxyEndpoint PreFlow | Request | First to execute; runs for every request regardless of path; ideal for security policies (key verification, OAuth) |
| ConditionalFlows (ProxyEndpoint) | Request | Named flows with conditions (e.g. path suffix or verb); only the first matching flow executes |
| ProxyEndpoint PostFlow | Request | Runs after conditional flows; rarely used on request side |
| TargetEndpoint PreFlow | Request | Runs just before Apigee forwards to backend; last chance to transform the outgoing request |
| Backend | Both | The actual backend service |
| TargetEndpoint PostFlow | Response | First to run on response; transform backend response before client sees it |
| ProxyEndpoint PostFlow | Response | Last policy stage before client receives the response |
| Error Flow (FaultRules) | Either | Executes when a policy raises an error; used for custom error responses |
<!-- Example: PreFlow with security policy --> <ProxyEndpoint name="default"> <PreFlow name="PreFlow"> <Request> <Step><Name>VerifyAPIKey</Name></Step> <!-- Step 1: check key --> <Step><Name>Quota</Name></Step> <!-- Step 2: enforce quota --> </Request> <Response/> </PreFlow> <Flows> <Flow name="GetOrders"> <Condition>request.verb == "GET" and proxy.pathsuffix MatchesPath "/orders"</Condition> <Request> <Step><Name>AssignMessage.SetHeaders</Name></Step> </Request> </Flow> </Flows> <PostFlow name="PostFlow"> <Response> <Step><Name>ResponseCache</Name></Step> <!-- cache the response --> </Response> </PostFlow> </ProxyEndpoint>
5. What are Apigee Policies and what categories are available?
Policies are the processing building blocks of an Apigee proxy. Each policy is a pre-built, reusable, XML-configured processing step that you attach to a flow. Because policies are declarative, most tasks require no custom code. Apigee provides over 40 built-in policies organised into five categories.
| Category | Examples | Purpose |
|---|---|---|
| Security | VerifyAPIKey, OAuthV2, JWT, HMAC, BasicAuthentication, AccessControl | Authentication, authorisation, token validation, IP allowlisting |
| Traffic management | Quota, SpikeArrest, ResponseCache, ConcurrentRateLimit | Rate limiting, caching, protecting backends from traffic spikes |
| Mediation / transformation | AssignMessage, ExtractVariables, JSONToXML, XMLToJSON, KeyValueMapOperations | Transforming request/response content, setting variables, protocol conversion |
| Extension | ServiceCallout, JavaCallout, JavaScriptCallout, PythonScript | Calling external services, executing custom code |
| Data | MessageLogging, StatisticsCollector | Logging, custom analytics |
<!-- VerifyAPIKey policy example --> <VerifyAPIKey name="VerifyAPIKey"> <DisplayName>Verify API Key</DisplayName> <APIKey ref="request.header.x-api-key"/> </VerifyAPIKey> <!-- Quota policy example --> <Quota name="Quota" type="rollingwindow"> <Interval>1</Interval> <TimeUnit>minute</TimeUnit> <Allow count="100"/> </Quota> <!-- AssignMessage policy example --> <AssignMessage name="AM.SetBackendHeaders"> <AssignTo createNew="false" type="request"/> <Set> <Headers> <Header name="x-internal-caller">apigee</Header> </Headers> </Set> <IgnoreUnresolvedVariables>true</IgnoreUnresolvedVariables> </AssignMessage>
6. What is the VerifyAPIKey policy and how does basic API key security work in Apigee?
The VerifyAPIKey policy is Apigee's most fundamental security mechanism. It validates that an incoming request contains a valid API key that was issued by Apigee to a registered developer application. If the key is absent or invalid, Apigee immediately returns a 401 Unauthorized response and the request never reaches the backend.
How the API key lifecycle works:
- An API producer creates an API Product that bundles one or more API proxies
- A developer registers on the developer portal and creates an App that subscribes to the product
- Apigee generates a consumer key (the API key) for that app
- The developer includes the key in each API request (typically as a header or query parameter)
- The VerifyAPIKey policy validates the key against Apigee's registry on every request
<!-- Policy definition --> <VerifyAPIKey name="VerifyAPIKey"> <!-- Read the key from the x-api-key request header --> <APIKey ref="request.header.x-api-key"/> </VerifyAPIKey> <!-- Alternative: read from query parameter --> <VerifyAPIKey name="VerifyAPIKey-QP"> <APIKey ref="request.queryparam.apikey"/> </VerifyAPIKey> <!-- Placement: always in ProxyEndpoint PreFlow so every request is checked --> <ProxyEndpoint name="default"> <PreFlow name="PreFlow"> <Request> <Step><Name>VerifyAPIKey</Name></Step> <!-- Must run first --> </Request> </PreFlow> </ProxyEndpoint> <!-- After verification, Apigee populates flow variables: verifyapikey.VerifyAPIKey.client_id -- the app consumer key verifyapikey.VerifyAPIKey.developer.email verifyapikey.VerifyAPIKey.app.name verifyapikey.VerifyAPIKey.api_product.name -->
7. How does OAuth 2.0 work in Apigee and what grant types are supported?
Apigee implements the complete OAuth 2.0 specification via the OAuthV2 policy. Apigee can act as an authorisation server (issuing tokens) or as a resource server (validating tokens), or both. All four OAuth 2.0 grant types are supported.
| Grant type | Use case | Flow summary |
|---|---|---|
| client_credentials | Machine-to-machine; no user involved | App sends client_id + client_secret; Apigee returns access token |
| password (Resource Owner Password) | Trusted first-party apps | User sends username + password; Apigee validates + returns token |
| authorization_code | Third-party apps; user consent required | Redirect flow; user authenticates at IdP; code exchanged for token |
| implicit | Single-page apps (legacy; less secure) | Token returned directly in URL fragment; no backend code exchange |
<!-- Step 1: GenerateAccessToken policy (Apigee acts as auth server) --> <OAuthV2 name="GenerateToken"> <Operation>GenerateAccessToken</Operation> <ExpiresIn>3600000</ExpiresIn> <!-- 1 hour in milliseconds --> <SupportedGrantTypes> <GrantType>client_credentials</GrantType> </SupportedGrantTypes> <GenerateResponse enabled="true"/> </OAuthV2> <!-- Step 2: VerifyAccessToken policy (protect API proxies) --> <OAuthV2 name="VerifyToken"> <Operation>VerifyAccessToken</Operation> </OAuthV2> <!-- Client credentials token request: POST /oauth/token Authorization: Basic base64(client_id:client_secret) Content-Type: application/x-www-form-urlencoded grant_type=client_credentials Response: { "access_token": "eyJ...", "token_type": "BearerToken", "expires_in": "3599" } -->
When acting as a resource server only (validating tokens issued by an external IdP), Apigee validates the token's signature and expiry using the VerifyAccessToken operation, optionally checking scopes and audience claims.
8. What is the difference between Quota and SpikeArrest policies in Apigee?
Both policies limit traffic, but they operate on very different time scales and serve different purposes. Confusing them is a common interview question because both say 'rate limiting' but do fundamentally different jobs.
| Aspect | Quota | SpikeArrest |
|---|---|---|
| Purpose | Business-level entitlement enforcement | Protect backend from sudden traffic spikes |
| Time window | Minutes, hours, days, weeks, or months | Smoothed over seconds or minutes |
| Counter tracking | Per app / developer / API product | Per Apigee message processor (no central count) |
| When reset | At end of the defined interval | Continuous sliding window |
| Example use | Developer on Free tier: max 1,000 calls/day | Allow max 100 requests/second across all callers |
| What happens on violation | Returns 429 (Quota Exceeded) | Returns 429 (Spike Arrest Violation) |
<!-- Quota policy: business entitlement --> <Quota name="Quota" type="rollingwindow"> <Allow count="1000"/> <!-- 1000 calls... --> <Interval>1</Interval> <TimeUnit>day</TimeUnit> <!-- ...per day --> <Identifier ref="verifyapikey.VerifyAPIKey.client_id"/> <!-- per app --> </Quota> <!-- SpikeArrest policy: smooth out bursts --> <SpikeArrest name="SpikeArrest"> <!-- Allow max 10 requests per second Apigee converts to "1 req per 100ms" --> <Rate>10ps</Rate> <!-- ps = per second, pm = per minute --> </SpikeArrest> <!-- Best practice: use BOTH SpikeArrest runs first to prevent sudden spikes Then Quota enforces the developer's entitlement -->
9. What is an API Product in Apigee and how does it differ from an API Proxy?
An API Product is a curated bundle of API proxy resources combined with a usage plan. It is the unit that developers subscribe to, and it represents how you monetise or control access to your APIs. A single API proxy can be included in multiple products with different entitlements.
| Aspect | API Proxy | API Product |
|---|---|---|
| What it is | The technical proxy configuration that handles request/response | A business-facing package of API resources with access rules |
| Who configures it | API developers / platform engineers | API product managers |
| Contains | ProxyEndpoint, TargetEndpoint, policies, flows | One or more proxies, specific resource paths, environments, and quota settings |
| Developer sees | Never directly (transparent) | Visible in developer portal; developer subscribes to it |
| Purpose | Transform, secure, route traffic | Package, monetise, and control access to API capabilities |
<!-- API Product configuration (conceptual) --> API Product: "Premium Weather API" - Proxies: weather-proxy - Environments: prod - Resource paths: /current, /forecast, /historical - Quota: 10,000 calls/day - Approval: automatic API Product: "Free Weather API" - Proxies: weather-proxy - Environments: prod - Resource paths: /current (forecast and historical NOT included) - Quota: 100 calls/day - Approval: automatic # Same proxy, different products = different entitlements per tier # Developer creates an App, subscribes to a Product, # receives a consumer key tied to that product's quota
This separation of concerns is powerful: the API proxy implementation stays the same while the product layer defines which paths, environments, and rate limits apply to each developer audience.
10. What is the Apigee organisation hierarchy and what are Environments?
Apigee uses a clear hierarchical structure to organise all resources. Understanding this hierarchy is essential for managing multi-team and multi-environment API programmes.
| Level | Name | Description |
|---|---|---|
| 1 (top) | Organisation | Top-level container; one per GCP project; holds everything -- proxies, products, developers, environments |
| 2 | Environment | A deployment boundary (e.g. dev, test, prod); proxies must be deployed to an environment to receive traffic; each has its own URL |
| 3 | API Proxy | The deployable proxy bundle; deployed to one or more environments |
| 3 | API Product | Business package; references environments and proxy resource paths |
| 3 | Developer / App | External developers and their registered applications |
# Typical environment setup: # # Organisation: my-company # |-- Environment: dev (https://dev.api.example.com) # |-- Environment: test (https://test.api.example.com) # |-- Environment: prod (https://api.example.com) # # Proxy deployed to both test and prod: # gcloud apigee deployments create \ # --organization=my-company \ # --environment=prod \ # --api=orders-proxy \ # --revision=3 # Environment-specific configuration: # - Target URLs different per environment (dev points to dev backend) # - Quotas may differ between test and prod # - Different SSL certificates per environment # - KVM (Key Value Maps) scoped per environment for config values
Key point: the Apigee Organisation is NOT the same as the Google Cloud Organisation. It lives inside your GCP project and contains all your environments, APIs, products, and developer registrations. When you deprovision Apigee API hub, it also deletes associated Apigee organisations if they have no Apigee instances.
11. What are Shared Flows in Apigee and when do you use them?
A Shared Flow is a reusable sequence of policies that can be called from any API proxy using the FlowCallout policy. Shared flows solve the problem of duplicating the same policy logic across dozens of proxies -- a change to the shared flow propagates to all proxies that reference it.
| Aspect | API Proxy | Shared Flow |
|---|---|---|
| Has a ProxyEndpoint | Yes -- receives direct client traffic | No -- cannot receive traffic directly |
| Has a TargetEndpoint | Yes | No |
| Can it be called externally | Yes (it has a URL) | No (called by FlowCallout from within a proxy) |
| Purpose | Full API lifecycle | Reusable policy bundle for cross-cutting concerns |
| Deployed to | Environment (same as proxies) | Environment (same as proxies) |
<!-- In an API proxy: calling a shared flow --> <FlowCallout name="FC.CommonSecurity"> <SharedFlowBundle>common-security</SharedFlowBundle> </FlowCallout> <!-- common-security shared flow content (sharedflowbundle/): --> <!-- VerifyAPIKey.xml --> <!-- SpikeArrest.xml --> <!-- Quota.xml --> <!-- MessageLogging.xml --> <!-- Typical shared flow use cases: - Common security (VerifyAPIKey + Quota + SpikeArrest) - Standard error handling (FaultRules + AssignMessage) - Logging (MessageLogging + StatisticsCollector) - Header injection (add internal headers before backend) - CORS handling across all proxies --> <!-- A platform team creates and governs the shared flow. Individual API teams attach it via FlowCallout. Policy change in one place = change across all proxies. -->
Governance pattern: a central platform team creates and enforces shared flows containing organisation-wide security, logging, and traffic management standards. API teams build proxies that must include the required shared flows via FlowCallout, ensuring policy consistency without manual duplication.
12. What is response caching in Apigee and how do you configure the ResponseCache policy?
The ResponseCache policy stores successful backend responses in Apigee's in-memory cache. When an identical subsequent request arrives within the cache TTL, Apigee serves the cached response directly without contacting the backend at all. This reduces backend load and improves latency.
<!-- ResponseCache policy --> <ResponseCache name="ResponseCache"> <!-- How to build the cache key --> <CacheKey> <Prefix>weather</Prefix> <!-- Cache key includes the city query parameter --> <KeyFragment ref="request.queryparam.city" /> </CacheKey> <!-- How long to cache the response --> <ExpirySettings> <TimeoutInSec>300</TimeoutInSec> <!-- 5 minutes --> </ExpirySettings> <!-- Skip caching if the client sends Cache-Control: no-cache --> <SkipCacheLookup>request.header.cache-control = "no-cache"</SkipCacheLookup> </ResponseCache> <!-- Placement: ResponseCache appears in BOTH: 1. ProxyEndpoint PreFlow Request (to check for cache hit) 2. ProxyEndpoint PostFlow Response (to populate the cache on cache miss) Apigee handles the dual role automatically with this single policy --> <!-- Flow variables after policy executes: responsecache.ResponseCache.cachehit -- true/false responsecache.ResponseCache.cachekey -- the computed cache key -->
| Policy | Scope | Purpose |
|---|---|---|
| ResponseCache | Full response body | Cache entire response to avoid backend calls |
| LookupCache | Arbitrary values | Read arbitrary data from cache (used with PopulateCache) |
| PopulateCache | Arbitrary values | Write arbitrary data into a named cache |
| InvalidateCache | Arbitrary values | Explicitly remove entries from cache |
13. What is the AssignMessage policy and what can it do?
The AssignMessage policy is one of the most-used policies in Apigee. It lets you create, modify, or remove HTTP message components (headers, query parameters, form parameters, body, verb, path) on either the request or the response. It is used for protocol bridging, header injection, body transformation, and creating custom responses.
<!-- Set headers on the outgoing request to backend --> <AssignMessage name="AM.SetBackendHeaders"> <AssignTo createNew="false" type="request"/> <Set> <Headers> <Header name="x-internal-caller">apigee-proxy</Header> <Header name="x-correlation-id">{request.header.x-correlation-id}</Header> </Headers> </Set> <Remove> <Headers> <Header name="x-api-key"/> <!-- strip the key before forwarding --> </Headers> </Remove> </AssignMessage> <!-- Create a custom error response --> <AssignMessage name="AM.CustomError"> <AssignTo createNew="true" type="response"/> <Set> <StatusCode>403</StatusCode> <ReasonPhrase>Forbidden</ReasonPhrase> <Headers> <Header name="Content-Type">application/json</Header> </Headers> <Payload contentType="application/json">{ "error": "access_denied", "message": "You do not have permission to call this API." }</Payload> </Set> </AssignMessage> <!-- Change the request verb and path --> <AssignMessage name="AM.RewritePath"> <AssignTo createNew="false" type="request"/> <Set> <Verb>POST</Verb> <Path>/v2/orders</Path> </Set> </AssignMessage>
14. What is the ExtractVariables policy and how does it work with flow variables?
The ExtractVariables policy extracts content from HTTP messages (headers, query parameters, URI path, JSON body, XML body, form parameters) and stores the values in named flow variables. These variables can then be referenced in conditions and other policies throughout the proxy.
<!-- Extract from JSON request body --> <ExtractVariables name="EV.ExtractBody"> <Source>request</Source> <JSONPayload> <Variable name="orderId"> <JSONPath>$.order.id</JSONPath> </Variable> <Variable name="customerId"> <JSONPath>$.order.customer.id</JSONPath> </Variable> </JSONPayload> </ExtractVariables> <!-- Extract from URI path pattern: /orders/{orderId}/items/{itemId} --> <ExtractVariables name="EV.PathVars"> <Source>request</Source> <URIPath> <Pattern ignoreCase="true">/orders/{orderId}/items/{itemId}</Pattern> </URIPath> </ExtractVariables> <!-- Extract from query parameter --> <ExtractVariables name="EV.QueryParam"> <Source>request</Source> <QueryParam name="customerId"> <Pattern>{customerId}</Pattern> </QueryParam> </ExtractVariables> <!-- Now use the variable in a condition or another policy --> <!-- Example: add the orderId as a backend header --> <AssignMessage name="AM.InjectOrderId"> <Set> <Headers> <Header name="x-order-id">{orderId}</Header> </Headers> </Set> </AssignMessage>
15. What is the ServiceCallout policy and when would you use it?
The ServiceCallout policy allows an Apigee proxy to make an additional HTTP call to an external service within the same request/response pipeline. The response from that external call is stored in a variable and can be used by subsequent policies, all before returning the final response to the client.
<!-- ServiceCallout: call an identity service to enrich the request --> <ServiceCallout name="SC.GetUserProfile"> <Request variable="userProfileRequest"> <Set> <Headers> <Header name="Authorization">Bearer {request.header.authorization}</Header> </Headers> </Set> </Request> <Response>userProfileResponse</Response> <HTTPTargetConnection> <URL>https://identity.internal.example.com/profile/{userId}</URL> </HTTPTargetConnection> </ServiceCallout> <!-- Then extract data from the callout response --> <ExtractVariables name="EV.ExtractProfile"> <Source>userProfileResponse</Source> <JSONPayload> <Variable name="userRole"> <JSONPath>$.role</JSONPath> </Variable> </JSONPayload> </ExtractVariables> <!-- Use the role in a condition to allow/deny access --> <!-- Condition: userRole = "admin" -->
| Use case | Description |
|---|---|
| Identity enrichment | Call an IdP to get user roles before authorisation decision |
| Data lookup | Fetch customer data from CRM to add to request |
| Token exchange | Exchange one token type for another with an external service |
| Webhook notification | Send event notification before/after backend call |
| Fraud check | Call a fraud detection service and block if flagged |
16. What are Key Value Maps (KVMs) in Apigee and how do you use them?
Key Value Maps (KVMs) are encrypted, persistent key-value stores that allow Apigee proxies to read configuration values at runtime without hardcoding them. KVMs are ideal for storing environment-specific configuration like backend URLs, API keys, feature flags, and whitelists that need to change without redeploying proxies.
| Scope | Accessible from | Use case |
|---|---|---|
| Organisation | All proxies in the org | Global config: OAuth endpoints, universal whitelists |
| Environment | All proxies in that environment | Environment-specific: backend URLs for dev vs prod |
| Proxy | Only that specific proxy | Proxy-specific: feature flags, local config |
<!-- KeyValueMapOperations policy: GET --> <KeyValueMapOperations name="KVM.GetConfig" mapIdentifier="backend-config"> <Scope>environment</Scope> <Get assignTo="backendUrl" index="1"> <Key><Parameter>target.url</Parameter></Key> </Get> </KeyValueMapOperations> <!-- After execution, use the retrieved value --> <!-- {backendUrl} is now available in flow variables --> <!-- KeyValueMapOperations policy: PUT (write a value) --> <KeyValueMapOperations name="KVM.PutToken" mapIdentifier="token-cache"> <Scope>environment</Scope> <Put override="true"> <Key><Parameter>access_token</Parameter></Key> <Value ref="token_response.access_token"/> </Put> </KeyValueMapOperations> <!-- CLI: create a KVM and set values --> # Using Apigee API: # curl -X POST "https://apigee.googleapis.com/v1/organizations/my-org/environments/prod/keyvaluemaps" \ # -d '{"name": "backend-config", "encrypted": true}' # Add an entry: # curl -X POST ".../keyvaluemaps/backend-config/entries" \ # -d '{"name": "target.url", "value": "https://api.prod.internal.com"}'
17. How does fault handling and error management work in Apigee?
Apigee provides a structured fault handling mechanism through FaultRules and DefaultFaultRule. When a policy raises an error, Apigee exits the normal flow and enters the error flow, where you can customise the error response returned to the client.
<!-- FaultRule: handle specific policy error --> <ProxyEndpoint name="default"> <FaultRules> <!-- Handle quota exceeded specifically --> <FaultRule name="QuotaExceeded"> <Condition>fault.name = "QuotaExceeded"</Condition> <Step><Name>AM.QuotaExceededResponse</Name></Step> </FaultRule> <!-- Handle invalid API key --> <FaultRule name="InvalidApiKey"> <Condition>fault.name = "InvalidApiKey"</Condition> <Step><Name>AM.UnauthorisedResponse</Name></Step> </FaultRule> </FaultRules> <!-- Catch-all for any unhandled fault --> <DefaultFaultRule name="DefaultFaultRule"> <Step><Name>AM.GenericErrorResponse</Name></Step> <AlwaysEnforce>true</AlwaysEnforce> </DefaultFaultRule> </ProxyEndpoint> <!-- Custom error response policy --> <AssignMessage name="AM.QuotaExceededResponse"> <AssignTo createNew="true" type="response"/> <Set> <StatusCode>429</StatusCode> <ReasonPhrase>Too Many Requests</ReasonPhrase> <Headers><Header name="Content-Type">application/json</Header></Headers> <Payload contentType="application/json">{ "error": "rate_limit_exceeded", "message": "You have exceeded your quota.", "retry_after": "3600" }</Payload> </Set> </AssignMessage> <!-- Key fault variables: fault.name -- e.g. "QuotaExceeded", "InvalidApiKey" fault.type -- "policy" or "messaging" error.message -- the error message string -->
18. What is Target Server configuration in Apigee and why is it used instead of hardcoding backend URLs?
A Target Server is a named, environment-scoped configuration object that defines a backend service endpoint (host, port, SSL settings). Instead of hardcoding the backend URL in the proxy's TargetEndpoint XML, you reference a Target Server by name. This allows the same proxy to point to different backends in different environments (dev vs prod) and enables seamless backend updates without proxy redeployment.
<!-- TargetEndpoint using a TargetServer (recommended) --> <TargetEndpoint name="default"> <HTTPTargetConnection> <LoadBalancer> <!-- Reference a named Target Server instead of hardcoded URL --> <Server name="orders-backend-server"/> </LoadBalancer> <Path>/api/v1</Path> </HTTPTargetConnection> </TargetEndpoint> <!-- Target Server definition (set in Apigee UI/API per environment) --> <!-- Environment: prod --> { "name": "orders-backend-server", "host": "orders.prod.internal.example.com", "port": 443, "sSLInfo": { "enabled": true, "clientAuthEnabled": false }, "isEnabled": true } <!-- Environment: dev --> { "name": "orders-backend-server", "host": "orders.dev.internal.example.com", "port": 8080, "sSLInfo": { "enabled": false } } <!-- Load balancing across multiple target servers --> <LoadBalancer> <Algorithm>RoundRobin</Algorithm> <Server name="orders-backend-1"/> <Server name="orders-backend-2"/> <Server name="orders-backend-3"/> </LoadBalancer>
19. What analytics capabilities does Apigee provide?
Apigee includes a built-in analytics engine that automatically captures data about every API request passing through the gateway. No additional instrumentation is needed in the backend. Analytics data powers dashboards, alerting, custom reports, and the developer portal.
| Capability | Description |
|---|---|
| Built-in dashboards | Traffic overview, error rates, latency percentiles, top APIs, top developers |
| Custom reports | Drag-and-drop report builder on any collected dimension or metric |
| StatisticsCollector policy | Capture custom business metrics (e.g. order value, product category) from request/response |
| Data export | Export raw analytics to BigQuery for long-term analysis and custom BI tools |
| Alerting | Set thresholds on metrics (e.g. error rate > 5%) and receive alerts |
| Developer portal analytics | Developers see their own app's usage stats |
| Advanced API Security | Anomaly detection powered by AI/ML to identify bot attacks and misuse |
<!-- StatisticsCollector: capture custom business dimension --> <StatisticsCollector name="SC.OrderMetrics"> <Statistics> <!-- Capture the order total from the JSON body as a metric --> <Statistic name="order_total" ref="order.total" type="Float"/> <!-- Capture the product category as a dimension for segmentation --> <Statistic name="product_category" ref="product.category" type="String"/> </Statistics> </StatisticsCollector> <!-- Metrics Apigee automatically captures (no policy needed): - request count - error count and error rate - response time (p50, p95, p99) - request/response payload sizes - developer / app / API product names - response status code breakdown -->
20. What is the Apigee Developer Portal and how does it support the developer experience?
The Developer Portal is a self-service website that Apigee generates and hosts for API producers. It is the primary channel through which external developers discover APIs, read documentation, register for API access, and manage their applications.
| Feature | Description |
|---|---|
| API catalogue | Lists all published API Products with descriptions and documentation |
| Interactive documentation | Try-it-now interface powered by OpenAPI specifications |
| Developer registration | Self-service signup for external developers |
| App registration | Developers create apps, subscribe to API Products, receive consumer keys |
| Usage analytics | Each developer can see their own app's API usage stats |
| Custom branding | Organisation branding, themes, and custom pages |
| API monetisation display | Shows pricing tiers and payment plans (if monetisation is enabled |
# Developer portal workflow: # # 1. API producer: # a. Creates API Proxy # b. Creates API Product (bundles proxy with quota/access config) # c. Publishes API Product to developer portal # d. SmartDocs (OpenAPI) documentation auto-generated # # 2. App developer: # a. Visits developer portal # b. Discovers available APIs in the catalogue # c. Reads documentation # d. Registers as a developer (creates account) # e. Creates an App and subscribes to an API Product # f. Receives consumer key (API key) # g. Calls the API using the consumer key # # Apigee supports two portal types: # - Integrated portal: built into Apigee, hosted by Google # - Drupal-based portal: full CMS customisation for complex needs # - Custom portal: build your own using Apigee APIs
21. How does JWT validation work in Apigee?
Apigee provides a dedicated JWT policy (separate from OAuthV2) for validating, generating, and decoding JSON Web Tokens. The JWT policy is useful when your authentication scheme uses JWTs issued by an external identity provider such as Google Identity, Auth0, Okta, or Keycloak.
<!-- VerifyJWT: validate a JWT from the Authorization header --> <JWT name="JWT.Verify"> <Operation>VerifyJWT</Operation> <Source>request.header.authorization</Source> <IgnoreUnresolvedVariables>false</IgnoreUnresolvedVariables> <!-- Validate signature using a public key stored in KVM --> <PublicKey> <JWKS ref="kvm.jwks.endpoint"/> <!-- Or use a static PEM: <Value ref="kvm.jwt.public-key"/> --> </PublicKey> <!-- Optional claims validation --> <Issuer>https://auth.example.com</Issuer> <Audience>https://api.example.com</Audience> <!-- AdditionalClaims can validate custom claims --> <AdditionalClaims> <Claim name="role" type="string">admin</Claim> </AdditionalClaims> </JWT> <!-- After successful VerifyJWT, claims are available as flow variables: jwt.JWT.Verify.claim.sub -- subject jwt.JWT.Verify.claim.email jwt.JWT.Verify.claim.role jwt.JWT.Verify.claim.exp -- expiry epoch jwt.JWT.Verify.valid -- true/false --> <!-- GenerateJWT: create a JWT for backend (service account flow) --> <JWT name="JWT.Generate"> <Operation>GenerateJWT</Operation> <ExpiresIn>3600</ExpiresIn> <Subject>apigee-proxy</Subject> <Issuer>https://api.example.com</Issuer> <SecretKey> <Value ref="kvm.jwt.signing-secret"/> </SecretKey> </JWT>
22. What is the MessageLogging policy in Apigee and how is it used for audit and debugging?
The MessageLogging policy sends log messages to an external syslog endpoint or Google Cloud Logging during or after request/response processing. Unlike debug trace (which is ephemeral), MessageLogging persists request/response data to an external system for audit trails, debugging, and compliance.
<!-- MessageLogging to Google Cloud Logging --> <MessageLogging name="ML.AuditLog"> <CloudLogging> <LogName>projects/my-project/logs/apigee-api-access</LogName> <Message contentType="application/json">{ "requestId": "{request.header.x-request-id}", "verb": "{request.verb}", "path": "{request.path}", "clientId": "{verifyapikey.VerifyAPIKey.client_id}", "statusCode": "{response.status.code}", "latency": "{target.elapsed.time}", "timestamp": "{system.timestamp}" }</Message> <Labels> <Label> <Key>environment</Key> <Value>{environment.name}</Value> </Label> </Labels> </CloudLogging> </MessageLogging> <!-- Key placement tip: MessageLogging is typically placed in the PostFlow Response AND in the DefaultFaultRule to capture both successful and error responses. The policy executes ASYNCHRONOUSLY by default -- it does NOT block the response to the client. --> <!-- Alternative: syslog (for on-prem logging systems) --> <MessageLogging name="ML.Syslog"> <Syslog> <Message>{request.verb} {request.path} - {response.status.code}</Message> <Host>logs.example.com</Host> <Port>514</Port> <Protocol>UDP</Protocol> </Syslog> </MessageLogging>
23. How does Apigee handle CORS (Cross-Origin Resource Sharing)?
CORS must be handled by Apigee when web browser clients make API calls cross-origin. Apigee deals with two types of CORS requests: simple requests (handled in the response flow) and preflight OPTIONS requests (which must be responded to immediately, before reaching the backend).
<!-- Step 1: Handle preflight OPTIONS requests These must return 200 immediately without hitting the backend --> <Flow name="OptionsPreFlight"> <Condition>request.verb == "OPTIONS"</Condition> <Request> <Step><Name>AM.AddCorsHeaders</Name></Step> <Step><Name>AM.ReturnOptions</Name></Step> <!-- returns 200, no backend call --> </Request> </Flow> <!-- Step 2: Add CORS headers to all responses --> <PostFlow name="PostFlow"> <Response> <Step><Name>AM.AddCorsHeaders</Name></Step> </Response> </PostFlow> <!-- CORS headers AssignMessage policy --> <AssignMessage name="AM.AddCorsHeaders"> <AssignTo createNew="false" type="response"/> <Set> <Headers> <Header name="Access-Control-Allow-Origin">*</Header> <!-- Or restrict to specific origins: <Header name="Access-Control-Allow-Origin"> {request.header.origin} </Header> --> <Header name="Access-Control-Allow-Methods">GET, POST, PUT, DELETE, OPTIONS</Header> <Header name="Access-Control-Allow-Headers">Content-Type, Authorization, x-api-key</Header> <Header name="Access-Control-Max-Age">3600</Header> </Headers> </Set> </AssignMessage> <!-- Return 200 for OPTIONS without calling backend --> <AssignMessage name="AM.ReturnOptions"> <AssignTo createNew="true" type="response"/> <Set><StatusCode>200</StatusCode></Set> <IgnoreUnresolvedVariables>true</IgnoreUnresolvedVariables> </AssignMessage>
24. What is the Apigee hybrid architecture in more depth, including its components?
Apigee hybrid splits responsibilities between Google-managed and customer-managed infrastructure. Understanding the component split is important for architects and operations engineers.
| Component | Where it runs | Managed by |
|---|---|---|
| Management Plane (UI, API, analytics ingestion) | Google Cloud | |
| Apigee Connect | Customer's Kubernetes cluster | Customer (installed by Google tooling) |
| Message Processor (proxy runtime) | Customer's Kubernetes cluster | Customer (installed by Helm/Apigee Operator) |
| Cassandra (config/KVM storage) | Customer's Kubernetes cluster | Customer |
| Mart (API metadata service) | Customer's Kubernetes cluster | Customer |
| Synchroniser | Customer's Kubernetes cluster | Customer - syncs config from management plane |
| UDCA (Universal Data Collection Agent) | Customer's Kubernetes cluster | Customer - ships analytics to Google |
# Apigee hybrid installation summary (Kubernetes-based) # Prerequisites: # - GKE (or any CNCF-certified Kubernetes cluster) # - cert-manager installed # - Anthos Service Mesh (optional but recommended) # Install via Apigee Operator (Helm chart): helm install apigee-operator \ oci://us-docker.pkg.dev/apigee-release/apigee-operators/apigee-operators \ --namespace apigee-system # Apply the ApigeeOrganization and ApigeeEnvironment CRDs: kubectl apply -f apigee-org.yaml kubectl apply -f apigee-env.yaml # Key hybrid release (mid-2026): # Apigee hybrid v1.14.6 (released June 16, 2026) # Apigee instance runtime 1-17-0-apigee-9
The Synchroniser is a critical component that periodically polls the management plane and downloads the latest proxy configurations, KVM values, and product definitions to the runtime cluster. If the synchroniser loses connectivity, the runtime continues serving traffic with the last-known configuration.
25. What are Environment Groups and how does routing work in Apigee?
Environment Groups define the hostnames that route incoming API traffic to a set of environments. They are the mechanism by which Apigee maps a public URL hostname to one or more environments for request routing.
| Concept | Description |
|---|---|
| Environment Group | A named group of environments sharing a set of hostnames |
| Hostname | A domain name (e.g. api.example.com) that clients use to reach proxies in the group |
| Routing | Apigee routes inbound requests to environments based on the hostname in the request |
| Multiple environments | A group can contain multiple environments; Apigee routes to the one with the matching deployed proxy |
# Create an environment group with a hostname: gcloud apigee envgroups create prod-group \ --hostnames="api.example.com" \ --organization=my-org # Attach environments to the group: gcloud apigee envgroups attachments create \ --envgroup=prod-group \ --environment=prod \ --organization=my-org # DNS configuration: # api.example.com CNAME <apigee-external-ip>.nip.io # Or: create an A record pointing to the Apigee instance IP # Virtual host and base path routing: # Apigee routes requests using: # 1. The hostname in the HTTP Host header (maps to environment group) # 2. The base path in the request URL (maps to specific proxy) # # Example: # https://api.example.com/orders/v1/... -> orders-proxy (base path /orders/v1) # https://api.example.com/products/v1/... -> products-proxy (base path /products/v1)
26. How does TLS and mutual TLS (mTLS) work in Apigee?
Apigee supports TLS on both the northbound (client-to-Apigee) and southbound (Apigee-to-backend) connections. Mutual TLS adds client certificate verification, enabling strong two-way authentication without API keys or tokens.
| Direction | Where configured | Purpose |
|---|---|---|
| Northbound (client to Apigee) | Virtual host / Environment Group SSL config | Client must present a valid certificate (mTLS) or just validate Apigee's cert (TLS) |
| Southbound (Apigee to backend) | TargetEndpoint or Target Server SSLInfo | Apigee validates backend cert; optionally sends its own client cert for mTLS |
<!-- Southbound TLS (Apigee to backend): TargetEndpoint --> <TargetEndpoint name="default"> <HTTPTargetConnection> <SSLInfo> <Enabled>true</Enabled> <!-- Verify the backend certificate --> <TrustStore>ref://truststore-backend</TrustStore> <!-- mTLS: Apigee presents its own client certificate --> <ClientAuthEnabled>true</ClientAuthEnabled> <KeyStore>ref://keystore-apigee-client</KeyStore> <KeyAlias>apigee-client-cert</KeyAlias> <!-- Optionally ignore backend cert validation (dev only!) --> <IgnoreValidationErrors>false</IgnoreValidationErrors> </SSLInfo> <URL>https://api.internal.example.com</URL> </HTTPTargetConnection> </TargetEndpoint> <!-- Keystores and Truststores are managed as environment-scoped resources in Apigee: Keystore: holds the private key + certificate Apigee presents Truststore: holds trusted CA certificates Apigee uses to validate backend certificates Created via Apigee API: POST /organizations/{org}/environments/{env}/keystores POST /organizations/{org}/environments/{env}/keystores/{ks}/aliases -->
27. What is the Access Control policy in Apigee and how do you allowlist/denylist IPs?
The AccessControl policy enforces IP-based allowlisting or denylisting. It inspects the client IP address from the request and either permits or blocks the request based on configured CIDR rules. This is used to restrict API access to known networks or block malicious IPs.
<!-- Allow only specific IP ranges (allowlist) --> <AccessControl name="AC.AllowInternalOnly"> <IPRules noRuleMatchAction="DENY"> <!-- DENY if no rule matches --> <MatchRule action="ALLOW"> <SourceAddress mask="24">10.100.0.0</SourceAddress> <!-- /24 subnet --> </MatchRule> <MatchRule action="ALLOW"> <SourceAddress mask="32">203.0.113.50</SourceAddress> <!-- single IP --> </MatchRule> </IPRules> </AccessControl> <!-- Denylist specific IPs (block known bad actors) --> <AccessControl name="AC.DenyBadActors"> <IPRules noRuleMatchAction="ALLOW"> <!-- ALLOW if no rule matches --> <MatchRule action="DENY"> <SourceAddress mask="32">192.0.2.100</SourceAddress> </MatchRule> </IPRules> </AccessControl> <!-- IMPORTANT: In environments with a load balancer, the client IP may be in X-Forwarded-For, not the direct connection. The ValidateBasedOn element handles this: --> <AccessControl name="AC.XFF"> <ValidateBasedOn>X_FORWARDED_FOR_ALL</ValidateBasedOn> <IPRules noRuleMatchAction="DENY"> <MatchRule action="ALLOW"> <SourceAddress mask="24">10.0.0.0</SourceAddress> </MatchRule> </IPRules> </AccessControl>
28. How do the JSONToXML and XMLToJSON policies work in Apigee?
The JSONToXML and XMLToJSON policies enable Apigee to act as a protocol bridge between clients and backends that use different message formats. This is common in enterprise environments where legacy backends speak SOAP/XML but modern clients expect JSON REST APIs.
<!-- Client sends JSON; SOAP backend expects XML --> <!-- Step 1: Convert incoming JSON request to XML --> <JSONToXML name="JSON2XML.Request"> <Options> <RootElement>root</RootElement> <NullValue>NULL</NullValue> </Options> <OutputVariable>request</OutputVariable> <Source>request</Source> </JSONToXML> <!-- Step 2: Route to SOAP backend (via TargetEndpoint) --> <!-- Step 3: Convert XML response from SOAP backend to JSON --> <XMLToJSON name="XML2JSON.Response"> <Options> <RecognizeNull>true</RecognizeNull> <NamespaceSeparator>_</NamespaceSeparator> <TextAlwaysAsProperty>false</TextAlwaysAsProperty> </Options> <OutputVariable>response</OutputVariable> <Source>response</Source> </XMLToJSON> <!-- Flow placement: JSONToXML -> TargetEndpoint PreFlow Request (transform before backend) XMLToJSON -> TargetEndpoint PostFlow Response (transform after backend) Full bridge pattern: Client (JSON) -> [JSONToXML] -> Backend (XML/SOAP) Client (JSON) <- [XMLToJSON] <- Backend (XML/SOAP) -->
29. What is GraphQL proxy support in Apigee?
Apigee supports GraphQL APIs through the GraphQL policy, which validates incoming GraphQL requests against a schema and enforces limits on query depth and field count. This prevents common GraphQL-specific attacks such as deeply nested queries that could overwhelm a backend.
<!-- GraphQL policy: validate and protect GraphQL requests --> <GraphQL name="GQL.Validate"> <Action>parse</Action> <!-- Reference the uploaded GraphQL schema --> <ResourceURL>graphql://schema.graphql</ResourceURL> <!-- Protect against deeply nested queries --> <MaxDepth>10</MaxDepth> <!-- Limit number of fields per query to prevent data scraping --> <MaxCount>100</MaxCount> </GraphQL> <!-- Supported operations: parse - validates the GraphQL query syntax and schema compliance verify - validates that the operation is in the schema The policy catches: - Malformed GraphQL syntax - Operations not in the schema - Queries exceeding MaxDepth (circular/deep nesting attacks) - Queries exceeding MaxCount (field count explosion) --> <!-- Typical proxy structure for GraphQL: Client -> POST /graphql (query in body) ProxyEndpoint: PreFlow: - VerifyAPIKey (or OAuthV2 VerifyToken) - SpikeArrest - GQL.Validate <- GraphQL-specific validation TargetEndpoint -> GraphQL backend service Note: Apigee proxies GraphQL as HTTP POST - standard HTTP policies (auth, rate limiting) all apply normally -->
30. What is Apigee CI/CD and how do you deploy proxies in a pipeline?
Apigee supports full CI/CD integration for proxy deployments using the Apigee Maven Plugin, apigeecli (the official CLI tool), and the Apigee Management API. This allows proxy bundles to be imported, deployed, and tested as part of a standard Git-based delivery pipeline.
# Method 1: apigeecli (official Google CLI tool) # Import a proxy bundle: apigeecli apis create bundle \ --name orders-proxy \ --proxy-zip ./orders-proxy.zip \ --org my-org \ --token $(gcloud auth print-access-token) # Deploy to an environment: apigeecli apis deploy \ --name orders-proxy \ --env prod \ --org my-org \ --rev 3 \ --token $(gcloud auth print-access-token) # Method 2: Apigee Management API (REST) curl -X POST \ "https://apigee.googleapis.com/v1/organizations/my-org/apis?action=import&name=orders-proxy" \ -H "Authorization: Bearer $(gcloud auth print-access-token)" \ -H "Content-Type: multipart/form-data" \ -F "file=@orders-proxy.zip" # Method 3: Maven plugin (in pom.xml) # <plugin> # <groupId>com.apigee.edge</groupId> # <artifactId>apigee-edge-maven-plugin</artifactId> # <configuration> # <org>my-org</org> # <env>prod</env> # </configuration> # </plugin> # Typical CI/CD pipeline: # 1. Developer pushes proxy to Git # 2. CI lints the proxy bundle (apigeelint) # 3. CI runs unit tests (apickli / Mocha) # 4. CI packages and deploys to test environment # 5. Integration tests run against test # 6. Manual approval gate # 7. Deploy to prod
31. What is RBAC (Role-Based Access Control) in Apigee and what are the built-in roles?
Apigee integrates with Google Cloud IAM for access control. Every Apigee operation is controlled by IAM roles assigned to users or service accounts at the Google Cloud project or organisation level.
| Role | Permissions | Typical user |
|---|---|---|
| roles/apigee.admin | Full control: create, update, delete all Apigee resources | Platform administrator |
| roles/apigee.apiCreator | Create and manage API proxies, shared flows, API products | API developer |
| roles/apigee.deployer | Deploy and undeploy proxies to environments | CI/CD service account |
| roles/apigee.analyticsViewer | View analytics data only | Business analyst, product manager |
| roles/apigee.environmentAdmin | Manage environments, target servers, KVMs, caches | Environment admin |
| roles/apigee.readOnlyAdmin | View all resources but cannot create or modify | Auditor, read-only reviewer |
# Grant a service account the deployer role (for CI/CD): gcloud projects add-iam-policy-binding my-project \ --member="serviceAccount:cicd-sa@my-project.iam.gserviceaccount.com" \ --role="roles/apigee.deployer" # Grant a developer the API creator role: gcloud projects add-iam-policy-binding my-project \ --member="user:dev@example.com" \ --role="roles/apigee.apiCreator" # Principle of least privilege: # CI/CD pipelines should use roles/apigee.deployer only # (deploy but not delete or modify proxy logic) # Application developers: roles/apigee.apiCreator # Business analysts: roles/apigee.analyticsViewer # Service account authentication for CI/CD: gcloud auth activate-service-account \ --key-file=cicd-sa-key.json TOKEN=$(gcloud auth print-access-token) apigeecli apis deploy --token $TOKEN ...
32. What is Advanced API Security in Apigee and how does it detect bot attacks?
Advanced API Security (formerly known as Apigee Sense) is an AI/ML-powered add-on that analyses API traffic patterns to detect and block bots, credential stuffing attacks, and API abuse -- without any policy configuration from the developer.
| Capability | Description |
|---|---|
| Bot detection | ML models identify bot-like traffic patterns (high frequency, regular intervals, scripted behaviour) |
| Anomaly detection | Identifies unexpected changes in traffic volume, error rates, or latency |
| Risk assessment | Assigns risk scores to client IPs and API keys based on behaviour |
| Security reports | Dashboards showing detected threats, sources, and patterns |
| Abuse detection rules | Pre-built rules for credential stuffing, data scraping, fake account creation |
| Automated blocking | Optionally block or flag identified bot traffic automatically |
<!-- Advanced API Security actions can be attached to Apigee proxy flows to act on detected threats. Example: deny request if Advanced API Security identifies it as bot traffic: Condition in a ConditionalFlow or FaultRule: apigee.bot.action = "deny" Alternatively, add the 'apigee-bot-protection' shared flow from the Apigee catalogue --> <!-- Security report categories: - Anomalous traffic: unusual volume spikes - Bot patterns: scripted/automated request signatures - Credential stuffing: many failed auth attempts - Data scraping: systematic data extraction - Geographic anomalies: traffic from unexpected regions Available in Apigee UI: Analyze > Security Reports > Advanced API Security -->
33. What is Apigee API Hub and how does it relate to Apigee gateway?
Apigee API Hub is Google Cloud's centralised API registry and governance platform. It is distinct from the Apigee gateway -- while the gateway handles runtime traffic, API Hub provides design-time governance: a searchable catalogue of all APIs across an organisation, regardless of which gateway manages them.
| Aspect | Apigee Gateway | Apigee API Hub |
|---|---|---|
| Primary function | Runtime: proxy, secure, and manage API traffic | Design-time: register, discover, and govern API specifications |
| Traffic handling | Yes - routes and transforms every API call | No - does not touch API traffic |
| OpenAPI specs | Can import for documentation | Central registry for all API specs |
| API lifecycle | Deploy, version, deprecate proxies | Track APIs through design, build, deploy, deprecate stages |
| Multi-gateway support | Manages only Apigee proxies | Can register APIs from any gateway (Apigee, Kong, AWS, etc.) |
| Developer discovery | Developer portal | Cross-organisational API discovery |
# Apigee API Hub CLI (apihub CLI): # Register an API specification: apigeecli apihub apis create \ --org my-org \ --region us-central1 \ --id orders-api \ --display-name "Orders API" \ --description "Manages customer orders" # Upload an OpenAPI spec version: apigeecli apihub apis versions create \ --org my-org \ --region us-central1 \ --api-id orders-api \ --version-id v1 \ --spec-file ./openapi.yaml # API Hub lifecycle stages: # DESIGN -> BUILD -> DEPLOY -> DEPRECATE -> RETIRED # NOTE: When you deprovision Apigee API Hub, # it deletes all associated Apigee organisations with no instances.
34. How does load balancing and health checking work on Apigee TargetEndpoints?
Apigee supports client-side load balancing across multiple backend Target Servers directly within the TargetEndpoint configuration. This provides basic resilience and failover without requiring an external load balancer between Apigee and the backend.
<!-- TargetEndpoint with load balancing across 3 servers --> <TargetEndpoint name="default"> <HTTPTargetConnection> <LoadBalancer> <Algorithm>RoundRobin</Algorithm> <!-- or: LeastConnections, Weighted, Random --> <Server name="backend-1"/> <Server name="backend-2"/> <Server name="backend-3"> <Weight>2</Weight> <!-- Receives 2x the traffic (Weighted algorithm) --> </Server> <!-- Health check / retry configuration --> <MaxFailures>5</MaxFailures> <RetryEnabled>true</RetryEnabled> <IsFallback>false</IsFallback> </LoadBalancer> <Path>/api/v1</Path> </HTTPTargetConnection> <!-- Active health checks (HealthMonitor) --> <HealthMonitor> <IsEnabled>true</IsEnabled> <IntervalInSec>5</IntervalInSec> <HTTPMonitor> <Request> <ConnectTimeoutInSec>2</ConnectTimeoutInSec> <SocketReadTimeoutInSec>2</SocketReadTimeoutInSec> <Verb>GET</Verb> <Path>/health</Path> </Request> <SuccessResponse> <ResponseCode>200</ResponseCode> </SuccessResponse> </HTTPMonitor> </HealthMonitor> </TargetEndpoint>
| Algorithm | Behaviour |
|---|---|
| RoundRobin | Cycles through servers in order (default) |
| LeastConnections | Routes to server with fewest active connections |
| Weighted | Routes proportionally based on Weight values |
| Random | Random server selection per request |
35. What is the Apigee Debug / Trace tool and how do you use it for troubleshooting?
The Debug (Trace) tool in the Apigee UI captures a real-time, step-by-step view of a request as it flows through the proxy pipeline. It shows which policies executed, the values of flow variables at each step, and any errors raised. It is the primary debugging tool for Apigee proxy developers.
<!-- Trace is started from the Apigee UI: Develop > API Proxies > [proxy name] > Debug tab Or via API: POST /organizations/{org}/environments/{env}/apis/{api}/revisions/{rev}/debugsessions A trace session captures: - Every policy that executed and its result - All flow variables and their values at each step - Request/response headers and body - Time spent at each step (ms) - Any faults raised and which FaultRule handled them Reading a trace: - Green step: policy executed successfully - Red step: policy raised a fault - Grey step: policy was skipped (condition was false) - Phase markers: ProxyRequest, TargetRequest, TargetResponse, ProxyResponse Common debugging workflows: 1. Variable values wrong: check ExtractVariables step output 2. Policy not executing: check condition expression in grey steps 3. Auth failing: check VerifyAPIKey step - red with fault.name 4. Slow response: check timing at TargetRequest/TargetResponse 5. Wrong response body: check AssignMessage step output IMPORTANT: Trace sessions capture sensitive data (request bodies, headers, API keys). Limit trace in production environments. -->
36. How do you import an OpenAPI specification into Apigee to generate a proxy?
Apigee can auto-generate an API proxy skeleton directly from an OpenAPI Specification (OAS 3.x or Swagger 2.0). This generates the proxy's flow structure, conditional flows for each operation, and basic passthrough routing - saving significant scaffolding time.
# Method 1: Apigee UI (simplest) # Develop > API Proxies > + Create > Reverse proxy > OpenAPI Spec # Paste or upload the OpenAPI spec # Apigee generates: # - ProxyEndpoint with one ConditionalFlow per operation # - TargetEndpoint pointing to the servers[0].url from the spec # - Basic passthrough proxy (no security policies added yet) # Method 2: apigeecli apigeecli apis create oas \ --name orders-api \ --oas-base-folderpath ./specs/ \ --env prod \ --org my-org \ --token $(gcloud auth print-access-token) # Method 3: Apigee Management API curl -X POST \ "https://apigee.googleapis.com/v1/organizations/my-org/apis?action=import" \ -H "Authorization: Bearer $(gcloud auth print-access-token)" \ -F "file=@proxy-bundle.zip" # What the generated proxy includes: # - One ConditionalFlow per API operation (path + verb) # - Correct basepath from the spec # - TargetEndpoint pointing to spec servers URL # - Does NOT include: # - Security policies (add VerifyAPIKey/OAuthV2 manually) # - Rate limiting (add Quota/SpikeArrest manually) # - Error handling (add FaultRules manually) # Best practice: use OAS generation as a starting point, # then add security and policies to the generated bundle
37. What is Apigee monetisation and how does it work?
Apigee Monetisation is a feature that enables API producers to charge developers for API consumption. It builds on the API Product model to attach pricing plans, enforce payment-based quotas, and generate revenue reports.
| Concept | Description |
|---|---|
| Rate plan | A pricing plan attached to an API Product (flat fee, per-transaction, tiered, revenue sharing) |
| Developer category | Groups of developers with different pricing (e.g. startups get discounts) |
| Balance | Each developer maintains a prepaid or postpaid balance |
| Revenue report | Financial reports on API call revenue per developer, product, or period |
| Notification | Email alerts to developers when balance is low or quota is near |
| Supported models | Flat fee, freemium, pay-as-you-go, tiered, revenue sharing |
# Monetisation workflow: # # 1. API producer creates an API Product (as usual) # 2. Attaches a Rate Plan to the product # - Type: FLAT_FEE, VOLUME_BANDED, REVENUE_SHARE # - Charge per API call, per month, or percentage of transaction value # 3. Developer purchases the plan from the developer portal # - Prepaid: loads credits; each call deducts from balance # - Postpaid: invoiced at end of billing period # 4. Apigee enforces quotas and tracks usage for billing # 5. Revenue reports available in Apigee UI: # Monetisation > Reports > Revenue # Monetisation rate plan types: # FLAT_FEE: Fixed monthly charge for access # VOLUME_BANDED: Tiered pricing (first 1k calls free, then $0.001 each) # REVENUE_SHARE: API producer takes % of transaction value # DEVELOPER: Developer pays for specific call count bundles # Minimum Apigee tier: Monetisation requires Apigee Pay-As-You-Go # or Subscription tier (not available on free tier)
38. What are Apigee flow variables and how do you work with them?
Flow variables are runtime key-value pairs that carry contextual information through the Apigee request/response pipeline. They are the primary means by which policies share data with each other. Some variables are automatically populated by Apigee; others are created by policies like ExtractVariables or AssignMessage.
| Variable | Value | Set by |
|---|---|---|
| request.verb | HTTP verb (GET, POST, etc.) | Apigee (always) |
| request.path | Request URL path | Apigee (always) |
| proxy.pathsuffix | Path after the proxy base path | Apigee (always) |
| request.header.{name} | Named request header value | Apigee (always) |
| request.queryparam.{name} | Named query parameter value | Apigee (always) |
| response.status.code | HTTP status code from backend | Apigee (always) |
| target.url | The URL Apigee sends to backend | Apigee / can be overridden |
| client.ip | Client's IP address | Apigee (always) |
| system.timestamp | Current epoch timestamp (ms) | Apigee (always) |
| environment.name | Current environment name | Apigee (always) |
<!-- Reference a flow variable in policy XML using curly braces --> <AssignMessage name="AM.SetHeader"> <Set> <Headers> <!-- Reference built-in variable --> <Header name="x-request-path">{request.path}</Header> <!-- Reference variable set by ExtractVariables --> <Header name="x-order-id">{orderId}</Header> <!-- Reference verifyapikey variable --> <Header name="x-client-id">{verifyapikey.VerifyAPIKey.client_id}</Header> </Headers> </Set> </AssignMessage> <!-- Reference in a condition expression (no braces needed) --> <Flow name="OrdersFlow"> <Condition>request.verb == "GET" and proxy.pathsuffix MatchesPath "/orders/**"</Condition> </Flow> <!-- Set a variable using JavaScript --> // context.setVariable("myCustomVar", "hello"); // context.getVariable("request.header.x-api-key"); // var statusCode = context.getVariable("response.status.code");
39. How does Apigee compare to other API gateways such as Kong, AWS API Gateway, and MuleSoft?
Apigee sits in the enterprise API management tier alongside Kong Enterprise, AWS API Gateway, and MuleSoft Anypoint. Each has distinct strengths that make them better suited for different organisations and architectures.
| Aspect | Apigee | Kong | AWS API Gateway | MuleSoft Anypoint |
|---|---|---|---|---|
| Vendor | Google Cloud | Kong Inc. | Amazon Web Services | Salesforce |
| Best for | Large enterprise API programmes; Google Cloud users | Cloud-native/K8s; extensible plugin model | AWS-native workloads | Integration-heavy enterprise (iPaaS + API) |
| Deployment | SaaS, hybrid, Envoy adapter | Self-managed or Konnect (SaaS) | Fully managed SaaS | Cloud-managed or hybrid |
| Analytics | Built-in, very rich | Basic built-in; Vitals add-on | CloudWatch integration | Built-in Anypoint Monitoring |
| Developer portal | Built-in (Integrated or Drupal) | Dev portal add-on | None built-in | Anypoint Exchange |
| Policy model | Declarative XML policies | Lua/Go plugins | Lambda integrations | DataWeave transformations |
| Pricing model | Subscription + usage | Subscription | Per million API calls | Subscription + capacity |
Key differentiators for Apigee:
- Most complete out-of-the-box API lifecycle management (design, publish, secure, analyse, deprecate)
- Native Google Cloud integration (BigQuery analytics, Cloud Logging, IAM, Secret Manager)
- Strong hybrid support with Kubernetes-native runtime
- Best developer portal and API monetisation capabilities in the enterprise tier
40. What are common Apigee anti-patterns and best practices for production deployments?
Knowing what NOT to do is as important as knowing the policies. These anti-patterns are commonly asked about in senior Apigee interviews and architecture reviews.
| Anti-pattern | Problem | Best practice |
|---|---|---|
| Hardcoding backend URLs in proxy XML | URL breaks when environment changes; requires proxy redeployment to update | Use Target Servers (environment-scoped) for all backend URLs |
| No DefaultFaultRule | Apigee returns raw technical error messages to clients | Always define a DefaultFaultRule with a friendly JSON error response |
| Security policies in PostFlow | Auth bypass possible if a ConditionalFlow error occurs | Security policies (VerifyAPIKey, OAuthV2) must be in ProxyEndpoint PreFlow |
| Copying policies across proxies | Change in one proxy not reflected in others; drift | Extract common logic into Shared Flows and call via FlowCallout |
| Using target.url to hardcode in AssignMessage | Same as hardcoded URL issue | Use Target Servers or KVMs |
| No SpikeArrest before Quota | Sudden bursts still reach backend before Quota catches them | Always pair SpikeArrest (first) + Quota (second) for traffic management |
| Using Trace in production without restrictions | Sensitive data captured; performance impact | Restrict trace access via IAM; set short TTL on trace sessions |
| Deploying untested proxy to prod | Bugs in production | Enforce CI/CD: apigeelint + integration tests before prod promotion |
<!-- Best practice: complete PreFlow with both SpikeArrest and Quota --> <ProxyEndpoint name="default"> <PreFlow name="PreFlow"> <Request> <!-- 1. Protect from spikes first --> <Step><Name>SpikeArrest</Name></Step> <!-- 2. Validate the API key --> <Step><Name>VerifyAPIKey</Name></Step> <!-- 3. Enforce business quota (after key validation so the quota counter knows which developer) --> <Step><Name>Quota</Name></Step> </Request> <Response/> </PreFlow> <!-- 4. Always have a DefaultFaultRule --> <DefaultFaultRule name="DefaultFaultRule"> <Step><Name>AM.GenericErrorResponse</Name></Step> <AlwaysEnforce>true</AlwaysEnforce> </DefaultFaultRule> </ProxyEndpoint>
