DEV Community

realNameHidden
realNameHidden

Posted on

Your Backend Sends 200 OK Even When an Order Fails — How Do You Fix It in Apigee X?

Learn how to fix incorrect 200 OK responses in API Proxies in Apigee X and return proper error codes using policies and fault handling.


Introduction: The “It Worked… But Actually Didn’t” Problem 😬

Imagine this.

A client application places an order.
Your backend fails the order due to insufficient balance or inventory issues.
But the API response still says:

HTTP/1.1 200 OK
{
  "status": "FAILED",
  "reason": "INSUFFICIENT_FUNDS"
}
Enter fullscreen mode Exit fullscreen mode

From the client’s point of view, the request succeeded.

This is a very common real-world problem in modern systems—especially in payments, BFSI, and microservices architectures.

This is where API Proxies in Apigee X shine.

In this blog, you’ll learn:

  • Why this problem happens
  • Why it’s dangerous
  • How to modify responses in Apigee X to return the correct HTTP status codes
  • Best practices you can apply immediately

What Is an API Proxy in Apigee X?

An API proxy in Apigee X sits between:

  • Client apps
  • Backend services

Think of it like a smart translator + traffic controller:

  • It understands backend responses
  • It can modify headers, body, and status codes
  • It enforces API standards without touching backend code

ELI5 Analogy 🧒

Your backend is like a kitchen.

  • The kitchen knows the food is burnt
  • But the waiter still tells the customer: “Your food is ready!”

👉 Apigee X is the head waiter who checks the plate before serving and says:

“Nope. This should go back with the right message.”


Why Returning 200 OK on Failure Is a Bad Idea ❌

Problem Impact
Client assumes success Data inconsistency
Retries don’t trigger Orders get stuck
Monitoring misses failures SLA violations
Violates REST standards Poor API design

Correct HTTP semantics are critical for:

  • API consumers
  • Observability
  • Reliability
  • API security

Step-by-Step: Fixing This in Apigee X (Beginner-Friendly)

Scenario

  • Backend always returns HTTP 200
  • Business failure is inside response body
  • We want Apigee X to:

    • Detect failure
    • Convert it to proper HTTP error code

Step 1: Example Backend Response (Problematic)

{
  "orderStatus": "FAILED",
  "errorCode": "ORDER_REJECTED",
  "message": "Order could not be processed"
}
Enter fullscreen mode Exit fullscreen mode

Step 2: Add an AssignMessage Policy in Response Flow

<AssignMessage name="AM-Set-Error-Response">
    <AssignTo createNew="false" transport="http" />
    <Set>
        <StatusCode>400</StatusCode>
        <ReasonPhrase>Bad Request</ReasonPhrase>
    </Set>
</AssignMessage>
Enter fullscreen mode Exit fullscreen mode

Step 3: Add a Condition (Only Modify When Order Fails)

Attach the policy in the TargetEndpoint Response with a condition:

<Step>
    <Name>AM-Set-Error-Response</Name>
    <Condition>
        response.content AsString matches "FAILED"
    </Condition>
</Step>
Enter fullscreen mode Exit fullscreen mode

✅ Now Apigee X returns:

HTTP/1.1 400 Bad Request
Enter fullscreen mode Exit fullscreen mode

Step 4: (Optional) Use RaiseFault for Cleaner Error Design

<RaiseFault name="RF-Order-Failed">
    <FaultResponse>
        <Set>
            <StatusCode>422</StatusCode>
            <ReasonPhrase>Unprocessable Entity</ReasonPhrase>
            <Payload contentType="application/json">
                {
                  "error": "ORDER_FAILED",
                  "message": "Order processing failed at backend"
                }
            </Payload>
        </Set>
    </FaultResponse>
</RaiseFault>
Enter fullscreen mode Exit fullscreen mode

Attach it conditionally the same way.


When Should You Use This Pattern?

Common Real-World Use Cases

  • Payments declined but backend returns 200
  • Inventory failure masked as success
  • Legacy systems that can’t change response codes
  • Partner APIs with inconsistent contracts

Best Practices for Apigee X Response Handling ✅

1️⃣ Never Trust Backend HTTP Status Blindly

Always validate business status, not just HTTP code.

2️⃣ Standardize Error Codes at the Proxy Layer

Use Apigee X to enforce REST standards consistently.

3️⃣ Prefer RaiseFault for Business Errors

It gives:

  • Cleaner error handling
  • Centralized fault logic
  • Better observability

4️⃣ Log Before Modifying Responses

Use MessageLogging to avoid blind debugging.

5️⃣ Don’t Overuse Regex on Large Payloads

For complex logic, use JavaScript policy instead.


Common Mistakes to Avoid ❌

  • Returning 200 with error messages
  • Modifying responses without conditions
  • Hardcoding logic per backend
  • Ignoring API monitoring and analytics

Conclusion: Apigee X = Control Without Backend Changes 🎯

To summarize:

  • Backends returning 200 OK on failure is common
  • It breaks API contracts and client logic
  • API Proxies in Apigee X give you full control
  • You can fix response codes without touching backend code

This is one of the most powerful—and underrated—capabilities of API management.


Call to Action 💬

Have you faced this issue in real projects?

👇 Comment below:

📌 Follow for more Apigee X, API security, and API traffic management insights.


Top comments (0)