Azure Cosmos DB + Functions Cookbook — HTTP querying
Following this series of posts of quick and easy recipes you can use with Azure Cosmos DB and Azure Functions, we’ll talk about HTTP querying.
Scenario
You want to expose an easy to use HTTP endpoint that can query an Azure Cosmos DB instance and return matched documents as response without coding an entire application.
Ingredients
There’s a myriad of triggers and bindings available in Azure Functions that are useful in dozens of different scenarios.
For this recipe we’ll use the HTTP Trigger, which will enable us to run our Function when we send an HTTP payload to an endpoint and the Azure Cosmos DB Input binding. The HTTP Trigger exposes a URL (we can configure the Authorization parameters if we want) to which we can send filtering parameters; the Cosmos DB Input binding is in charge of connecting to the Cosmos DB instance and running queries with a flexible configuration.
If you read the previous post in this series, you’ll know about the performance benefits of communicating with your Cosmos DB account using an static client, the good news is that the Input binding will do this for you, it will maintain a static instance of the DocumentClient, so you don’t have to worry about it!
NOTE: The Input binding is compatible with Azure Cosmos DB SQL API accounts, do not attempt to use it with Cosmos DB Mongo API accounts.
Recipe
There is an interesting relationship between Triggers and Input bindings, you can dynamically match properties from the Trigger with configuration data on the Input binding without extra coding.
Let’s say that we want to filter documents by two properties, name
and city
running this SQL Query:
SELECT * FROM d WHERE d.name = {Name} and d.city = {City}
We can expose the HTTP endpoint that will receive a payload (JSON or XML) in its body containing these two properties and we’ll magically wire up the property values into the query to the collection.
When working with C#, the trick to making this work is to create a class with the properties and using it as input in the Function, matching the Function’s parameter’s name with the HTTP Trigger attribute name.
Then we can use any of the class’ property names in the Cosmos DB Input binding sqlQuery
attribute and the Function’s Runtime will wire up the value received into the query and execute it, we don’t have to type any code to accomplish that!
This is the function.json
file, notice the name
property of the httpTrigger
and the sqlQuery
property in the documentDB
binding:
Now, in the run.csx
file, we define a class named Query with the properties we want to receive, notice the Run
parameters and how the query
matches the name we used in the httpTrigger
, that does the deserialization magic.
In NodeJS, the code is a bit simpler given the dynamic nature of the language, our index.js
will look like this:
Notice how we didn’t need to write any code that queries the collection, we are just getting the results in the form of the documents
parameter and returning them to the client, all in less than 10 lines of code!
Now we can send payloads from anywhere and obtain results:
If you are concerned about SQL Injection attacks, this article explains the security measures implemented to sanitize the bindings.
You can now create your own custom queries and payloads by customizing the function.json
file.
Stay tuned for more recipes!
Other posts in this series:
- Azure Cosmos DB + Functions Cookbook — static client
- Azure Cosmos DB + Functions Cookbook — output collector
- Azure Cosmos DB + Functions Cookbook — live migration
- Azure Cosmos DB + Functions Cookbook — search indexing
- Azure Cosmos DB + Functions Cookbook — secure client
- Azure Cosmos DB + Functions Cookbook — multi trigger
- Azure Cosmos DB + Functions Cookbook — Connection modes
- Azure Cosmos DB + Functions Cookbook — Multi master & preferred region
- Azure Cosmos DB + Functions Cookbook — Shared throughput and new health logs
- Azure Cosmos DB + Functions Cookbook — monitoring Trigger pending work