Introduction
Using Cosmos DB REST API from Postman can be a challenge.
It involves send some mandatory request headers, mainly for authorization porpoises.
You can give it a look at:
https://docs.microsoft.com/en-us/rest/api/cosmos-db/access-control-on-cosmosdb-resources
As well as a C# Sample at: https://github.com/Azure/azure-cosmos-dotnet-v2/tree/master/samples/rest-from-.net
This post help you to make it easier.
What do you need?
- An Azure Cosmos DB Account: If you don't already have one, you can get it from free: https://docs.microsoft.com/en-us/azure/cosmos-db/free-tier.
- Last version of Postman installed: To install it, look at: https://learning.postman.com/docs/getting-started/installation-and-updates/. You can use web app version instead: https://learning.postman.com/docs/getting-started/installation-and-updates/.
How to do it?
To make process simple in Postman, we will be creating one collection with necessary collection variables and a pre-request script to fill those variables before sending the request to the server, then in each request, we will be filling those variables with the corresponding variable values.
Disclaimer
This is not a post oriented to learn Postman, then just expect to get general guidance instead of detailed steps, then I am putting the Postman documentation link into each step. Feel free to click on the links to see how to do it. Remember that you always can look at Postman docs page.
The process consist on the next steps:
- Get Cosmos DB URI and KEY.
- Create a new Postman Collection.
- Create Postman Collection variables.
- Create pre-request script.
- Add a new request to the collection.
Next we are going to see each step in a detailed way.
Get Cosmos DB URI and KEY
You can go to the Azure Portal, then click on your Cosmos BD account, and then go to the "🔑Keys" option into the "Settings" section and get: "URI" and either "PRIMARY KEY" or "SECONDARY KEY" (if you will be doing just read only operation it is preferable to use data from "Read-only Keys" tab.
If you feel more comfortable using a shell, then you can get them using either Powershell or az.
Create a new Postman Collection
In this post, we are assuming that collection name will be "Cosmos DB REST".
See hot to do it in: https://learning.postman.com/docs/sending-requests/intro-to-collections/#creating-collections
Create Postman Collection variables
See how to do it in: https://learning.postman.com/docs/sending-requests/variables/#defining-collection-variables).
An then create next variables:
VARIABLE | CURRENT VALUE | NOTES |
---|---|---|
authorization_type | master | We are using Master Key Authorization but we can use a different option. |
authorization_version | 1.0 | See valid values. |
authorization_signature | PRIMARY KEY value obtained in step Get Cosmos DB URI and KEY. | See valid values. |
x-ms-version | 2018-12-31 | See supported REST API Versions. |
Example:
Important: We prefer to set just "CURRENT VALUE" for each variable. Check why at Adding environment variables Postman documentation.
Create pre-request scripts
See what is it at: https://learning.postman.com/docs/writing-scripts/pre-request-scripts/
The next pre-request script will test for mandatory variables, calculate and set valid headers for all the request in the collection.
To see how to create a pre-request script in Postman see: https://learning.postman.com/docs/writing-scripts/pre-request-scripts/#scripting-before-your-request-runs.
To see GitHub Gist of the pre-request script go to: https://gist.github.com/josuemb/f03232ac043dfa0ff645a367c69383e8
GitHub Gist:
/** | |
* This POSTMAN pre-request script help to create necessary values | |
* to make a call to Cosmos DB REST API with Authorization request headers | |
* and set those headers to each request. | |
* See REST API into in: https://docs.microsoft.com/en-us/rest/api/cosmos-db/ | |
* See access control reference on: | |
* https://docs.microsoft.com/en-us/rest/api/cosmos-db/access-control-on-cosmosdb-resources | |
* Josué Martínez Buenrrostro @josuemb on twitter | |
*/ | |
// Checking for mandatory collection variables need to be present in any call, those are: | |
// Authorization, x-ms-version, Authorization and x-ms-date. | |
// When Authorization and x-ms-date values are going to be filled in this script. | |
// See reference on: https://docs.microsoft.com/en-us/rest/api/cosmos-db/common-cosmosdb-rest-request-headers | |
pm.test("Check for collectionVariables", function () { | |
let vars = ['authorization_type', 'authorization_version', 'authorization_signature', 'x-ms-version']; | |
vars.forEach(function (item, index, array) { | |
pm.expect(pm.collectionVariables.get(item), item + ' variable not set').to.not.be.undefined; | |
pm.expect(pm.collectionVariables.get(item), item + ' variable not set').to.not.be.empty; | |
}); | |
}); | |
// Get URL value from request. | |
let url = pm.request.url.toString(); | |
//Regular expression to separate parameters in pair with resource name and resource id when resource id is optional. | |
let urlRegExp = /^https?:\/\/.*\.documents\.azure\.com(?::\d+)?(?:\/([^\/]+)(?:\/([^\/]+)?)?)+$/i; | |
// Checking for valid URL syntax. | |
// See: https://docs.microsoft.com/en-us/rest/api/cosmos-db/cosmosdb-resource-uri-syntax-for-rest | |
pm.test("Check for URL valid format", function() { | |
pm.expect(url, 'URL not set').to.not.be.undefined; | |
pm.expect(url, 'URL not set').to.not.be.empty; | |
pm.expect(urlRegExp.test(url), 'URL does not have a valid format. See: https://docs.microsoft.com/en-us/rest/api/cosmos-db/cosmosdb-resource-uri-syntax-for-rest').to.be.true; | |
}); | |
// Getting necessary values from collection variables. | |
// See: https://learning.postman.com/docs/sending-requests/variables/ | |
let autorizationType = pm.collectionVariables.get('authorization_type'); | |
let autorizationVersion = pm.collectionVariables.get('authorization_version'); | |
let authorizationSignature = pm.collectionVariables.get('authorization_signature'); | |
let cosmosDBApiVersion = pm.collectionVariables.get('x-ms-version') | |
// Decode authorization signature (it is originally base64 coded) | |
let key = CryptoJS.enc.Base64.parse(authorizationSignature); | |
// Set request date formatting as UTC | |
let dateUtc = new Date().toUTCString(); | |
// Get request method (a.k.a. verb) to build text for authorization token | |
let verb = pm.request.method; | |
// Execute regular expression to extract some parts from URL. | |
let parsedUrl = urlRegExp.exec(url); | |
// Get resource type from URL | |
let resourceType = parsedUrl[1]; | |
// Get resource ID from URL, if it is not present, we are getting undefined. | |
let resourceId = parsedUrl[2]; | |
// Build regular expression to get all parameters from URL to build ResourceLink part. | |
// See "Example Encoding" in: https://docs.microsoft.com/en-us/rest/api/cosmos-db/access-control-on-cosmosdb-resources | |
let resourceLinkPattern = /^https?:\/\/.*\.documents\.azure\.com(?::\d+)?\/(.*)$/i; | |
let parsedResourceLink = resourceLinkPattern.exec(url); | |
// Get resource LInke from expression and in case last character is / we just drop it out. | |
let resourceLink = parsedResourceLink[1].charAt(parsedResourceLink[1].length-1) === "/"? | |
parsedResourceLink[1].substring(parsedResourceLink[1], parsedResourceLink[1].length-1): | |
parsedResourceLink[1]; | |
// When Resource Id is present in parameters, then Resource Link is whole parameters part, | |
// elsewhere, then we need to drop last /resource type to | |
// build Resource Link. | |
// Example: | |
// for URL: https://myaccount.documents.azure.com/dbs/MyCollection/colls/ | |
// Resource Link will be just: dbs/MyCollection | |
if(resourceId === undefined) { // Resource Id not provided | |
// We need to cut last part to left just Resource Id | |
resourceLink = resourceLink.substring(0, resourceLink.lastIndexOf('/')); | |
} | |
// Build string to be encrypted and used as signature. | |
// See: https://docs.microsoft.com/en-us/rest/api/cosmos-db/access-control-on-cosmosdb-resources | |
var text = (verb || "").toLowerCase() + "\n" + | |
(resourceType || "").toLowerCase() + "\n" + | |
(resourceLink || "") + "\n" + | |
dateUtc.toLowerCase() + "\n\n"; | |
// Build key to authorize request. | |
let signature = CryptoJS.HmacSHA256(text, key); | |
// Code key as base64 to be sent. | |
let signature_base64 = CryptoJS.enc.Base64.stringify(signature); | |
// Build autorization token and encode it as URI to be sent. | |
var authorizationToken = encodeURIComponent("type=" + autorizationType + "&ver=" + autorizationVersion + "&sig=" + signature_base64); | |
// Set request headers | |
pm.request.headers.upsert({'key': 'Accept', 'value': 'application/json'}); | |
pm.request.headers.upsert({'key': 'x-ms-version', 'value': cosmosDBApiVersion}); | |
pm.request.headers.upsert({'key': 'x-ms-date', 'value': dateUtc}); | |
pm.request.headers.upsert({'key': 'Authorization', 'value': authorizationToken}); |
Example:

Add a new request to the collection
See how to do it in: https://learning.postman.com/docs/sending-requests/intro-to-collections/#adding-requests
Since we are already creating all needed request headers in the pre-request script (see step 4), then we just need to create a new request by indicating: verb, uri, body (optional) as well as additional request headers (just in case you need it).
Example:
Now we will create a new request to get the list the databases for a given Cosmos DB Account. To create it we will need:
- Cosmos DB URI: We already have seen how to get it in step 1. In this case it is: https://jmbcosmosnotebookdemo.documents.azure.com:443/ but we can abbreviate it as: https://jmbcosmosnotebookdemo.documents.azure.com/ since 443 is the standard port for https protocol.
-
List Databases URI: In this case: https://jmbcosmosnotebookdemo.documents.azure.com/dbs. To see other operations, see: https://docs.microsoft.com/en-us/rest/api/cosmos-db/common-tasks-using-the-cosmosdb-rest-api and to see valid URIs see: https://docs.microsoft.com/en-us/rest/api/cosmos-db/cosmosdb-resource-uri-syntax-for-rest
That's it. Then we can execute the request and see response.
Example:
Summary
Once you have done all previous steps, you can create any request and all needed request headers will be added automatically and you just need to add elements specific to each request.
Get a Postman Collection example from: https://www.getpostman.com/collections/57e0af5bf2d7021d4d15
And then you can import it as is documented on: https://learning.postman.com/docs/running-collections/working-with-data-files/
Feel free to reach me in twitter: @josuemb
Top comments (3)
Thanks for the guide, really useful!
A question please. If i follow the steps, and run the postman collection, i get the error - TypeError: Cannot read properties of null (reading '1')
But if I copy the Pre-request Script from the collection into the Request's pre-request script part, then it works!
Where could i be going wrong?
Is not it the same? sajeetharan.com/2019/07/01/easily-...
It is similar but I simplified needed variables and changed the algorithm since the post you are referring did nor work for some cases.