{"id":7546,"date":"2024-02-06T07:00:12","date_gmt":"2024-02-06T15:00:12","guid":{"rendered":"https:\/\/devblogs.microsoft.com\/cosmosdb\/?p=7546"},"modified":"2024-02-02T14:10:47","modified_gmt":"2024-02-02T22:10:47","slug":"azure-cosmos-db-design-patterns-part-6-event-sourcing","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/cosmosdb\/azure-cosmos-db-design-patterns-part-6-event-sourcing\/","title":{"rendered":"Azure Cosmos DB design patterns &#8211; Part 6: Event Sourcing"},"content":{"rendered":"<p>We&#8217;re excited to present the sixth edition of our blog series, dedicated to exploring design patterns in Azure Cosmos DB for NoSQL applications. Drawing from real-world customer experiences, our aim is to help you navigate the intricacies of JSON-based NoSQL databases. In this chapter, we delve deeper into prevalent NoSQL patterns, perfect for those new to this database type. We also focus on patterns specific to Azure Cosmos DB, demonstrating how to harness its distinct capabilities to tackle complex architectural issues.<\/p>\n<p><img decoding=\"async\" width=\"1024\" height=\"512\" class=\"wp-image-7547\" src=\"https:\/\/devblogs.microsoft.com\/cosmosdb\/wp-content\/uploads\/sites\/52\/2024\/02\/azure-samples-cosmsos-db-design-patterns.jpeg\" alt=\"Azure Samples \/ cosmsos-db-design-patterns\" srcset=\"https:\/\/devblogs.microsoft.com\/cosmosdb\/wp-content\/uploads\/sites\/52\/2024\/02\/azure-samples-cosmsos-db-design-patterns.jpeg 1024w, https:\/\/devblogs.microsoft.com\/cosmosdb\/wp-content\/uploads\/sites\/52\/2024\/02\/azure-samples-cosmsos-db-design-patterns-300x150.jpeg 300w, https:\/\/devblogs.microsoft.com\/cosmosdb\/wp-content\/uploads\/sites\/52\/2024\/02\/azure-samples-cosmsos-db-design-patterns-768x384.jpeg 768w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/p>\n<p>These patterns, previously shared individually with customers, are now being made more widely accessible. We believe it&#8217;s the right moment to broadly publish these insights, enhancing their discoverability among users. Thus, we&#8217;ve created <a href=\"https:\/\/github.com\/Azure-Samples\/cosmos-db-design-patterns\" target=\"_blank\" rel=\"noopener\">Azure Cosmos DB Design Patterns<\/a> \u2014 a GitHub repository filled with an array of examples. These samples are meticulously curated to demonstrate the implementation of specific patterns, assisting you in addressing design challenges when utilizing Azure Cosmos DB in your projects.<\/p>\n<p>To help share these, we have created a blog post series on each of them. Each post will focus on a specific design pattern with a corresponding sample application that is featured in this repository. We hope you enjoy it and find this series useful.<\/p>\n<p>Here is a list of the previous posts in this series:<\/p>\n<ul>\n<li><a href=\"https:\/\/devblogs.microsoft.com\/cosmosdb\/azure-cosmos-db-design-patterns-part-1-attribute-array\/\" target=\"_blank\" rel=\"noopener\">Part 1: Attribute Array<\/a><\/li>\n<li><a href=\"https:\/\/devblogs.microsoft.com\/cosmosdb\/azure-cosmos-db-design-patterns-part-1-attribute-array\/%22HYPERLINK%20%22https:\/\/devblogs.microsoft.com\/cosmosdb\/azure-cosmos-db-design-patterns-part-2-data-binning\/\" target=\"_blank\" rel=\"noopener\">Part 2: Data Binning<\/a><\/li>\n<li><a href=\"https:\/\/devblogs.microsoft.com\/cosmosdb\/azure-cosmos-db-design-patterns-part-2-data-binning\/%22%EF%B7%9FHYPERLINK%20%22https:\/\/devblogs.microsoft.com\/cosmosdb\/azure-cosmos-db-design-patterns-part-3-distributed-counter\/\" target=\"_blank\" rel=\"noopener\">Part 3: Distributed counter<\/a><\/li>\n<li><a href=\"https:\/\/devblogs.microsoft.com\/cosmosdb\/azure-cosmos-db-design-patterns-part-4-global-distributed-lock\/\" target=\"_blank\" rel=\"noopener\">Part 4: Global distributed lock<\/a><\/li>\n<li><a href=\"https:\/\/devblogs.microsoft.com\/cosmosdb\/azure-cosmos-db-design-patterns-part-5-document-versioning\/\" target=\"_blank\" rel=\"noopener\">Part 5: Document versioning<\/a><\/li>\n<\/ul>\n<h2>Azure Cosmos DB design pattern: Event Sourcing<\/h2>\n<p><a href=\"https:\/\/devblogs.microsoft.com\/cosmosdb\/wp-content\/uploads\/sites\/52\/2024\/02\/event-sourcing.jpg\"><img decoding=\"async\" class=\"aligncenter size-full wp-image-7549\" src=\"https:\/\/devblogs.microsoft.com\/cosmosdb\/wp-content\/uploads\/sites\/52\/2024\/02\/event-sourcing.jpg\" alt=\"Image event sourcing\" width=\"768\" height=\"768\" srcset=\"https:\/\/devblogs.microsoft.com\/cosmosdb\/wp-content\/uploads\/sites\/52\/2024\/02\/event-sourcing.jpg 768w, https:\/\/devblogs.microsoft.com\/cosmosdb\/wp-content\/uploads\/sites\/52\/2024\/02\/event-sourcing-300x300.jpg 300w, https:\/\/devblogs.microsoft.com\/cosmosdb\/wp-content\/uploads\/sites\/52\/2024\/02\/event-sourcing-150x150.jpg 150w, https:\/\/devblogs.microsoft.com\/cosmosdb\/wp-content\/uploads\/sites\/52\/2024\/02\/event-sourcing-24x24.jpg 24w, https:\/\/devblogs.microsoft.com\/cosmosdb\/wp-content\/uploads\/sites\/52\/2024\/02\/event-sourcing-48x48.jpg 48w, https:\/\/devblogs.microsoft.com\/cosmosdb\/wp-content\/uploads\/sites\/52\/2024\/02\/event-sourcing-96x96.jpg 96w\" sizes=\"(max-width: 768px) 100vw, 768px\" \/><\/a><\/p>\n<p>Event sourcing is a powerful architectural pattern that has its roots in Domain-Driven Design. It represents a fundamental shift in how entities maintain their internal state. Unlike traditional methods that rely on direct serialization or object-relational mapping, event sourcing achieves this by recording a series of events in an event store.<\/p>\n<p>At its core, event sourcing involves a container-like structure that records events in an append-only manner. This means that events are added to the log, but not updated or deleted. The result is a comprehensive historical record of all events, providing a valuable resource for various system functions.<\/p>\n<p>This approach offers several significant advantages in application design. A key benefit is its natural pairing with the Command Query Responsibility Segregation (CQRS) architecture pattern. In such combinations, especially with Azure Cosmos DB, the Change Feed feature plays a crucial role. It facilitates the read layer of the architecture, supporting patterns like Materialized Views, which are also often used with CQRS. Additionally, event sourcing can establish a communication layer for loosely coupled services, enhancing system flexibility and scalability.<\/p>\n<p>While event sourcing can be implemented with different database types, it finds resonance with developers using Azure Cosmos DB for several reasons:<\/p>\n<ul>\n<li><strong>Flexible Schema:<\/strong> NoSQL databases like Azure Cosmos DB are known for their schema flexibility. This adaptability is ideal for event sourcing, where unstructured event data, often in JSON format, needs to be supported seamlessly.<\/li>\n<li><strong>Scalability:<\/strong> NoSQL databases are designed to manage high scalability demands. Event sourcing can generate a vast range of data volumes, from thousands to millions of messages per second. Azure Cosmos DB&#8217;s scale-out architecture, with its highly elastic throughput and storage capabilities, is well-suited to meet these demands.<\/li>\n<li><strong>Change Feed as a Messaging Mechanism:<\/strong> The Change Feed feature in Azure Cosmos DB acts as a centralized and scalable message publishing system. This is particularly useful in event sourcing patterns, where tracking changes and updates in real-time is crucial.<\/li>\n<\/ul>\n<h2>The Scenario:<\/h2>\n<p>A common scenario for using the NoSQL event sourcing data pattern is in building event-driven microservices architectures. Event sourcing can be particularly valuable in such scenarios due to its ability to capture and store all changes to an application&#8217;s state as a sequence of events.<\/p>\n<h3><strong>Scenario: Event-Driven Microservices Architecture<\/strong><\/h3>\n<ol>\n<li>Microservices Communication: In a microservices architecture, different services communicate through events. When an event occurs in one microservice, it can be published to an event bus or event stream. Other microservices can then subscribe to relevant events and react accordingly, updating their own state based on the events received.<\/li>\n<li>Decoupled Components: Event sourcing allows microservices to be loosely coupled. Each microservice focuses on managing its own events and state changes without needing to know the internal workings of other services. This leads to better separation of concerns and enables each microservice to evolve independently.<\/li>\n<li>Scalability: As microservices communicate through events, they can scale independently to manage varying workloads. NoSQL databases, which are often used in event sourcing, are designed to scale horizontally, making them well-suited for supporting the high throughput of events generated and consumed by microservices.<\/li>\n<li>Resilience and Event Replay: In the event of failures or system crashes, event sourcing enables easy recovery by replaying events from the event log. By replaying the events, the application can reconstruct its state and continue processing from the point of failure, ensuring data consistency and reliability.<\/li>\n<li>Audit and Compliance: Event sourcing provides a complete history of events and state changes, offering a robust audit trail. This is valuable for compliance purposes and helps track and understand how the system reached its current state.<\/li>\n<li>Event Versioning and Evolution: As services evolve, events can be versioned, and new event types can be introduced. This allows smooth integration with both new and old versions of services. NoSQL databases&#8217; flexibility in handling different data structures makes it easier to manage event versioning.<\/li>\n<li>Event Replay for Testing and Analytics: Event sourcing allows easy replication of events for testing and analytics purposes. Developers can use a test environment to replay events and verify the behavior of services, while data analysts can analyze the historical event log for insights and business intelligence.<\/li>\n<\/ol>\n<p>Overall, the NoSQL event sourcing data pattern is well-suited for event-driven microservices architectures, enabling scalability, resilience, and loose coupling among microservices. It&#8217;s important to design the events carefully and choose the appropriate NoSQL database that fits the application&#8217;s requirements and expected event throughput. Additionally, this pattern requires careful consideration of event schema evolution to ensure backward and forward compatibility as services evolve over time.<\/p>\n<h3><\/h3>\n<h3>Sample Implementation:<\/h3>\n<p><strong>Case Study: eCommerce Shopping Cart Application<\/strong><\/p>\n<p><strong>Design and Implementation<\/strong><\/p>\n<p>Consider the scenario of an eCommerce company needing to track all changes to a shopping cart. Event sourcing is an ideal choice for this scenario, as it ensures the retention of all history and allows the calculation of the state at any point in time.<\/p>\n<p>In our case study, whenever a change is made to the cart, an event is appended to the <span style=\"font-family: 'courier new', courier, monospace;\"><strong>`shopping_cart_event`<\/strong> <\/span>event store collection. This approach avoids the need for updating multiple containers for each change. The partition key <span style=\"font-family: 'courier new', courier, monospace;\"><strong>\u2018\/cartId\u2019<\/strong><\/span> is used to support the most common queries by the shopping cart service. Other services can consume data from the change feed and leverage solutions like materialized views for different query patterns.<\/p>\n<p><strong>Code Examples<\/strong><\/p>\n<p>Consider the state of products in the cart maintained as <span style=\"font-family: 'courier new', courier, monospace;\"><strong>\u2018productsInCart\u2019<\/strong>.<\/span> This could also be dynamically derived by each query or consumer. Here are sample events in the event store:<\/p>\n<pre class=\"prettyprint language-json\"><code class=\"language-json\">{\r\n  \"cartId\": guid,\r\n  \"sessionId\": guid,\r\n  \"userId\": guid,\r\n  \"eventType\": \"cart_created\",\r\n  \"eventTimestamp\": \"2022-11-28 01:22:04\"\r\n},\r\n{\r\n  \"cartId\": guid,\r\n  \"sessionId\": guid,\r\n  \"userId\": guid,\r\n  \"eventType\": \"product_added\",\r\n  \"product\": \"Product 1\",\r\n  \"quantityChange\": 1,\r\n  \"productsInCart\": [{\"productName\": \"Product 1\", \"quantity\": 1}],\r\n  \"eventTimestamp\": \"2022-11-28 01:22:34\"\r\n},\r\n{\r\n  \"cartId\": guid,\r\n  \"sessionId\": guid,\r\n  \"userId\": guid,\r\n  \"eventType\": \"product_added\",\r\n  \"product\": \"Product 2\",\r\n  \"quantityChange\": 3,\r\n  \"productsInCart\": [{\"productName\": \"Product 1\", \"quantity\": 1},\r\n                     {\"productName\": \"Product 2\", \"quantity\": 3}],\r\n  \"eventTimestamp\": \"2022-11-28 01:22:58\"\r\n},\r\n{\r\n  \"cartId\": guid,\r\n  \"sessionId\": guid,\r\n  \"userId\": guid,\r\n  \"eventType\": \"product_deleted\",\r\n  \"product\": \"Product 2\",\r\n  \"quantityChange\": -1,\r\n  \"productsInCart\": [{\"productName\": \"Product 1\", \"quantity\": 1},\r\n                     {\"productName\": \"Product 2\", \"quantity\": 2}],\r\n  \"eventTimestamp\": \"2022-11-28 01:23:12\"\r\n},\r\n{\r\n  \"cartId\": guid,\r\n  \"sessionId\": guid,\r\n  \"userId\": guid,\r\n  \"eventType\": \"cart_purchased\",\r\n  \"productsInCart\": [{\"productName\": \"Product 1\", \"quantity\": 1},\r\n                     {\"productName\": \"Product 2\", \"quantity\": 2}],\r\n  \"eventTimestamp\": \"2022-11-28 01:24:45\"\r\n}<\/code><\/pre>\n<p><strong>Cost Considerations<\/strong><\/p>\n<p>When designing and implementing this pattern, it&#8217;s essential to consider the cost implications, especially regarding the frequency and volume of events generated.<\/p>\n<p><img decoding=\"async\" width=\"1430\" height=\"567\" class=\"wp-image-7548\" src=\"https:\/\/devblogs.microsoft.com\/cosmosdb\/wp-content\/uploads\/sites\/52\/2024\/02\/word-image-7546-2.png\" srcset=\"https:\/\/devblogs.microsoft.com\/cosmosdb\/wp-content\/uploads\/sites\/52\/2024\/02\/word-image-7546-2.png 1430w, https:\/\/devblogs.microsoft.com\/cosmosdb\/wp-content\/uploads\/sites\/52\/2024\/02\/word-image-7546-2-300x119.png 300w, https:\/\/devblogs.microsoft.com\/cosmosdb\/wp-content\/uploads\/sites\/52\/2024\/02\/word-image-7546-2-1024x406.png 1024w, https:\/\/devblogs.microsoft.com\/cosmosdb\/wp-content\/uploads\/sites\/52\/2024\/02\/word-image-7546-2-768x305.png 768w\" sizes=\"(max-width: 1430px) 100vw, 1430px\" \/><\/p>\n<p><strong>Querying the Event Source Data<\/strong><\/p>\n<p>After populating the event store with data, you can query it directly using Data Explorer in the Azure Portal. Here\u2019s how:<\/p>\n<ol>\n<li>In the Azure Portal, navigate your Azure Cosmos DB resource.<\/li>\n<li>Select Data Explorer from the left menu.<\/li>\n<li>Choose your container and create a new SQL Query.<\/li>\n<\/ol>\n<p>The most common query for this appends-only store is to retrieve events for a specific <span style=\"font-family: 'courier new', courier, monospace;\"><strong>`CartId`<\/strong><\/span>, ordered by <span style=\"font-family: 'courier new', courier, monospace;\"><strong>`EventTimestamp`<\/strong><\/span>. For example, to retrieve the latest event for a cart to know its last status and contents, use a query like:<\/p>\n<pre class=\"prettyprint language-sql\"><code class=\"language-sql\">SELECT *\r\n\r\nFROM CartEvents c\r\n\r\nWHERE c.CartId = \"38f4687d-35f2-4933-aadd-8776f4134589\"\r\n\r\nORDER BY c.EventTimestamp DESC<\/code><\/pre>\n<p><strong>Advanced Queries<\/strong><\/p>\n<p>For more complex scenarios, you can run sophisticated queries on the event container, ideally using the partition key for cost optimization. For instance, if your application does not track <span style=\"font-family: 'courier new', courier, monospace;\"><strong>`productsInCart`<\/strong><\/span>, you can derive this information with a query like:<\/p>\n<pre class=\"prettyprint language-sql\"><code class=\"language-sql\">SELECT c.CartId, c.UserId, c.Product,\r\n\r\nSUM(c.QuantityChange) as Quantity\r\n\r\nFROM CartEvents c\r\n\r\nWHERE c.CartId = \"38f4687d-35f2-4933-aadd-8776f4134589\"\r\n\r\nand IS_NULL(c.Product) = false\r\n\r\nGROUP BY c.CartId, c.UserId, c.Product<\/code><\/pre>\n<p>In our sample implementation, we explored the event sourcing pattern through the lens of a shopping cart application for an eCommerce company using Azure Cosmos DB. The design emphasized tracking all cart changes as events within a single event store collection named <span style=\"font-family: 'courier new', courier, monospace;\"><strong>`shopping_cart_event`<\/strong><\/span>, with <span style=\"font-family: 'courier new', courier, monospace;\"><strong>`\/cartId`<\/strong><\/span> as the partition key to <a id=\"post-7546-_Int_3rocWEXo\"><\/a>optimize query performance. This setup ensures comprehensive historical data tracking and helps efficient data retrieval and processing by various consuming services. We gave concrete examples of event entries and detailed how to query this data effectively using Azure Portal&#8217;s Data Explorer, highlighting the practicality and efficiency of event sourcing in handling dynamic, event-driven data requirements in a NoSQL database environment.<\/p>\n<h2>Why it Matters.<\/h2>\n<p><strong>Event Sourcing with NoSQL is particularly important for developers due to:<\/strong><\/p>\n<ul>\n<li><strong>Immutable History:<\/strong> Ensures a complete, unchangeable record of state changes, enhancing auditability and reliability.<\/li>\n<li><strong>Resilience and Recovery:<\/strong> Helps system recovery and debugging by allowing the replay of events, improving overall system resilience.<\/li>\n<li><strong>Scalability and Performance:<\/strong> Supports handling large data volumes efficiently, crucial for distributed systems.<\/li>\n<li><strong>Flexible Querying:<\/strong> Enables detailed historical data analysis, beneficial for analytics and compliance requirements.<\/li>\n<li><strong>Microservices Compatibility:<\/strong> Promotes decoupled service interactions, aligning well with microservices architectures.<\/li>\n<li><strong>Schema Flexibility:<\/strong> NoSQL databases offer the ease of evolving event schemas without complex migrations.<\/li>\n<li><strong>Real-time Processing:<\/strong> Compatible with real-time data processing and streaming, enabling dynamic, responsive application development.<\/li>\n<\/ul>\n<p>In conclusion, the Event Sourcing NoSQL design pattern offers developers a robust framework for building scalable, resilient, and flexible applications, particularly in complex, distributed environments. Its advantages in terms of system reliability, data integrity, and architectural flexibility make it a valuable pattern in the toolkit of modern software development.<\/p>\n<h2>Getting Started with Azure Cosmos DB Design Patterns<\/h2>\n<p>You can review the sample code by visiting the\u00a0<a href=\"https:\/\/github.com\/Azure-Samples\/cosmos-db-design-patterns\/tree\/main\/event-sourcing\" target=\"_blank\" rel=\"noopener\">Global Distributed Event Sourcing on GitHub<\/a>. You can also try this out for yourself by visiting the\u00a0<a href=\"https:\/\/github.com\/Azure-Samples\/cosmos-db-design-patterns\" target=\"_blank\" rel=\"noopener\">Azure Cosmos DB Design Patterns<\/a>\u00a0GitHub repo and cloning or forking it. Then run locally or from Code Spaces in GitHub. If you are new to Azure Cosmos DB, we have you covered with a\u00a0<a href=\"https:\/\/aka.ms\/trycosmosdb\" target=\"_blank\" rel=\"noopener\">free Azure Cosmos DB account\u00a0<\/a>for <a id=\"post-7546-_Int_fpF4YQgI\"><\/a>30 days, no credit card needed. If you want more time, you can extend the free period. You can even upgrade too.<\/p>\n<p>Sign up for your free Azure Cosmos DB account at\u00a0<a href=\"https:\/\/aka.ms\/trycosmosdb\">aka.ms\/trycosmosdb<\/a>.<\/p>\n<p>Explore this and the other design patterns and see how Azure Cosmos DB can enhance your application development and data modeling efforts. Whether you\u2019re an experienced developer or just getting started, the free trial allows you to discover the benefits firsthand.<\/p>\n<p>To get started with Azure Cosmos DB Design Patterns, follow these steps:<\/p>\n<ol>\n<li>Visit the\u00a0<a href=\"https:\/\/github.com\/Azure-Samples\/cosmos-db-design-patterns\" target=\"_blank\" rel=\"noopener\">GitHub repository\u00a0<\/a>and explore the various design patterns and best practices provided.<\/li>\n<li>Clone or download the repository to access the sample code and documentation.<\/li>\n<li>Review the README files and documentation for each design pattern to understand when and how to apply them to your Azure Cosmos DB projects.<\/li>\n<li>Experiment with the sample code and adapt it to your specific use cases.<\/li>\n<\/ol>\n<h3>About Azure Cosmos DB<\/h3>\n<p>Azure Cosmos DB is a fully managed and serverless distributed database for modern app development, with SLA-backed speed and availability, automatic and instant scalability, and support for open-source PostgreSQL, MongoDB, and Apache Cassandra.\u00a0<a href=\"https:\/\/cosmos.azure.com\/try\/\" target=\"_blank\" rel=\"noopener\">Try Azure Cosmos DB for free here.<\/a>\u00a0To stay in the loop on Azure Cosmos DB updates, follow us on\u00a0<a href=\"https:\/\/twitter.com\/AzureCosmosDB\" target=\"_blank\" rel=\"noopener\">Twitter<\/a>,\u00a0<a href=\"https:\/\/www.youtube.com\/AzureCosmosDB\" target=\"_blank\" rel=\"noopener\">YouTube<\/a>, and\u00a0<a href=\"https:\/\/www.linkedin.com\/company\/azure-cosmos-db\/\" target=\"_blank\" rel=\"noopener\">LinkedIn<\/a>.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>We&#8217;re excited to present the sixth edition of our blog series, dedicated to exploring design patterns in Azure Cosmos DB for NoSQL applications. Drawing from real-world customer experiences, our aim is to help you navigate the intricacies of JSON-based NoSQL databases. In this chapter, we delve deeper into prevalent NoSQL patterns, perfect for those new [&hellip;]<\/p>\n","protected":false},"author":39313,"featured_media":7547,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[14],"tags":[1882],"class_list":["post-7546","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-core-sql-api","tag-design-patterns"],"acf":[],"blog_post_summary":"<p>We&#8217;re excited to present the sixth edition of our blog series, dedicated to exploring design patterns in Azure Cosmos DB for NoSQL applications. Drawing from real-world customer experiences, our aim is to help you navigate the intricacies of JSON-based NoSQL databases. In this chapter, we delve deeper into prevalent NoSQL patterns, perfect for those new [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/cosmosdb\/wp-json\/wp\/v2\/posts\/7546","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/devblogs.microsoft.com\/cosmosdb\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/devblogs.microsoft.com\/cosmosdb\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/cosmosdb\/wp-json\/wp\/v2\/users\/39313"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/cosmosdb\/wp-json\/wp\/v2\/comments?post=7546"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/cosmosdb\/wp-json\/wp\/v2\/posts\/7546\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/cosmosdb\/wp-json\/wp\/v2\/media\/7547"}],"wp:attachment":[{"href":"https:\/\/devblogs.microsoft.com\/cosmosdb\/wp-json\/wp\/v2\/media?parent=7546"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/cosmosdb\/wp-json\/wp\/v2\/categories?post=7546"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/cosmosdb\/wp-json\/wp\/v2\/tags?post=7546"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}