In this post I am going to explain how to create a LogicApp to use CosmosDB in Azure based on a common scenario. The full source code of this post and the next posts is on GitHub.
Request
Given a new green field project, the requirements are that are two different payloads, A and B that need to be exposed to our customers via the internet. An audit log is also required for every request that is received. Given this has to be done quickly and cheaply to prove some value. how would you go about designing this system?
Data to use
So, the requirement are not very specific about the payload, it could be everything. Then, I decided to define the payload. If I think to a bank, I want to save the name of a customer and its transactions.
Customer details
{
"id": "2ef07067-bd63-428a-9417-1aae3ebc4fab",
"address":{
"type":"PostalAddress",
"addressLocality":"London",
"addressRegion":"London",
"postalCode":"W105LT",
"streetAddress":"228"
},
"email":"info@s981402199.websitehome.co.uk",
"jobTitle":".NET developer",
"name":"Enrico Rossini",
"telephone":"07745001700",
"url":"https://puresourcecode.com"
}
Transaction details
{
"id": "8cb02b56-3d42-4ef1-9cb7-f8c23feeb836",
"customerId": "2ef07067-bd63-428a-9417-1aae3ebc4fcd",
"type": "MoneyTransfer",
"name": "Donate puresourcecode.com",
"amount": {
"type": "MonetaryAmount",
"amount": "30",
"currency": "GBP"
},
"beneficiaryBank": "European ExampleBank, London"
}
What is a Logic App?
Microsoft Azure Logic Apps is a managed cloud service that runs in a company’s public cloud and helps users introduce scalable, cloud-based integrations and workflows to business processes. Logic Apps is available as a fully managed integration PaaS tool. Also, it provides the user with a visual designer to model their business processes and design workflows.
Microsoft offers three development models for Logic Apps. You can create applications in Logic Apps via:
- the Azure portal
- in Visual Studio after 2015
- or in templates built by Microsoft.
Why should I use Azure Logic Apps?
Logic Apps enables enterprises to connect legacy systems to modern ones quickly and easily. Also, it handles hosting, management, monitoring and scalability of applications on Azure resources. So, developers can focus primarily on the business logic of their apps. Developers can configure complex business processes with minimal development effort and build applications with predefined workflows that are part of the Logic App template gallery.
Another benefit of Logic Apps is that it doesn’t have any upfront setup costs. The pricing model works on a pay-per-use basis, so users are only charged for the actions they execute.
How does Azure Logic Apps work?
Now, a Logic App workflow starts with a trigger. It is fired each time an event occurs or when new data is available. When the application executes this trigger, the Logic Apps engine creates a Logic App instance. In turn, this instance executes the actions within a workflow. These actions can include conditional statements, loops and branching.
For example, let’s say a trigger fires whenever a record is added to a list. When the Logic Apps engine detects an event that matches this criterion, the trigger sets off a workflow, the app makes data updates and branching occurs as appropriate. The workflow closes by sending an email notification to the list manager of the record update.
Azure Logic Apps vs. Azure Functions
While Azure Functions and Logic Apps both fall under the umbrella of Microsoft’s serverless offerings, there are distinct differences between the two. Azure Functions is a serverless compute service; Logic Apps represents a serverless workflow.
In Azure Functions, the event triggers the code, but in Logic Apps, the event triggers the workflow. Overall, Logic Apps enables serverless applications to automate and orchestrate business processes and workflows.
Azure Logic Apps vs. Flow, PowerApps
PowerApps is another cloud offering from Microsoft. PowerApps provides a platform on which business experts can build apps without writing any code. It is a powerful framework for quick builds, but Logic Apps is the better choice if you want more control over application workflows.
Microsoft Flow, on the other hand, is a streamlined version of Logic Apps. It is a SaaS offering for automating workflows, but unlike Logic Apps, you don’t have access to step through the source code in Flow. This means that the provisioning and management features found in Logic Apps are abstracted in Flow, and employees can create workflows without developers.
To choose which approach is the best fit for your organization, think about the user and what they want to accomplish. PowerApps enables business people to quickly create apps. Microsoft Flow enables employees to quickly create business processes on their own. Azure Logic Apps helps developers quickly connect business processes to any enterprise data sources, like ERP systems and data warehouses.
Azure Logic Apps vs. AWS Step Functions
AWS Step Functions enables users to quickly coordinate multiple AWS offerings into serverless workflows. You can use AWS Step Functions to design and run workflows and create tasks that use AWS Lambda. Azure Logic Apps has a comparable capability with Azure Function connectors.
Compared to AWS Lambda, Azure Functions provides more flexibility in terms of pricing models, programming language support, built-in HTTP triggers and built-in continuous delivery. Another important feature of Logic Apps is that it contains prebuilt connectors that can push or pull data to and from your applications.
AWS Lambda can deploy source code via zip packages only. This is convenient until you have to make a change, then you have to deploy the entire package again. When using Azure Functions, you have more choices. You can deploy Azure Functions from zip packages, GitHub, Atlassian Bitbucket or an external repository of your choice.
Create the resource group
To start and create a LogicApp to use CosmosDB, we have to create a resource group in Azure in order to create other resources. Also, I want an organized resource group. For this reason, I will use a common naming convention for resources for Azure.
Create a CosmosDb
First step in order to create a LogicApp to use CosmosDB is to have a CosmosDB. So, create a new resource and search for Azure CosmosDB. As API, select Core.
Following the azure naming convention, I’m going to add those values:
- Account name: azuks-mcp-vaq-cdb-d1
- for other parameters I use the default value
Then, you have to create a new database and a new container:
- Database id: Accounts
- Container id: Customers
- Partition id: /id
Then, press OK.
Then, after few seconds you have your Azure CosmosDB up and running. Here an example.
Create a new LogicApp
Now, it is time to create a LogicApp. As I said before, following the common naming convention for resources for Azure. So, in the resource group, add a new resource clicking the Create button and then search for Logic App. Then, fill the form and press Next.
Pretty straightforward. So, we have just prepared the environment to start. Now, it is time to create the first Logic App.
Create a new customer
Finally, we can start to create a LogicApp to use CosmosDB. So, in your Logic App, click on Workflow and then type its name (in my case createCustomer
) and select Stateful.
Now, Azure is creating the workflow and at the end you can click on it. Azure shows you the dashboard for this workflow. Then, click on Designer.
Now, you have a screen like the following image. Azure asks what the first operation is. What is the first operation? First, we have to decide how and when this workflow has to starts. There are different triggers:
Schedule Recurrence: Trigger a workflow based on the specified recurrence. Sliding Window: Trigger a workflow that needs to handle data in continuous chunks. Delay: Pause your workflow for the specified duration. Delay until: Pause your workflow until the specified date and time. | HTTP Call an HTTP or HTTPS endpoint by using either the HTTP trigger or action. You can also use these other built-in HTTP triggers and actions: HTTP + Swagger HTTP + Webhook | Request When a HTTP request is received: Wait for a request from another workflow, app, or service. This trigger makes your workflow callable without having to be checked or polled on a schedule. Response: Respond to a request received by the When a HTTP request is received trigger in the same workflow. | Batch Batch messages: Trigger a workflow that processes messages in batches. Send messages to batch: Call an existing workflow that currently starts with a Batch messages trigger. |
Call your own triggers and actions in APIs that you define, manage, and publish using Azure API Management. Note: Not supported when using Consumption tier for API Management. | Azure App Services Call apps that you create and host on Azure App Service, for example, API Apps and Web Apps. When Swagger is included, the triggers and actions defined by these apps appear like any other first-class triggers and actions in Azure Logic Apps. | Azure Logic Apps Call other workflows that start with the Request trigger named When a HTTP request is received. | SQL Server (Single-tenant only) Connect to your SQL Server on premises or an Azure SQL Database in the cloud so that you can manage records, run stored procedures, or perform queries. Note: Single-tenant Azure Logic Apps provides both SQL built-in and managed connector operations, while multi-tenant Azure Logic Apps provides only managed connector operations. |
So, in our scenario we want that the workflow starts when a HTTP request is received. So, search HTTP and then click on When a HTTP request is received, like in the following image.
Now, we have to set what HTTP method we want to use. Because the operation the workflow will perform is a creation of a new record, the standard says we have to use POST
. So, in the dropdown Method
choose POST
.
The next step is to tell the workflow what JSON schema it has to expect. For that, at the beginning of this post, I have a json
for a customer. Copy it. In the workflow click on Use sample payload to generate schema. In the popup window, paste the json
and then click Done.
Now, the workflow knows what kind of json it has to expect. The next step is to save the json in the CosmosDb. Click on the + button under the first step in the workflow and then click on Add an action. This time search for cosmos. From the list, choose Create or update document.
At this step, probably you have to create a connection with the CosmosDb and for that you have to type a Connection name and select what DocumentDB Account you want to use.
So, at this point you can select from the dropdown list what Database ID you want to use and the Collection ID. Now, the Document. When you click in the textbox, immediately a popup window appears with the list of values in the Dynamic content tab you can use or you can write your own Expression.
Here, we only want to save the json the workflow has received. So, click on Body under When a HTTP request is received. In the Document field, you see the Body field in green.
Very easy. When we created the CosmosDb, a field was mandatory: Partition key value. If we don’t specified this value in the Create or update document, we will get this error:
The partition key supplied in x-ms-partitionkey header has fewer components than defined in the the collection
{
"code": "BadRequest",
"message": "Message: {\"Errors\":[\"The partition key supplied in x-ms-partitionkey header has
fewer components than defined in the the collection.\"]}\r\nActivityId:
73c13b2a-0e35-4697-a096-c2a999297db3, Request URI: /apps/7f808ea2-c87e-4f5a-8bdd-73d1da463d99/
services/1a7db1f4-a311-4b19-83e2-04ac9f2cefb5/partitions/8147bf7a-e988-4c03-ac89-1b5de49f7e69/
replicas/132718584022508947p, RequestStats: \r\nRequestStartTime: 2021-07-27T21:16:09.9628538Z,
RequestEndTime: 2021-07-27T21:16:09.9729163Z,
Number of regions attempted:1\r\n
ResponseTime: 2021-07-27T21:16:09.9729163Z,
StoreResult: StorePhysicalAddress: rntbd://10.0.0.102:14000/apps/7f808ea2-c87e-4f5a-8bdd-73d1da463d99/
services/1a7db1f4-a311-4b19-83e2-04ac9f2cefb5/partitions/8147bf7a-e988-4c03-ac89-1b5de49f7e69/
replicas/132718584022508947p, LSN: 2, GlobalCommittedLsn: 2,
PartitionKeyRangeId: 0, IsValid: True, StatusCode: 400, SubStatusCode: 1001,
RequestCharge: 0, ItemLSN: -1, SessionToken: 2, UsingLocalLSN: False,
TransportException: null, BELatencyMs: 0.574, ActivityId: 73c13b2a-0e35-4697-a096-c2a999297db3,
ResourceType: Document, OperationType: Create\r\n,
SDK: Microsoft.Azure.Documents.Common/2.14.0"
}
Quite scary, right? This is because we didn’t pass the Partition key value. This is quite common issue among developers and I will explain soon how to fix it in your code, if you need it.
For that, we have to add a new parameter. So, click on the dropdown list Add new parameter and check Partition key value. Then, in the form a new textbox appeared: Partition key value.
When you click on this textbox, again the popup window appears to show all the fields that come from the json
. Very cool! The field we selected as partition key is the Id.
This is the important thing. There are a lot of error because of that. Pay attention here.
So, before click on id in the list, type twice "
and then point the cursor in the middle of those 2 and click. Now, you can click on id in the list.
Here the important think. You must pass the Partition key value between quotation marks. If not, you will get the error I showed early.
Finally, I want to complete this workflow with a response. The response must be the HTTP Status Code. The status code 200 means the request is done. Also, I want to return the full document for the customer the workflow has just created. For that, add a new action and search for Response.
Now, when you click on Body in the Response, you can select the Body from Create or update document. That is the new document the workflow has just created.
The last thing to do is click to Save.
Test the workflow
So, we saw how to create a LogicApp to use CosmosDB. Now, we have to test own workflow. Click on Overview. Then, click on Run Trigger and select Run with payload.
Sometimes, running in the Azure portal is not the best idea. For that, you can use Postman. You have to copy the Workflow URL and paste in a new tab in Postman. So, add the payload as raw body and then select JSON.
If you are in trouble, watch the video of this tutorial on the YouTube channel and please subscribe.
How to resolve : Cosmos DB x-ms-partitionkey Error
One of the most repeated question that I came across on stackoverflow on the tag #Cosmosdb is that how to resolve the error “The partition key supplied in x-ms-partitionkey header has fewer components than defined in the collection”
This error could occur when you are attempting to get a Document from CosmosDB using the REST API or using SDK. If you are using a partitioned Collection and therefore you need to add the x-ms-documentdb-partitionkey
header. Even after adding the header if you get the error you can fix it by the following methods. Partition key must be specified as an array (with a single element).
So, in C# this is the code
requestMessage.Headers.Add("x-ms-documentdb-partitionkey",
" [ \"" + partitionKey + "\" ] ");
And this is the code for JavaScript
headers['x-ms-documentdb-partitionkey'] = JSON.stringify([pkey]);
Read the customer details
Now, we successfully create a LogicApp to use CosmosDB adding a new record in the database. But what about to read a document from CosmosDB?
The procedure is pretty much the same as before but I want to add something a bit interesting change. So, generally, when you call for getting a record, we are using GET
. That means, we can avoid to pass a payload and change the URL to pass the ID of the document we want to read.
So, add a new When a HTTP request is received and select the GET
Method. Then, you can decide the Relative Path. The Relative Path will be added to the workflow URL. For example, in this case, I want to read a customer from the CosmosDB. So, I’m adding this Relative Path:
customer/{customerId}
{customerId}
is a variable to use in your workflow. Automatically, the workflow matches the URL with your Relative Path and create a new variable customerId
and assign to it the value of {customerId
}.
When you call the workflow, you can change manually the URL adding the Relative Path after invoke/
followed by the ID of the document you want to read. This is an example. The magic is happening on the row number 2.
https://azuks-mcp-vaq-log-d1.azurewebsites.net/api/readAccount/triggers/manual/
invoke/customer/2ef07067-bd63-428a-9417-1aae3ebc4fcd?
api-version=2020-05-01-preview&sp=%2Ftriggers%2Fmanual%2Frun&sv=1.0&
sig=J97R-VR3AdpGy_KTuf5D1Hx-uigeTj2azlWiVYlJSW0
Then, if you try this URL in your browser, for example, what you will see is the document.
How to create Logic Apps in Visual Studio 2019?
At the end of this post “Create a LogicApp to use CosmosDB”, I’m going to give you same hits about Logic Apps and Visual Studio 2019.
It is possible to create and change Logic Apps directly in Visual Studio 2019 (for now, Visual Studio 2021 doesn’t have this option). Out of the box, Visual Studio doesn’t have the tool to support Logic Apps.
So, in Visual Studio, click on Extensions and then Manage extensions. In the window, search for Logic Apps. From the list, select Azure Logic Apps Tools for Visual Studio 2019.
After the successful installation, you can start changing your workflow. For that, you have to create a new project as Azure Resource Group.
Then, type the Project Name, Location and Framework and click Next. Then, Visual Studio opens a new window with title Select Azure Template. From the list, select Logic App.
When you have your new project in the solution in Visual Studio, you have to right-click on the LogicApp.json
file and select Open With Logic App Designer.
So, the result is something like in the following image.