Handling request at Azure APIM

Azure API management (APIM) to Interact with API

Prerequisite

  • Knowledge of setting up Azure APIMs.
  • Knowledge of C#

Introduction

In a typical request flow, an http request starts from a mobile app or a web browser, and the http request reaches an API that communicates with some database somewhere in its path. It could be possible that there are different types of http requests which need the same response from the backend API.

Problem

Consider a scenario where you have two kinds of jwt tokens for the user. One for mobile and one for browser. The mobile token does not contain a user id, whereas the browser token has a user id as a claim. Both need to call an endpoint “get user details”. Our endpoint expects the customer id to be part of the route only. Mobile provides the user id as part of the route, and the browser only sends the customer id as part of the token.

This problem can be solved without touching the API code and simply handling the request in APIM.

Solution

For mobile, it seems straightforward. However, for a website, we have handled this in APIM. We create an APIM endpoint with the URL “GET: /GetUserDetails/{userId}”

We can create an APIM endpoint for the website with url “GET: /GetUserDetails”.

Now mobile requests will go to our first endpoint, and website requests will go to the second endpoint, and we can handle both requests separately.

Mobile request

We can write the following code to handle the mobile request and forward it to API.

<policies>
  <inbound>
    <base />
    <set-backend-service base-url="<your base url here>" />
    <set-header name="content-type" exists-action="override">
      <value>application/json</value>
    </set-header>
    <rewrite-uri template="@($&quot;/api/getuserdetails/{userId}&quot;)" />
  </inbound>
  <backend>
    <base />
  </backend>
  <outbound>
    <base />
  </outbound>
  <on-error>
    <base />
  </on-error>
</policies>

This will access the request from mobile and send it to your API.

Website Request

We can write the following code to handle website requests and forward them to API.

<policies>
  <inbound>
    <base />
<validate-jwt header-name="Authorization" failed-validation-httpcode="401" failed-validation-error-message="The access token is invalid." require-expiration-time="true" require-scheme="Bearer" require-signed-tokens="true" output-token-variable-name="jwtToken">
                    <openid-config url="<your authentication portal base address>/.well-known/openid-configuration" />
                    <audiences>
                        <audience><Audience></audience>
                    </audiences>
                    <issuers>
                        <issuer><Issuer></issuer>
                    </issuers>
                    <required-claims>
                        <claim name="sub" />
                        <claim name="userId" />
                    </required-claims>
</validate-jwt>
<set-variable name="userId" value="@(((Jwt)context.Variables["jwtToken"]).Claims.GetValueOrDefault("userId", ""))" />

<set-backend-service base-url="https:<your base url here>" />
<set-header name="content-type" exists-action="override">
   <value>application/json</value>
</set-header>
<rewrite-uri template="@($&quot;/api/getuserdetails/{(string)context.Variables[&quot;userId&quot;]}&quot;)" />
</inbound>
  <backend>
    <base />
  </backend>
  <outbound>
    <base />
  </outbound>
  <on-error>
    <base />
  </on-error>
</policies>

Conclusion

This way, we can handle two types of requests for the same endpoint without touching our backend API code and reduce some burden from our API.

References

Cheers.