Expose Azure Search through Function Proxy
If you use Azure Search on a website, you should expose it through Azure Function Proxy. Here is why.
Search everywhere
Azure Search is a great service that you can use to extend your website or web application with a powerful search capability, literally, in a matter of minutes. All you need to do is to create an instance of Azure Search in your subscription, define the properties and fill the index with data. That’s it. As soon as there is data in the index, you can start searching through it. And if the default capabilities are not enough, you can tweak the ranking model to improve the relevance to whatever you need. What’s even better, is that if you don’t have a high volume of data or don’t issue a crazy number of queries, you can be using it for free.
Using Azure Search in web applications
Using Azure Search from a web application is straight-forward and comes down to issuing GET requests to its REST API. With the different parameters, you can specify the search query, which properties you want to retrieve or which ranking model should be used. But instead of calling the Search API directly from your site, I’d suggest that you do something else.
Inconvenient publishing changes in cached files
To improve the performance of my blog, I configured caching static assets for long periods. The problem is, that whenever I change something, I need to rename the asset files such as script or CSS files to ensure that the new version of the file will be served to everyone. But these files are referenced from literally every single HTML file on my static site. So a single change in a script means rebuilding and republishing the whole site.
I’ve been using Azure Search on my blog to allow my readers to easily search through my content. At some point, I noticed, that the search results weren’t as good as they could be, and I decided to tweak the ranking model. Additionally, I wanted to change how the results were presented to give my readers a better indication of what in the particular result matched their query.
Once I was done with my changes I wanted to publish them. And since I was calling the Azure Search API directly, I had to update the script and all references to it basically invalidating my whole cache. What I learned then was, that instead of calling the Azure Search API directly, I should’ve exposed it through Azure Function Proxy.
Expose Azure Search through Function Proxy
Azure Function Proxy is a capability of Function Apps, that allows you to proxy API calls. Each proxy gets a public URL that will be consumed by the web application or other clients. In the proxy’s configuration, you can specify which URL it should call internally. This URL is not limited to Functions and can be any API URL accessible on the Internet. For each proxy, you can also configure how it should change the request and response either by rewriting the payload or adding/changing the headers. Azure Function Proxy is perfect if you want to hide API intricacies like API keys or parameters from the API’s consumers.
Exposing Azure Search through Function Proxy makes perfect sense. It allows you to keep the public API surface of your Azure Search instance limited to specifying the search query. Everything else, like the API key, which ranking model you’re using, which properties you’re selecting and highlighting can be defined in the proxy configuration and hidden away from your website. Whenever you want to change something, all you need to do is to update the proxy configuration and your changes are visible immediately without you having to worry about invalidating the client cache.
Here is the necessary configuration required for exposing your Azure Search instance through a Function Proxy.
Proxy configuration
Assuming you’ve created an Azure Function and in it, a Proxy for use with your Azure Search instance, start with defining the route template, eg. /search
. Whatever you put in, it will be appended to the URL of your Azure Function App. You can keep the route template simple and use a query parameter to pass the search query.
If you want to expose your Azure Search instance only for public use, the proxy will need to allow only GET requests. Other types of requests are used when managing the Azure Search instance configuration but are not something that you would typically expose publicly.
Finally, specify the backend URL which should point to your Azure Search instance, eg. https://contoso.search.windows.net/indexes/myindex/docs?$select=title,url,content,pubDate
. All query string parameters can be defined more conveniently in the request override section. Unfortunately, Function Proxy doesn’t accept $
when specifying query parameters in the request override section, which is why $select
, or any other OData parameter, needs to be included directly in the backend URL.
With the basics in place, the next step is to extend the incoming request with additional data that should be passed to Azure Search.
Since the Proxy accepts only GET requests and we pass GET requests to Azure Search, there is no need to override the HTTP method.
Next, you need to define the required parameter like api-version
or search
. Notice, that while we’re using a static value for the api-version
, for the search
parameter, we’re using the value of the q
query string parameter from the original request to our proxy. In my configuration, I also specify the highlight
property, which instructs Azure Search to highlight the fragments that match the search query in the title
and content
properties from my search index.
The final step is to add the api-key
request header which is required by Azure Search.
With this configuration in place, on your website, you can be using Azure Search by calling:
GET https://contoso-api.azurewebsites.net/search?q=my%20search%20query
Internally, your Azure Function Proxy will translate this call to:
GET https://contoso.search.windows.net/indexes/posts/docs?$select=title,url,content,pubDate&search=my%20search%20query&highlight=title,content&api-version=2015-02-28
api-key: abcdef
Whenever you will want to change Azure Search settings, such as using a newer API version, adding highlighted properties and using a specific search index, you can do that directly in the proxy, without affecting your website and with your changes being visible immediately. If you’re using Azure Search on a website or a web application, this flexibility is exactly why you should expose it through an Azure Function Proxy.