In today’s post, I want to talk about using Azure API Management (APIM) along Dynamics 365 Finance and Operations.

Azure API Management is a hybrid, multi-cloud management platform for APIs across all environments. This means that, after deploying an APIM account, you can create an API that can serve services from one system or multiple.

Why would I put Azure API Management in front of D365’s services/OData?

That’s a legitimate and excellent question. We already have OData and custom web services, and both can be easily accessed.

Well, of course OData and WS are perfectly fine, but by using Azure API Management we can add an extra layer of several things:

  • Add extra security and decoupling your APIM API from the backend one. Forget about passing the Azure AD App ID and secret to an external provider, you can manage that inside APIM and give an API Key to whoever is consuming your API.
  • Add limit call rates, or usage quotas.
  • Validate the request or response body.
  • Validate parameters.
  • Custom policies and custom responses.

And of course, you can have several backends in a single API. This means you could have the CRM WebAPI and ERP OData endpoints in the same URL. And also deploy a self-hosted gateway to connect to support hybrid and multi-cloud environments.

And a lot more feature, I’ve just scratched on the surface of Azure API Management.

Use it with Dynamics 365 F&O

Create API Management account

Go to your Azure account and look for “API Management services” in the top search bar. Select create and fill in all the fields.

Regarding the pricing tier, I’d go with the “Consumption” one which gives us a million calls per subscription, and after that it’s like 3 cents/10K calls. Keep in mind that if you wish to have a developer portal with your API’s documentation, you’ll need to get any of the other tiers.

When creating the API Management, you can also enable Application Insights and select several protocols. All of these can be enabled or changed after creating the APIM.

Depending on the tier you’ve selected, the APIM will take from minutes to up to an hour to be deployed. If the tier includes a developer portal, it’ll take more time.

Create an API

Now it’s time to create a new API, so head to the API menu on the left. You have several choices:

Azure APIM Management new API screen
Azure APIM Management new API screen

You can import OpenAPI definitions, WSDL for SOAP services, etc. but we’ll choose the HTTP one. Give it a name and enter your Dynamics 365 environment URL, including the /data in this case because I’ll be showing it using OData.

Create new API
Create new API

If you were creating an API Management for custom web services you’d add the /api/services suffix.

The Designer

I won;t go much into detail but this is something it’s worth mentioning. The designer gives us a clue about how API Management work:

APIM design
APIM design

You can see a “Frontend” which is our APIM API URL and where the user will make a request.

Then an “Inbound processing” box where you can set some rules before that will be applied to the incoming request and passed to the “Backend” API.

And finally an “Outbound processing” box where the backend API sends the request and where we can change some things before returning them to the “Frontend” and display them to the customer that called the APIM API.

Create new operation

Now we need to create a new operation, so click on Add operation and fill in the fields:

Create APIM Operation
Create APIM Operation

Click save and let’s test it! Go to the Test tab, copy the request URL and paste it to a different tab and let magic happen!

Azure APIM Access denied
Not much magic

Too quick! Go to the settings tab, and you’ll see a Subscription section:

Subscription section

And now you can do two things:

  1. Uncheck the subscription required box.
  2. Add a header parameter to the URL with the value of your subscription key, found on the “Subscriptions” menu on the left. That’d leave our URL as https://apimd365.azure-api.net/CustomerGroups?subscription-key=YOUR_SUBSCRIPTION_KEY.

But wait, there’s one more thing missing, and you must be asking how would I access an OData endpoint without getting the bearer token first. You’re totally right.

Get the token

Each time we call a Dynamics 365 F&O OData endpoint or web service, we need to authenticate with the bearer token. We’ll solve this thanks to the policies. GO back to the design tab and click the code symbol in the “Inbound processing” section while “All operations” is selected:

Inbound policies
Inbound policies

An XML editor will appear, and you need to add an Azure App ID and secret here to get the token and authenticate:

<!--
    IMPORTANT:
    - Policy elements can appear only within the <inbound>, <outbound>, <backend> section elements.
    - To apply a policy to the incoming request (before it is forwarded to the backend service), place a corresponding policy element within the <inbound> section element.
    - To apply a policy to the outgoing response (before it is sent back to the caller), place a corresponding policy element within the <outbound> section element.
    - To add a policy, place the cursor at the desired insertion point and select a policy from the sidebar.
    - To remove a policy, delete the corresponding policy statement from the policy document.
    - Position the <base> element within a section element to inherit all policies from the corresponding section element in the enclosing scope.
    - Remove the <base> element to prevent inheriting policies from the corresponding section element in the enclosing scope.
    - Policies are applied in the order of their appearance, from the top down.
    - Comments within policy elements are not supported and may disappear. Place your comments between policy elements or at a higher level scope.
