I am trying to use validate-content policy to validate the json payload of my requests in Azure APIM. My API request payloads will have a property called schemaName. For example the request payload will be like this: { "schemaId":"app1-schema1", "propertyAbc": 123 } In APIM > Schemas, I have saved multiple json schemas with names like "app1-schema1", "app1-schema2", etc. To do the validation in API, I have include this inbound snippet:
<policies>
<inbound>
<set-variable name="Schema" value="@(context.Request.Body.As<JObject>(true)["schemaId"].Value<string>())" />
<validate-content unspecified-content-type-action="prevent" max-size="102400" size-exceeded-action="prevent" errors-variable-name="validateError">
<content type="application/json" validate-as="json" action="prevent" schema-id="@(context.Variables["Schema"])" />
</validate-content>
<base />
</inbound>
<backend>
<base />
</backend>
<outbound>
<base />
</outbound>
<on-error>
<base />
</on-error>
</policies>
I am unable to save this policy configuration from Azure Portal. I get the following error: One or more fields contain incorrect values: Error in element 'validate-content' on line 16, column 10: The schema @(context.Variables["Schema"]) does not exist. If I hardcode the value of schema-id to be "app1-schema1", then i am able to save the policy configuration. Does this mean one cannot dynamically set the name of the schema-id property?
Yes, it looks like
schema-idinvalidate-contentpolicy accepts static values and throwing error for expressions like '@{}' and '@()'.You can provide the value of schema-id parameter explicitly or can skip it too, as its an optional parameter.
If you want to pass it dynamically, you can set the schema-id values in Named Values and use it as given below-
There is an alternative way to add the schema definition in API level, if you don't want to hardcode the value of schema-id.
Click on definitions
Enter the definition name and add a sample Json to generate the payload and then click on Create definition.
Once the definition is created, you can use it in your operation directly as shown below.
Select the definition from the dropdown.
Once the schema is added, no need to pass the schema-id in the policy.
By using this policy, I am able to get expected response.