Azure API management can truncate your operation ID and mess your next upload!
Azure API management is without any doubt a great tool to manage your APIs catalog but you can have some surprise about undocumented restrictions.
Let’s take a real quick example. Try to create a new API and upload this OpenAPI specification:
openapi: 3.0.1
info:
title: My super API
version: 1.0.0
paths:
/contracts/[contractId]/versions/[versionNumber]/administration/contact-informations:
get:
responses:
200:
description: Valid response
content: {}
/contracts/[contractId]/versions/[versionNumber]/administration/contact-informations/[contactId]:
get:
responses:
200:
description: Valid response
content: {}
The initial upload should be successful. As you can notice the specification is one of the most simple you could see. Only 2 get operations, no security setting, no model description, …
You maybe noticed I used brackets for path parameters instead of curly brackets. It’s just to keep the specification small. If I had used curly brackets I would have been forced to describe every parameter which is irrelevant for this demonstration.
Now try to upload the following specification using the update mode meaning the new specification will totally replace the previous one. No merge attempt.
It’s exactly the same one except the first operation has been deleted:
openapi: 3.0.1
info:
title: My super API
version: 1.0.0
paths:
/contracts/[contractId]/versions/[versionNumber]/administration/contact-informations/[contactId]:
get:
responses:
200:
description: Valid response
content: {}
Despite the totally valid scenario and the really simple specification you’ll get an error:
Operation with the same method and URL template already exists: GET, /contracts/[contractId]/versions/[versionNumber]/administration/contact-informations/[contactId]
Actually the issue is pretty simple to understand. Every operation in an OpenAPI specification should have an operation ID. This ID is what allows us (or API Management) to uniquely identify a single operation. Since we did not provide them (you can check the specifications, those are missing) Azure API Management will generate them.
According to the documentation:
If operationId isn’t specified (not present, null, or empty), Azure resource name value will be generated by combining HTTP method and path template.
This way of doing it is quite simple but efficient: The combination method/URL will always be unique within an API specification.
So now let’s check the existing API (uploaded with first specification) and let’s export the specification from Azure API Management. We see in the export some operation ID have indeed been generated :
- operationId: get-contracts-contractid-versions-versionnumber-administration-contact-infor
- operationId: get-contracts-contractid-versions-versionnumber-administration-contact-infor-1
As expected the operation ID is generated following the rules (and some special characters replacement) but we also notice the URL is not complete. The operation ID has an undocumented max length and in order to comply to it the operation ID is truncated after its generation.
In our case both operations have almost the same URL. Meaning the truncated operation IDs will have the same value.
In order to solve that Azure API Management will affect some numbers to the duplicated operation IDs.
In the second specification we removed the first operation. Meaning the second operation is now the only one. The operation ID that was affected to the first operation is now affected to the second operation.
And it seems Azure API management does not like to see the exact same operation ID applied to another method/URL. Which is still strange because the second upload was in “update” mode and should totally ignore the existing operations.
What if I provide my own operation IDs?
Of course you should provide your own operation IDs (it’s actually recommended by Microsoft) but does it solve the issue?
Absolutely not.
The max length restriction still exists and the truncation is still applied so the exact same issue can occur even if you provide your own operation ID.
What is the reliable solution?
You probably guessed the solution by now: You have to provide your own operation IDs and ensure they are less than the max length (around 70 characters).