Azure APIM "rewrite-uri" policy - How to remove the URL suffix? - azure-api-management

I have a requirement where I have the Azure APIM public facing URL - https://api.example.com/api/v1/storenumber/ordernumber
And
Back-end service URL (Notice - There is no URL path suffix here) - https://back-end.service.com
So I need to remove "/api/v1/storenumber/ordernumber" in APIM.
How to achieve this in Azure APIM policies?
Thanks,
Aneesh.

Let's say you have APIM service with hostname my-service.azure-api.net. An API in APIM service with URL suffix my-api, and a backend URI of https://my-backend.com. And an operation in this API with URI template of my/uri/template.
So for an incoming call to
https://my-service.azure-api.net/my-api/my/uri/template
without any additional configuration APIM service will make a call to
https://my-backend.com/my/uri/template
Because by default APIM service replaces in source URI scheme+hostname+api suffix with backend URI defined for an API in question.
In most simple case when your API has only one operation you could set API suffix to api/v1/storenumber/ordernumber and operation template to /. That would result in public facing URI of
https://api.example.com/api/v1/storenumber/ordernumber
and backend URI for this operation of
https://back-end.service.com/
Of course this is approach is harder to use when you have multiple operations in API. In that case you'll need to use policies: https://learn.microsoft.com/en-us/azure/api-management/api-management-transformation-policies#RewriteURL. For that you can set your API suffix and operation URI template to anything, but add this policy into operation's inbound section:
<rewrite-uri template="/" />
what rewrite-uri policy does is overrides operation URI template for backend request.

Related

Banno Admin API for External Transfers