-->
<policies>
    <inbound>
        <base />
        <send-request mode="new" response-variable-name="bearerToken" timeout="20" ignore-error="true">
            <set-url>https://login.microsoftonline.com/YOUR_TENANT/oauth2/token</set-url>
            <set-method>POST</set-method>
            <set-header name="Content-Type" exists-action="override">
                <value>application/x-www-form-urlencoded</value>
            </set-header>
            <set-body>@{ return "client_id=YOUR_CLIENT_ID&resource=ENVIRONMENT_URL&client_secret=YOUR_SECRET&grant_type=client_credentials"; }</set-body>
        </send-request>
        <set-header name="Authorization" exists-action="override">
            <value>@("Bearer " + (String)((IResponse)context.Variables["bearerToken"]).Body.As<JObject>()["access_token"])</value>
        </set-header>
        <retry condition="@(context.Response.StatusCode == 429)" count="3" interval="20" max-interval="60" delta="20" first-fast-retry="false" />
    </inbound>
    <backend>
        <base />
    </backend>
    <outbound>
        <base />        
    </outbound>
    <on-error>
        <base />
    </on-error>
</policies>

You can copy this and just change the YOUR_TENANT, YOUR_CLIENT_ID, ENVIRONMENT_URL and YOUR_SECRET values. And now we can go back to the browser, paste our APIM URL and subscription key if you’ve left it enabled and:

Customer groups in APIM
Customer groups in APIM

We’ve successfully retrieved the customer groups through our API Management endpoint!

More good things

As you all know, Dynamics 365 F&O has throttling enabled, and in case there’s an operation that fails due to it, we’ll get a 429 response. We can implement retry policies in our API Management and whoever is using our APIM API can forget about doing it.

Go back to the Design tab and click on any of the code editors for policies, then in the backend node add:

<retry
    condition="@(context.Response.StatusCode == 429)"
    count="10"
    interval="10"
    max-interval="100"
    delta="10"
    first-fast-retry="false">
</retry>

This will do up to 10 retries. Isn’t it cool?

Use cases

I wouldn’t put an API Management in front of each Dynamics 365 implementation, of course, but there might be some scenarios where there are several 3rd parties accessing data, and you want to keep some control over who is accessing what.

Being able to enable Application Insights can also give us more detail on the usage and errors than LCS too.

And there’s a ton of other policies that you can set at the inbound, backend or outbound level. As I said I’ve only tried this a bit, but it has a lot of potential uses for Dynamics, now it’s your turn to try it out!

Subscribe!

Receive an email when a new post is published
Author

Microsoft Dynamics 365 Finance & Operations technical architect and developer. Business Applications MVP since 2020.

6 Comments

  1. Pingback: D365 F&O/Commerce interfacing via Azure API Management: My Best Practices Kopiëren - Patrick Mouwen

  2. Pingback: Logs en Dynamics 365: ¡nunca más! - ariste.info

  3. Florian Hopfner Reply

    Nice article. I played around today with APIM and got the scenario described here working no problem. Thanks a lot, the policies would have taken some time to figure out. And there is a lot to explore, products, named values, backends, versions and revisions, …
    Also love the built in monitoring with application insights. This should be very useful in an upcoming project.

    • Adrià Ariste Santacreu Reply

      Thanks Florian! Yes the policies can be really complicated, there are some examples in the docs if you want to check them.

  4. Marcelo jose Alves Reply

    Excellent article. I am currently participating in an effort to document and segment new custom services in D365FO, which will be used by various Hubs and software partners. With APIM, in addition to not exposing the AppID and AppSecret and production endpoint, I can create subscriptions for each integrator, better controlling the services that each one can interact with.

    • Adrià Ariste Santacreu Reply

      Thanks Marcelo! I’m actually also working on something with the APIM, with additional logging using an Event Hub to have better understanding of why something is going wrong in case the API returns an error.

Write A Comment

This site uses Akismet to reduce spam. Learn how your comment data is processed.

ariste.info