Search code examples
azure-api-managementibm-api-management

API Management Conditional Flow Policy


I have the following request data

{
   "id": "1115e297-12de-4189-8e11-75a8354f77d6",
   "type": "transaction",
   "version": "1.0.0",
   "data": {
      "account_id": "999",
      "customer_info": {
         "client_id": 999
      },
      "company_id": "999999",
      "event": {
         "id": 99999999,
         "type_code": "3098"
      }
   }
}

I want to write a policy that ignores the request unless the type is "transaction" and the type_code is "3098" or "3099"

If this is not satisfied then it should just return the id of the request to the caller and not forward on the request

Here is what I have come up with

    <choose>
            <when condition="@((string)context.Request.Body?.As<JObject>(true)["type"] != "transaction")">
                <return-response>
                    <set-status code="200" reason="OK" />
                    <set-header name="Content-Type" exists-action="override">
                        <value>application/json</value>
                    </set-header>
                    <set-body>@{ 
                        var json = new JObject( 
                            new JProperty("id", context.Request.Body?.As<JObject>(true)["id"])
                        ); 

                        return json.ToString(); 
                    }</set-body>
                </return-response>
            </when>
            <when condition="@(context.Request.Body?.As<JObject>(true)["data"] == null || context.Request.Body?.As<JObject>(true)["data"]["event"] == null)">
                <return-response>
                    <set-status code="200" reason="OK" />
                    <set-header name="Content-Type" exists-action="override">
                        <value>application/json</value>
                    </set-header>
                    <set-body>@{ 
                        var json = new JObject( 
                            new JProperty("id", context.Request.Body?.As<JObject>(true)["id"])
                        ); 

                        return json.ToString(); 
                    }</set-body>
                </return-response>
            </when>
            <when condition="@((int)context.Request.Body?.As<JObject>(true)["data"]["event"]["type_code"] != 3098 && (int)context.Request.Body?.As<JObject>(true)["data"]["event"]["type_code"] != 3099)">
                <return-response>
                    <set-status code="200" reason="OK" />
                    <set-header name="Content-Type" exists-action="override">
                        <value>application/json</value>
                    </set-header>
                    <set-body>@{ 
                        var json = new JObject( 
                            new JProperty("id", context.Request.Body?.As<JObject>(true)["id"])
                        ); 

                        return json.ToString(); 
                    }</set-body>
                </return-response>
            </when>
        </choose>

I'm tipping there is a much more elegant way to do this?


Solution

  • Sure. Provided all you return-response policies are the same you can use multiline expression:

    <set-variable name="payload" value="@((string)context.Request.Body?.As<JObject>(true))" />
    <choose>
        <when condition="@{
            var payload = (JObject)context.Variables["payload"];
            if (payload?["type"] != "transaction"
                || payload?["data"]?["event"]?["type_code"] != 3099)
            {
                return true;
            }
        }">
            <return-response>
                <set-status code="200" reason="OK" />
                <set-header name="Content-Type" exists-action="override">
                    <value>application/json</value>
                </set-header>
                <set-body>@{ 
                    var payload = (JObject)context.Variables["payload"];
    
                    var json = new JObject( 
                        new JProperty("id", payload?["id"])
                    ); 
    
                    return json.ToString(); 
                }</set-body>
            </return-response>
        </when>
    </choose>