I am having an issue calling External Transfer Settings API. I tested other APIs and was able to get a response. Below is the URI I used for External Transfers.
https://banno.com/a/transfer-settings/api/v0/institutions/xxxx/xxxxxxx/transfer/settings/external
and the response I got is 'Cannot PUT /a/transfer-settings/api/v0/institutions/xxxx/xxxxx/transfer/settings/external'
1) Which endpoint is the the one that is failing?
The /xxxx/xxxxx/ makes it a bit ambiguous if this is the Institution External Transfer Settings endpoint (PUT /a/transfer-settings/api/v0/institutions/{institutionId}/transfer/settings/external or if it is the User External Transfer Settings endpoint (PUT /a/transfer-settings/api/v0/institutions/{institutionId}/users/{userId}/transfer/settings/external
2) Can you provide the full error response?
The error response will have an HTTP status code (which is helpful), a response body, and a header x-request-id (which is also helpful) to understand what is occurring.

Get traceparent generated by APIM and return from response header

By correlate requests in Azure APIM and Application Insight with W3C distributed tracing Azure, if the client dose not send the traceparent header, seems APIM would checks the incoming request and if no traceparent, the APIM would generate and set from the request goes to backend.
In this case, we would like to return the traceparent information from the frontend response header so the consumer who inoke the API would get it, they could report API issue with this traceparent id so we can better trace/diagnose it with service log.
The question is how to get the APIM generated traceparent from inbound/outbound policy, please suggest a approach, thanks !
The traceparent HTTP header field identifies the incoming request in a tracing system. The traceparent describes the position of the incoming request in its trace graph in a portable, fixed-length format.
If the traceparent HTTP header is not available then, you can set it by using the set-header policy of API Management policies. The set-header policy is used to assigns a value to an existing response and/or request header or adds a new response and/or request header.
When placed in an inbound pipeline, this policy sets the HTTP headers for the request being passed to the target service. When placed in an outbound pipeline, this policy sets the HTTP headers for the response being sent to the gateway’s client.
The below snippet shows how you can set a new correlation context header if none is available.
<set-header name="traceparent" exists-action="skip">
<value>#($"00-{context.RequestId.ToString("N")}-0000000000000000-01")</value>
</set-header>
With the context.RequestId.ToString("N") you get the internally correlated id of the request and format it without dashes. But don't forget to set the correlation format in the Settings tab to W3C.
And with this you will get the traceparent in the header section of your request.
I would suggest you to read this W3C document on traceparent headers and Correlation headers using W3C TraceContext for more information.

Azure APIM Gateway is trimming the trailing slash in the api url

I have a requirement to add trailing slash to the APIs hosted in APIM. However, APIM gateway seems to be removing the trailing slash when forward the call to backend service.
Example 1:
APIM Gateway URL: https://api.domain.com/getdata/
Backend service URL: https://mybackendservice.domain.com/getdata
Example 2:
APIM Gateway URL: https://api.domain.com/getdata/?q=1&r=2
Backend service URL: https://mybackendservice.domain.com/getdata?q=1&r=2
Can someone please suggest any URL rewrite policies we can add to retain the trailing slash, so that the backend service urls would be:
https://mybackendservice.domain.com/getdata/
https://mybackendservice.domain.com/getdata/?q=1&r=2
Thank you Vitaliy Kurokhtin ,Posting your suggestion as an answer to help other community members.
"Let's say you have APIM service with hostname my-service.azure-api.net. An API in APIM service with URL suffix my-api, and a backend URI of https://my-backend.com. And an operation in this API with URI template of my/uri/template.
So for an incoming call to
https://my-service.azure-api.net/my-api/my/uri/template
without any additional configuration APIM service will make a call to
https://my-backend.com/my/uri/template
Because by default APIM service replaces in source URI scheme+hostname+api suffix with backend URI defined for an API in question.
In most simple case when your API has only one operation you could set API suffix to api/v1/storenumber/ordernumber and operation template to /. That would result in public facing URI of https://api.example.com/api/v1/storenumber/ordernumber
and backend URI for this operation of
https://back-end.service.com/
Of course this is approach is harder to use when you have multiple operations in API. In that case you'll need to use policies: Rewrite URL |MS DOC . For that you can set your API suffix and operation URI template to anything, but add this policy into operation's inbound section:
<rewrite-uri template="/" />
what rewrite-uri policy does is overrides operation URI template for backend request"
Reference:
Azure APIM "rewrite-uri" policy - How to remove the URL suffix?

Getting the URL for a bucket or an object using oci-java-sdk

I have already a code to retrieve the objects in the bucket using oci-java-sdk and this is working as expected. I would like to retrieve the URL of the file which was uploaded to the bucket in object storage and when I use this URL, this should redirect to the actual location without asking any credentials.
I saw preauthenticated requests but again i need to create one more request. I dont want to send one more request and want to get URL in the existing GetObjectResponse.
Any suggestions>
Thanks,
js
The URL of an object is not returned from the API but can be built using information you know (See Update Below!). The pattern is:
https://{api_endpoint}/n/{namespace_name}/b/{bucket_name}/o/{object_name}
Accessing that URL will (generally, see below) require authentication. Our authentication mechanism is described at:
https://docs.cloud.oracle.com/en-us/iaas/Content/API/Concepts/signingrequests.htm
Authentication is NOT required if you configure the bucket as a Public Bucket.
https://docs.cloud.oracle.com/en-us/iaas/Content/Object/Tasks/managingbuckets.htm?TocPath=Services%7CObject%20Storage%7C_____2#publicbuckets
As you mentioned, Pre-authenticated Requests (PARs) are an option. They are generally used in this situation, and they work well.
https://docs.cloud.oracle.com/en-us/iaas/Content/Object/Tasks/usingpreauthenticatedrequests.htm
Strictly speaking, it is also possible to use our Amazon S3 Compatible API...
https://docs.cloud.oracle.com/en-us/iaas/Content/Object/Tasks/s3compatibleapi.htm
...and S3's presigned URLs to generate (without involving the API) a URL that will work without additional authentication.
https://docs.aws.amazon.com/AmazonS3/latest/dev/ShareObjectPreSignedURL.html
Update: A teammate pointed out that the OCI SDK for Java now includes a getEndpoint method that can be used to get the hostname needed when querying the Object Storage API. https://docs.cloud.oracle.com/en-us/iaas/tools/java/1.25.3/com/oracle/bmc/objectstorage/ObjectStorage.html#getEndpoint--

Api Management return empty response if origin header is present

I am doing post request to API via Azure ApiManagement.
If Origin header is present and its not one of specified in Cors policy even postman will return empty response.
As soon as I disable Origin header I can get response.
So problem is following for web based application we must enable cors,
<cors allow-credentials="true">
<allowed-origins>
${env:CorsOrigin}
</allowed-origins>
<allowed-methods>
<method>*</method>
</allowed-methods>
<allowed-headers>
<header>*</header>
</allowed-headers>
</cors>
But our cordova app is also calling same api, and by default cordova will append Origin: file:// Then Api management is doing strange things it will cut body. So response will be empty. If i do same request directly to azure function, I will get proper response back, and since cordova does not care (To a degree in our case is ok) about CORS I would expect api management not to cut response.
Also Api management will not allow me to enter *, because of allow-credentials="true" and also I can't set it to allow file://
APIM does not support origin with file scheme, only http and https. I'll see if we can fix it. But there the workaround for allow-origins=* and allow-credentials=true is to use expressions:
<allowed-origins>
<origin>#(context.Request.Headers.GetValueOrDefault("Origin", "*"))</origin>
</allowed-origins>
This way response will contain sent Origin header value in Access-Control-Allow-Origin and not just * which is not allowed.