When it comes to working with Cosmos DB in .NET the Azure SDK team is working on a v4 SDK that I decided to use (even though it's still in preview).
Unfortunately, the SDK doesn't feel particularly friendly to F# developers, mainly because it relies on the .NET
Task API rather than F#‘s
Async, so I wanted to make something that felt a bit more like F# code.
open FSharp.CosmosDb let host = "https://..." let key = "..." let findUsers() = host |> Cosmos.host |> Cosmos.connect key |> Cosmos.database "UserDb" |> Cosmos.container "UserContainer" |> Cosmos.query "SELECT u.FirstName, u.LastName FROM u WHERE u.LastName = @name" |> Cosmos.parameters ["name", box "Powell"] |> Cosmos.execAsync<User>
Here we've got a pipe-able API, starting with the host endpoint for our Cosmos instance, then providing the authorisation key. This will allow us to setup a connection to Cosmos and then we can start working with it. Then we can specify the database and container that we'll work with before writing a query and providing parameters (if required).
The last step is
Cosmos.execAsync<'T> which takes a type argument that we want to unpack our query results into. This will provide an
AsyncSeq for you to iterate over asynchronously. Until you run
Cosmos.execAsync<'T> nothing has happened with Cosmos, in fact, it uses a record type to wrap up the information provided so you can pass it around easily.
This first version is a little rough around the edges, I won't deny that, so here's a few things to be aware of:
- The argument for
(string * object) listso you have to
boxthe value argument. This is because the underlying API takes an object value, but if anyone can think a better approach let me know
- If the type provided to
execAsyncis a record type it must be marked as
[<CLIMutable>]. I need to find a way to work around that so we can use plain record types
- It doesn't support connection string connections, only host + key access (easy fix, just requires some time)
- I haven't written docs yet, sorry!
I hope you find this useful, I'm going to keep plugging away at adding features to the API and make it more feature compatible with the full .NET SDK. In the mean time if you try it out let me know what you think. 😊