[Azure] Using Azure Functions Proxies

If you’ve started using Functions in Azure and you’ve got multiple set-up by now, you’ll start to find that managing them becomes a bit cumbersome, especially when you’ve spread them across multiple instances. All of the instances will have a different base URL and you might find it difficult to keep naming and versioning in line with what you planned. So now what? Let’s take a look at the newly released Proxies for Azure Functions!

An API proxy acts as a single point of entry for the outside world, a facade if you will. Instead of calling a service directly, it will take an incoming request and forwards it to a service sitting in the background. So your callers will only know about the proxy and don’t have to care about where the request goes internally. This gives you an extra layer of abstraction if you will, allowing all sorts of things to take place without the API user knowing about it.

Some thoughts:

  • An API route might be pointing to Function A at one point in time and then swapped to Function B. You could use this to test a new implementation or even do versioning with a “latest” implementation.
  • You can mix / match Functions with other API methods and expose them as one endpoint.
  • You could use it to forward a request to a secured (on-prem?) endpoint.
  • Your implementation ideas here (use the comments!)

 

At the time of writing, this functionality is still in preview. So the way it works is probably subject to change and might be different by the time you read this article. If you spot any mistakes, please lets me know in the comments below so I can update.

 

How does it work?

I will assume that you already have some Functions set-up. Maybe a trivial comment but these need to be Functions that are called via the web (like HTTP triggered functions), since there’s not much use setting up an proxy for functions that are triggered by a storage queue for instance (at least nothing I can think of).

One of your Function apps will serve as the proxy. You can use an existing one or create a new instance specifically for this purpose. At the moment, that function app needs to have an app setting defined named ‘ROUTING_EXTENSION_VERSION’. Use ‘latest’ as the value. This will enable the proxy functionality for that Function app.

Next, you need to start specifying the routes from your proxies to your actual endpoints. This is done in ‘proxies.json‘, or you can use the UI to edit the file. The proxies.json file looks something like this:

{
    "proxies": {
        "proxyName": {
            "matchCondition": {
                "methods": [
                    "GET"
                ],
                "route": "/values"
            },
            "backendUri": "https://my-own-func-instance.azurewebsites.net/api/values"
        }
    }
}

The most important parts:

  • proxyName: pick some name for your own convenience.
  • matchCondition: here you specify the matching rules for this particular endpoint, like the route and method. The use of querystring variables in the form of {variableName} is allowed.
  • backendUri: this is the endpoint to which the request should be forwarded. This endpoint (of course) should accept requests that match the match condition specified.

 

The UI looks like this:
functionproxy

Using a default proxy

In some cases, you might have one API in place that processes the majority of requests. In such cases, using a default proxy can come in handy so you do not need to specify all of those endpoints individually. The runtime already specifies a default proxy out of the box with the configuration seen below. It can be overridden by a custom configuration though.

"default": {
    "matchCondition": {
        "methods": [
            "ANY"
         ],
         "route": "/{*rest}"
     },
     "backendUri": "https://%WEBSITE_HOSTNAME%/{rest}"
}

Notice the %WEBSITE_HOSTNAME%? That syntax allows you to directly insert app settings into your file. Awesome feature which in my opinion should be available for way more other filetypes as well. In this case, %WEBSITE_HOSTNAME% is a default appsetting specifying the url of the app instance.

Also notice the use of matching patterns (*) which in this case would proxy all calls ending in ‘rest’ to a backend rest api.

UX_screenshot

Request overrides

Lastly, another nice feature are request overrides which can be used to transform a request, add or subtract information or provide a direct response even. There’s all kinds of possible overrides for different purposes, here’s a few samples from the proxies sample itself.

Transforming a request

"px2 - Transform header, segment and querystring": {
    "desc": [
        "Example show how you can",
        "1. Read headers (request.header.<<header name>>), segements({xyz}) and querystring (request.querystring.<<param name>>) from input request ",
        "2. Set the backend headers (backend.request.header.<<header name>>, querystring (backend.request.querystring.<<param name>>)",
        "3. Set the response headers (repsonse.header.<<header name>>), status (response.status)",
        "4. You can use AppSettings in your proxy definitons by enclosing theam with %% For e.g.%APP_SETTING_NAME%",
        "Sample input: https://<<yourhostname>>/test2/1?operation=posts&version=1.2"
    ],
    "matchCondition": {
        "methods": [
            "GET"
        ],
        "route": "/test2/{uid}"
    },
    "backendUri": "https://jsonplaceholder.typicode.com/users/{uid}/{request.querystring.operation}",
    "requestOverrides": {
        "backend.request.querystring.newkey": "request.header.me",
        "backend.request.querystring.userId": "{uid}",
        "backend.request.querystring.token": "%MY_CUSTOM_TOKEN%",
        "backend.request.header.appname": "Appname is %CUSTOM_SETTING%",
        "backend.request.header.myheaderv": "request.querystring.version"
    },
    "responseOverrides": {
        "response.header.myversion": "backend.response.header.version",
        "response.header.anotherHeader": "Some other value is %CUSTOM_SETTING%",
        "response.status": "200 FINE"
    }
},

Providing a direct response

"px6 - Example of Json output ": {
    "desc": [
        "You can set the response body to a json object.",
        "You can use this in conjunction with conditional overrrides to provie response based on status codes",
        "The is can be useful for creating mock apis for development and testing"
    ],
    "matchCondition": {
        "methods": [
            "GET"
        ],
        "route": "json/{id}"
    },
    "responseOverrides": {
        "response.status": "200 OK",
        "response.header.Content-Type": "application/json",
        "response.body": {
            "User": {
                "Id": "{id}",
                "Name": "User Name {id}"
            }
        }
    }
}

 

Conclusion

Proxies bring an interesting additional functionality to Azure Functions. Especially for API scenario’s this is very useful. Since they’re still in preview, I would recommend these for any production scenario yet. But apart from that, head over to Azure and have a go!

Update 22-02-2017: the public preview is here! Check out the official blog post @ https://blogs.msdn.microsoft.com/appserviceteam/2017/02/22/azure-functions-proxies-public-preview/

,

Related posts

Long Term Support… or not?

If you've started using Functions in Azure and you've got multiple set-up by now, you'll start to find that managing them becomes a bit cumbersome, especially when you've spread them across multiple instances. All of the instances will have a different base URL and you might find it difficult to keep naming and versioning in line with what you planned. So now what? Let's take a look at the newly released Proxies for Azure Functions!

[DevOps] Should you migrate onto YAML release pipelines?

If you've started using Functions in Azure and you've got multiple set-up by now, you'll start to find that managing them becomes a bit cumbersome, especially when you've spread them across multiple instances. All of the instances will have a different base URL and you might find it difficult to keep naming and versioning in line with what you planned. So now what? Let's take a look at the newly released Proxies for Azure Functions!

Latest posts

Long Term Support… or not?

If you've started using Functions in Azure and you've got multiple set-up by now, you'll start to find that managing them becomes a bit cumbersome, especially when you've spread them across multiple instances. All of the instances will have a different base URL and you might find it difficult to keep naming and versioning in line with what you planned. So now what? Let's take a look at the newly released Proxies for Azure Functions!

[DevOps] Should you migrate onto YAML release pipelines?

If you've started using Functions in Azure and you've got multiple set-up by now, you'll start to find that managing them becomes a bit cumbersome, especially when you've spread them across multiple instances. All of the instances will have a different base URL and you might find it difficult to keep naming and versioning in line with what you planned. So now what? Let's take a look at the newly released Proxies for Azure Functions!

Leave a Comment

Leave a Reply

Your email address will not be published. Required fields are marked *