azureazure-functionsazure-cosmosdbcosmosdbtrigger

Access CosmosDB from Azure Function (without input binding)


I have 2 collections in CosmosDB, Stocks and StockPrices.

StockPrices collection holds all historical prices, and is constantly updated.

I want to create Azure Function that listens to StockPrices updates (CosmosDBTrigger) and then does the following for each Document passed by the trigger:

  1. Find stock with matching ticker in Stocks collection
  2. Update stock price in Stocks collection

I can't do this with CosmosDB input binding, as CosmosDBTrigger passes a List (binding only works when trigger passes a single item).

The only way I see this working is if I foreach on CosmosDBTrigger List, and access CosmosDB from my function body and perform steps 1 and 2 above.

Question: How do I access CosmosDB from within my function?


Solution

  • One of the CosmosDB binding forms is to get a DocumentClient instance, which provides the full range of operations on the container. This way, you should be able to combine the change feed trigger and the item manipulation into the same function, like:

    [FunctionName("ProcessStockChanges")]
    public async Task Run(
        [CosmosDBTrigger(/* Trigger params */)] IReadOnlyList<Document> changedItems,
        [CosmosDB(/* Client params */)] DocumentClient client,
        ILogger log)
    {
        // Read changedItems, 
        // Create/read/update/delete with client
    }
    

    It's also possible with .NET Core to use dependency injection to provide a full-fledged custom service/repository class to your function instance to interface to Cosmos. This is my preferred approach, because I can do validation, control serialization, etc with the latest version of the Cosmos SDK.

    You may have done so intentionally, but just mentioning to consider combining your data into a single container partitioned by, for example, a combination of record type (Stock/StockPrice) and identifier. This simplifies things and can be more cost/resource efficient relative to multiple containers.