Controlling Azure Functions Invocation by Azure API Management

Azure Functions provides the feature to invoke a function using HTTP Trigger.  Functions can be invoked directly by keeping the function url which has the host key along with the function url.

Typical function url is usually of the below format.

https://functionappname.azurewebsites.net/api/FunctionName?code=key

It is not recommended to share the secure code to invoke the functions in a production environment.  This can be controlled by using Azure API Management, where the clients are provided with a different url instead of the function url.

Using an Azure API Management, provides some of the below benefits.

  • Can implement throttling mechanism to control the number of requests
  • Control access by subscription id and keys.
  • Perform analytics on the consumption of the API.
  • Extract reports to understand the consumption behavior.
  • Perform secure configuration to control the access of API.

Below are the steps used to invoke an Azure function from Azure API Management.

In this scenario, I have created a simple function which uses default template and triggered using HTTP.  Verifying the function by triggering the function and check if proper response is received from the function. Use the test window in azure functions to check the function.

API1

Once the function is verified. Use the below steps to create azure API Management. Login  to portal.azure.com and use your azure account and click on New in azure portal.

API1

Click on Create and provide all mandatory values to create the API Management Portal.

API1

Provide a valid administrator email and select an appropriate pricing tier. I have selected the developer portal. This administrator email will default be given developer access.

It would take around 10 minutes to activate and access the API Management overview. Azure API Management, by default has two portals.

  1. Publisher Portal
  2. Developer Portal

Publisher portal is used to develop the APIs and operations and define the policies. This is where all the development takes place.

Developer portal is used to test the published APIs and verify the trace logs of the APIs.

Open the publisher portal and create an API. API can be created by importing API or selecting Add API. Since the azure function which we are using does not have any swagger implementation, I have selected the ADD API option.

API1

Provide the values to define the API by providing an api name and description. The webservice url mentioned here corresponds to the host name of the function url.

https://functionappname.azurewebsites.net/

Provide value for web api url suffix and select the url scheme as HTTPS. This step also shows the url which external clients will be using to consume the API.

API1

Once the API is created, the next step is to create an operation in the API. The operation step defines the http verb and the url templates , request and responses formats.

API1

Url Template is used to define the actual REST API operation which will be used by client.

Rewrite Url template is mainly used to transform the request corresponding to the actual function url with the code used to consume the function. These secure codes are not visible to the client consuming the APIs.

Next step is to define the request Body and response which would be given by the API.

Provide a description and click on Add Representation. Provide the content type as application/json and paste the sample request format which will be accepted by the API.

API1

I have configured to return responses with status 200 and 400. Below steps provide the configuration for the same.  It is required to define the response format by selecting Add representation as application/json and mention the sample response for each HTTP status codes. The response format should match the response format returned by azure function.

API1

API1

Save the operation changes.

In order to publish the API and make it visible from outside, it is required to map the created API to a product.

By default Azure provides two products which are Starter and Unlimited.

API1

In my case I have added the created API to Starter product by clicking on Add API  to Products. Usually developers can be provided access to Started product as it controls the execution of the function.  We can also create our own product.

After adding API to Starter product, click on the Starter value. This will navigate to the product screen displaying the values of the product and other APIs which are part of the product.

API1

In order to consume the API in developer portal we need to Publish the product. On publishing the status changes to Published. The subscribers tab shows the users which are given access to consume the APIs in the product and we can also control the visibility of API among users and groups.

We can define policies in the publisher portal against the product and API which is not covered in this example. For now I have not defined any policies.

We can test the above API by navigating to developer portal.

API1

Here we can see that the API displayed in the developer portal. Since in my case am the administrator , I have access to the default Products. If we are using custom username other than administrator account to test the API in developer portal, we would need to request subscription. Once subscribed we can test the API.

Click on the API which we desire to test. This navigates to screen displaying all metadata of the API along with the request format and response formats and the code to consume in different clients.

API1

Click on the Try It button to test the API.  On providing valid values in the request we can test the API by clicking on Send Button. This invokes the API and provides the response returned from the back end service. In this case the back end service is the azure functions url.

Below is the raw format of the request posted from try it window. In order to access an API exposed by Azure it is required to pass the Subscription-Key as part of the header of request.  Providing trace options as true will enable the trace window in the response.

[code language="javascript"]
POST https://btest.azure-api.net/testazfunction/api/HttpTriggerCSharp1 HTTP/1.1
 Host: btest.azure-api.net
 Content-Type: application/json
 Ocp-Apim-Trace: true
 Ocp-Apim-Subscription-Key: ••••••••••••••••••••••••••••••••
{
   "name" : "test"
 }
[/code]

Below is the response displayed in the developer portal. Clicking on the trace tab provides a detailed trace of the request.

API1

On inspecting the trace tab, we can see how the incoming request to API is forwarded to actual Azure functions url.

The below displays the from portion and to portion and other fields which were mentioned as part of the Operation set up. This also displays the groups which have access to the API and which product the API is part of.

{ "configuration": { "api": { "from": "/testazfunction", "to": { "scheme": "https", "host": "btestfunction.azurewebsites.net", "port": 443, "path": "/", "queryString": "", "query": {}, "isDefaultPort": true }, "version": null, "revision": "1" }, "operation": { "method": "POST", "uriTemplate": "/api/HttpTriggerCSharp1" }, "user": { "id": "1", "groups": [ "Administrators", "Developers" ] }, "product": { "id": "starter" } } }

Rewrite url defined in the operation is used to construct the actual url to which request has to be posted.

rewrite-uri (1 ms){
"message": "Updated request URL per specified rewrite template.",
"request": {
"url": "<a href="https://btestfunction.azurewebsites.net/api/HttpTriggerCSharp1?code=XXYXYXUBIABSIASSASI">https://btestfunction.azurewebsites.net/api/HttpTriggerCSharp1?code=XXYXYXUBIABSIASSASI</a>"
}
}

The above rewrite url is used by API to post the incoming request to azure functions url.

{ "message": "Request is being forwarded to the backend service.", "request": { "method": "POST", "url": "<a href="https://btestfunction.azurewebsites.net/api/HttpTriggerCSharp1?code=YYJJBJGUOGGGGUGOOOG">https://btestfunction.azurewebsites.net/api/HttpTriggerCSharp1?code=YYJJBJGUOGGGGUGOOOG</a>", "headers": [ { "name": "Ocp-Apim-Subscription-Key", "value": "deefc6db0b1d405888051fe5ea8a26e3" }, { "name": "Content-Type", "value": "application/json" }, { "name": "X-Forwarded-For", "value": "13.85.23.48" } ] } }

It is to be noted that the domain name in API url and the actual azure function url domain are different.

When there is any change to the secure code of azure functions it is required to update the secure code in the operations of the API.

 

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s