{"id":13061,"date":"2022-04-12T10:11:38","date_gmt":"2022-04-12T17:11:38","guid":{"rendered":"https:\/\/www.couchbase.com\/blog\/?p=13061"},"modified":"2024-05-08T07:18:22","modified_gmt":"2024-05-08T14:18:22","slug":"event-broker-integration-with-couchbase-solace-java","status":"publish","type":"post","link":"https:\/\/www.couchbase.com\/blog\/event-broker-integration-with-couchbase-solace-java\/","title":{"rendered":"Event Broker Integration with Couchbase, Solace &#038; Java"},"content":{"rendered":"<p><span style=\"font-weight: 400\">In the previous <\/span><a href=\"https:\/\/www.couchbase.com\/blog\/event-driven-architecture-with-solace-event-broker-couchbase\/\"><span style=\"font-weight: 400\">blog post<\/span><\/a><span style=\"font-weight: 400\"> we discussed how Couchbase can seamlessly integrate into an <\/span><i><span style=\"font-weight: 400\">Event-Driven Architecture<\/span><\/i><span style=\"font-weight: 400\">. Using the Couchbase Eventing Service, document mutations can be published to a <\/span><a href=\"https:\/\/solace.com\/products\/event-broker\/software\/\"><span style=\"font-weight: 400\">Solace PubSub+<\/span><\/a><span style=\"font-weight: 400\"> queue from where the data is made available to subscribing microservices in near real-time.<\/span><\/p>\n<p><span style=\"font-weight: 400\">This post focuses on how microservices as Topic subscribers can leverage Couchbase as a scalable &amp; resilient datastore.<\/span><\/p>\n<p><b>Architecture overview &amp; sample application<\/b><\/p>\n<p><span style=\"font-weight: 400\">In this <a href=\"https:\/\/github.com\/puhhma\/cb_solace_blog_example\">sample application<\/a>, we subscribe to a Solace PubSub+ Topic, process the data, and update the document in Couchbase.<\/span><\/p>\n<p><span style=\"font-weight: 400\">In our example application, we store hotel details in Couchbase. Updates to the hotel configuration are published to a Solace PubSub+ topic. We build an application that subscribes to the Topic, retrieves the updated data and updates the existing hotel configuration in Couchbase.<\/span><\/p>\n<p><span style=\"font-weight: 400\">We use the <\/span><i><span style=\"font-weight: 400\">travel-sample<\/span><\/i><span style=\"font-weight: 400\"> bucket that contains sample data such as <\/span><i><span style=\"font-weight: 400\">flights<\/span><\/i><span style=\"font-weight: 400\">, <\/span><i><span style=\"font-weight: 400\">routes<\/span><\/i><span style=\"font-weight: 400\"> and others. In our example, we focus on the <\/span><i><span style=\"font-weight: 400\">hotel<\/span><\/i><span style=\"font-weight: 400\"> documents stored in the <\/span><i><span style=\"font-weight: 400\">inventory<\/span><\/i><span style=\"font-weight: 400\"> scope in the <\/span><i><span style=\"font-weight: 400\">hotel<\/span><\/i><span style=\"font-weight: 400\"> collection. All hotel documents consist of a JSON document with various attributes.<\/span><\/p>\n<p><span style=\"font-weight: 400\">We will update only a small subset of attributes for this tutorial, such as <\/span><i><span style=\"font-weight: 400\">pets_allowed<\/span><\/i><span style=\"font-weight: 400\"> and <\/span><i><span style=\"font-weight: 400\">free_internet<\/span><\/i><span style=\"font-weight: 400\">.<\/span><\/p>\n<div id=\"attachment_13062\" style=\"width: 910px\" class=\"wp-caption alignnone\"><img loading=\"lazy\" decoding=\"async\" aria-describedby=\"caption-attachment-13062\" class=\"size-large wp-image-13062\" src=\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/2022\/04\/image3-1024x438.png\" alt=\"Event-driven architecture with Solace and Couchbase\" width=\"900\" height=\"385\" srcset=\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2022\/04\/image3-1024x438.png 1024w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2022\/04\/image3-300x128.png 300w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2022\/04\/image3-768x329.png 768w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2022\/04\/image3-1536x658.png 1536w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2022\/04\/image3-20x9.png 20w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2022\/04\/image3-1320x565.png 1320w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2022\/04\/image3.png 1999w\" sizes=\"auto, (max-width: 900px) 100vw, 900px\" \/><p id=\"caption-attachment-13062\" class=\"wp-caption-text\">The sample application subscribes to a Solace Topic and updates hotel data in Couchbase. Other applications may provide the hotel configuration changes. We use a simple service that publishes updates to the Topic.<\/p><\/div>\n<p><i><span style=\"font-weight: 400\">Caption: The sample application subscribes to a Solace Topic and updates hotel data in Couchbase. Other applications may provide the hotel configuration changes. We use a simple service that publishes updates to the Topic.<\/span><\/i><\/p>\n<h2><span style=\"font-weight: 400\">Prerequisites<\/span><\/h2>\n<p><span style=\"font-weight: 400\">Please review the prerequisites for this sample application:<\/span><\/p>\n<p><b>Couchbase Capella<\/b><\/p>\n<p><span style=\"font-weight: 400\">Create a free <\/span><a href=\"https:\/\/www.couchbase.com\/products\/capella\/\"><span style=\"font-weight: 400\">Couchbase Capella<\/span><\/a><span style=\"font-weight: 400\"> trial account and follow the instructions to provision your trial cluster. This only takes a few minutes and gives you a fully-fledged Couchbase cluster, including the <\/span><i><span style=\"font-weight: 400\">Data<\/span><\/i><span style=\"font-weight: 400\"> service and the sample dataset, <\/span><i><span style=\"font-weight: 400\">travel-sample,<\/span><\/i><span style=\"font-weight: 400\"> that we will use throughout this blog post.<\/span><\/p>\n<p><span style=\"font-weight: 400\">You can use this tutorial when not using our managed Couchbase Capella offering. The <\/span><i><span style=\"font-weight: 400\">travel-sample<\/span><\/i><span style=\"font-weight: 400\"> bucket is part of the Couchbase server product and can be imported using the Couchbase console.<\/span><\/p>\n<p><b>Solace PubSub+ Event Broker Cloud<\/b><\/p>\n<p><span style=\"font-weight: 400\">Sign up for a free <\/span><a href=\"https:\/\/solace.com\/products\/platform\/cloud\/\"><span style=\"font-weight: 400\">Solace cloud trial<\/span><\/a><span style=\"font-weight: 400\"> and create a Service\/VPN. We will use the VPN to connect to a Solace Topic.<\/span><\/p>\n<p>&nbsp;<\/p>\n<h2><span style=\"font-weight: 400\">Code review &#8211; Solace subscriber &amp; publisher<\/span><\/h2>\n<p><span style=\"font-weight: 400\">To subscribe to messages from the Solace Topic we use the Solace Java API. This example implementation is derived from examples in the Solace documentation. For implementation details consult the Solace documentation.<\/span><\/p>\n<pre class=\"decode-attributes:false lang:java decode:true\">final JCSMPProperties properties = new JCSMPProperties();\r\nproperties.setProperty(JCSMPProperties.HOST, \"tcps:\/\/yourhost.messaging.solace.cloud:55443\");\r\nproperties.setProperty(JCSMPProperties.USERNAME, \"solace-cloud-client\");\r\nproperties.setProperty(JCSMPProperties.PASSWORD, \"password\");\r\nproperties.setProperty(JCSMPProperties.VPN_NAME, \"couchbasedemo\");\r\nJCSMPSession session = JCSMPFactory.onlyInstance().createSession(properties);\r\nsession.connect();\r\n\r\nfinal Topic topic = JCSMPFactory.onlyInstance().createTopic(\"tutorial\/topic\");<\/pre>\n<p><span style=\"font-weight: 400\">We set up the <\/span><i><span style=\"font-weight: 400\">JCSMPProperties<\/span><\/i><span style=\"font-weight: 400\"> with the relevant access information available in the Solace web interface. We then create a <\/span><i><span style=\"font-weight: 400\">JCSMPSession<\/span><\/i><span style=\"font-weight: 400\"> and a <\/span><i><span style=\"font-weight: 400\">Topic<\/span><\/i><span style=\"font-weight: 400\">.<\/span><\/p>\n<p><span style=\"font-weight: 400\">To subscribe to the messages on the Topic we implement an <\/span><i><span style=\"font-weight: 400\">XMLMessageConsumer<\/span><\/i><span style=\"font-weight: 400\">:<\/span><\/p>\n<pre class=\"decode-attributes:false lang:java decode:true\">\/\/ ### Message Receiver - Subscribe to Topic ###\r\nfinal XMLMessageConsumer cons = session.getMessageConsumer(new XMLMessageListener() {\r\n  @Override\r\n  public void onReceive(BytesXMLMessage msg) {\r\n    if (msg instanceof TextMessage) {\r\n      System.out.printf(\"SUBSCRIBE: Message received: '%s'%n\", ((TextMessage) msg).getText());\r\n      UpdateHotelData.getInstance().upsertHotelData(((TextMessage) msg).getText());\r\n    } else {\r\n      System.out.println(\"Message received.\");\r\n    }\r\n  }\r\n\r\n  @Override\r\n  public void onException(JCSMPException e) {\r\n    System.out.printf(\"Consumer received exception: %s%n\", e);\r\n  }\r\n});\r\nsession.addSubscription(topic);\r\nSystem.out.println(\"SUBSCRIBE: Connected. Awaiting message...\");\r\ncons.start();<\/pre>\n<p>In the <i>onReceive<\/i> method, we take the message, convert it to a string and then call the <i>upsertHotelData<\/i> method of <i>UpdateHotelData <\/i>class that contains the Couchbase implementation discussed a bit later in this blog post.<\/p>\n<p><span style=\"font-weight: 400\">We add the topic subscription to the session and start the message consumer.<\/span><\/p>\n<p><span style=\"font-weight: 400\">In order to be able to test the implementation, we also create a message publisher. For this, we first implement an <\/span><i><span style=\"font-weight: 400\">XMLMessageProducer<\/span><\/i><span style=\"font-weight: 400\">.<\/span><\/p>\n<pre class=\"decode-attributes:false lang:java decode:true\">\/\/ ### Message Producer - Send message to Topic\r\nXMLMessageProducer prod = session.getMessageProducer(new JCSMPStreamingPublishCorrelatingEventHandler() {\r\n  @Override\r\n  public void responseReceivedEx(Object key) {\r\n    System.out.println(\"Producer received response for msg: \" + key.toString());\r\n  }\r\n\r\n  @Override\r\n  public void handleErrorEx(Object key, JCSMPException cause, long timestamp) {\r\n    System.out.printf(\"Producer received error for msg: %s@%s - %s%n\", key.toString(), timestamp, cause);\r\n  }\r\n});<\/pre>\n<p><span style=\"font-weight: 400\">With the message producer in place, we can now send messages as seen below.\u00a0<\/span><\/p>\n<pre class=\"decode-attributes:false lang:java decode:true\">\/\/ Send messages. Here we loop through and send the same message multiple times.\r\nfor (int msgsSent = 0; msgsSent &lt; 2; ++msgsSent) {\r\n  TextMessage msg = JCSMPFactory.onlyInstance().createMessage(TextMessage.class);\r\n  msg.setText(data);\r\n  System.out.printf(\"PUBLISH: Sending message '%s' to topic '%s'...%n\", data, topic.getName());\r\n  prod.send(msg, topic);\r\n  \/\/Gives us some time to follow the console logs\r\n  Thread.sleep(3000);\r\n}<\/pre>\n<h3><span style=\"font-weight: 400\">Upserting the data to Couchbase<\/span><\/h3>\n<p><span style=\"font-weight: 400\">With the logic to subscribe and publish messages in place, let\u2019s now focus on how to update the hotel documents in Couchbase.<\/span><\/p>\n<p><span style=\"font-weight: 400\">For this example, we assume that the message retrieved from the Topic has the JSON format below. Including a <\/span><i><span style=\"font-weight: 400\">hotel_id<\/span><\/i><span style=\"font-weight: 400\"> that we will use as the document id of the hotel documents stored in Couchbase, as well as a number of attributes that we can change:<\/span><\/p>\n<pre class=\"decode-attributes:false lang:js decode:true\">{\r\n\u00a0\u00a0\"hotel_id\": \"hotel_10025\",\r\n\u00a0\u00a0\"pets_ok\": true,\r\n\u00a0\u00a0\"free_breakfast\": true,\r\n\u00a0\u00a0\"free_internet\": true,\r\n\u00a0\u00a0\"free_parking\": true\r\n}<\/pre>\n<p><span style=\"font-weight: 400\">To establish a secure connection from our application to Couchbase Capella, we need to:<\/span><\/p>\n<ul>\n<li style=\"list-style-type: none\">\n<ul>\n<li style=\"font-weight: 400\"><span style=\"font-weight: 400\">Create a database user and grant this user access to the hotel data.<\/span><\/li>\n<li style=\"font-weight: 400\"><span style=\"font-weight: 400\">Whitelist the IP address of the host running the application<\/span><\/li>\n<li style=\"font-weight: 400\"><span style=\"font-weight: 400\">Capture the secure connection URL<\/span><\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<p><span style=\"font-weight: 400\">You can manage all these details in the Capella management plane. <\/span><a href=\"https:\/\/cloud.couchbase.com\"><span style=\"font-weight: 400\">Login to Capella<\/span><\/a><span style=\"font-weight: 400\"> in the browser:<\/span><\/p>\n<ol>\n<li style=\"font-weight: 400\"><span style=\"font-weight: 400\">Open the <\/span><b>Trial &#8211; Cluster<\/b><span style=\"font-weight: 400\"> cluster and navigate to the <\/span><b>Connect <\/b><span style=\"font-weight: 400\">tab<\/span><\/li>\n<li style=\"font-weight: 400\"><span style=\"font-weight: 400\">Scroll down to the <\/span><b>Database Access<\/b><span style=\"font-weight: 400\"> section and click on <\/span><b>Manage Credentials<\/b><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-large wp-image-13063\" src=\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/2022\/04\/image4-1024x377.png\" alt=\"Set database access credentials in Couchbase Capella\" width=\"900\" height=\"331\" srcset=\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2022\/04\/image4-1024x377.png 1024w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2022\/04\/image4-300x110.png 300w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2022\/04\/image4-768x283.png 768w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2022\/04\/image4-20x7.png 20w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2022\/04\/image4.png 1162w\" sizes=\"auto, (max-width: 900px) 100vw, 900px\" \/><\/li>\n<li><span style=\"font-weight: 400\">Click on <\/span><i><span style=\"font-weight: 400\">Create Database Credentials<\/span><\/i><span style=\"font-weight: 400\"> and provide a database username and password. Configure the Bucket level access to the <\/span><i><span style=\"font-weight: 400\">inventory<\/span><\/i><span style=\"font-weight: 400\"> scope in the <\/span><i><span style=\"font-weight: 400\">travel-sample<\/span><\/i><span style=\"font-weight: 400\"> bucket and grant Read\/Write access.<br \/>\n<img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-large wp-image-13064\" src=\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/2022\/04\/image2-1024x1003.png\" alt=\"Set cluster database credentials in Couchbase Capella\" width=\"900\" height=\"882\" srcset=\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2022\/04\/image2-1024x1003.png 1024w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2022\/04\/image2-300x294.png 300w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2022\/04\/image2-768x752.png 768w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2022\/04\/image2-65x65.png 65w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2022\/04\/image2-50x50.png 50w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2022\/04\/image2-20x20.png 20w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2022\/04\/image2.png 1270w\" sizes=\"auto, (max-width: 900px) 100vw, 900px\" \/><br \/>\n<\/span><\/li>\n<li><span style=\"font-weight: 400\">Whitelist the application IP address by clicking on <\/span><b>Manage Allowed IP<\/b><span style=\"font-weight: 400\"> and then <\/span><b>Add Allowed IP<\/b><span style=\"font-weight: 400\">. When running the application from your local machine, simply click <\/span><b>Add My IP<\/b><span style=\"font-weight: 400\"> and your external IP address will be discovered and added automatically.<br \/>\n<img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-large wp-image-13065\" src=\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/2022\/04\/image1-1024x642.png\" alt=\"Whitelist an IP address in Couchbase Capella \" width=\"900\" height=\"564\" srcset=\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2022\/04\/image1-1024x642.png 1024w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2022\/04\/image1-300x188.png 300w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2022\/04\/image1-768x482.png 768w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2022\/04\/image1-1536x963.png 1536w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2022\/04\/image1-20x13.png 20w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2022\/04\/image1-1320x828.png 1320w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2022\/04\/image1.png 1674w\" sizes=\"auto, (max-width: 900px) 100vw, 900px\" \/><br \/>\n<\/span><\/li>\n<li><span style=\"font-weight: 400\">In the <\/span><b>Wide Area Network<\/b><span style=\"font-weight: 400\"> section copy the connection URL.<\/span><\/li>\n<\/ol>\n<h2><span style=\"font-weight: 400\">Code review &#8211; connect to Couchbase and update documents<\/span><\/h2>\n<p><span style=\"font-weight: 400\">We connect to Couchbase Capella as the first step by creating a cluster object. We provide the endpoint URL captured in the previous step as well as the database user credentials.<\/span><\/p>\n<pre class=\"decode-attributes:false lang:java decode:true\">\/\/ Update this to your cluster\r\nString endpoint = \"cb.8c-f5di7pqrfjy8.cloud.couchbase.com\";\r\nString username = \"dbuser\";\r\nString password = \"Passw0rd!\";\r\n\/\/ User Input ends here.\r\n\r\nString bucketName = \"travel-sample\";\r\n\r\n\/\/ Cluster Environment configuration\r\nClusterEnvironment env = ClusterEnvironment.builder()\r\n  .securityConfig(\r\n    SecurityConfig.enableTls(true).trustManagerFactory(InsecureTrustManagerFactory.INSTANCE))\r\n  .ioConfig(IoConfig.enableDnsSrv(true)).build();\r\n\r\n\/\/ Initialize the Connection and provide database user credentials\r\nCluster cluster = Cluster.connect(endpoint, ClusterOptions.clusterOptions(username, password).environment(env));\r\n\r\n\/\/ Create bucket object\r\nbucket = cluster.bucket(bucketName);\r\nbucket.waitUntilReady(Duration.parse(\"PT10S\"));\r\n\/\/ create collection object for the 'hotel' collection located in the 'inventory' scope\r\ncollection = bucket.scope(\"inventory\").collection(\"hotel\");<\/pre>\n<p><span style=\"font-weight: 400\">Once the bucket object is created we can retrieve the <\/span><i><span style=\"font-weight: 400\">hotel<\/span><\/i><span style=\"font-weight: 400\"> scope and use it later to upsert the document changes. The <\/span><i><span style=\"font-weight: 400\">hotel<\/span><\/i><span style=\"font-weight: 400\"> scope is within the <\/span><i><span style=\"font-weight: 400\">inventory<\/span><\/i><span style=\"font-weight: 400\"> scope of the <\/span><i><span style=\"font-weight: 400\">travel-sample<\/span><\/i><span style=\"font-weight: 400\"> bucket.<\/span><\/p>\n<p><span style=\"font-weight: 400\">Please note, that I use the singleton pattern in order to use the same collection object for all subsequent requests. See the sample implementation for details in <a href=\"https:\/\/github.com\/puhhma\/cb_solace_blog_example\" target=\"_blank\" rel=\"noopener\">my GitHub project<\/a>. <\/span><\/p>\n<p><span style=\"font-weight: 400\">Let\u2019s now look into how we can update the hotel documents with the data received from the Topic.<\/span><\/p>\n<p><span style=\"font-weight: 400\">The message received is a String so as the first step we need to convert it into a JSON object.<\/span><\/p>\n<pre class=\"decode-attributes:false lang:java decode:true\">public void upsertHotelData(String content) {\r\n    \u2026\r\n    hotelData = JsonObject.fromJson(content);\r\n    \u2026<\/pre>\n<p><span style=\"font-weight: 400\">Since the input data from the Topic contains only a subset of all the attributes of the hotel document, we need to consider how to update the document fields most efficiently.\u00a0<\/span><\/p>\n<p><span style=\"font-weight: 400\">There are two possible options:<\/span><\/p>\n<ol>\n<li style=\"list-style-type: none\">\n<ol>\n<li style=\"font-weight: 400\"><span style=\"font-weight: 400\">We use the document ID to retrieve the full document from Couchbase, update the attributes and write the document back.<\/span><\/li>\n<li style=\"font-weight: 400\"><span style=\"font-weight: 400\">We use the sub-document API in Couchbase to only update dedicated fields within the document instead of replacing the entire document.<\/span><\/li>\n<\/ol>\n<\/li>\n<\/ol>\n<p><span style=\"font-weight: 400\">Option one is commonly used to update or upsert documents. However, if we work with bigger documents and we only want to update a small portion of it there is no need to send the entire document over the network. In our implementation below, we will use the sub-document API to resolve and update fields in the hotel document.<\/span><\/p>\n<pre class=\"decode-attributes:false lang:java decode:true\">\/\/Instead of resolving the entire document we use the sub-document API&amp;nbsp;\r\n\/\/to only resolve the relevant parts of the hotel document prior to the update.\r\n\/\/Here we can define the path to the relevant attributes of the document.\r\n\/\/In our scenario 'pets_ok' and 'free_internet' are at the document root.\r\nLookupInResult result = collection.lookupIn(hotelData.getString(\"hotel_id\"),\r\n    Arrays.asList(get(\"pets_ok\"), get(\"free_internet\")));\r\n\r\n\/\/Display the current values prior to the document update\r\nSystem.out.println(\"Values prior to update: 'pets_ok': \" +&amp;nbsp; result.contentAs(0, String.class) + \", 'free_internet': \" + result.contentAs(1, String.class));<\/pre>\n<p><span style=\"font-weight: 400\">We use the <\/span><i><span style=\"font-weight: 400\">lookupIn<\/span><\/i><span style=\"font-weight: 400\"> operation to query the document for certain paths. Whereby different components in the path are separated by dots (.). The <\/span><i><span style=\"font-weight: 400\">pets_ok<\/span><\/i><span style=\"font-weight: 400\"> and <\/span><i><span style=\"font-weight: 400\">free_internet <\/span><\/i><span style=\"font-weight: 400\">attributes are located at the document root in our scenario. We then traverse through the result and display the current values.<\/span><\/p>\n<pre class=\"decode-attributes:false lang:java decode:true\">\/\/Even here we use the sub-document API.\r\n\/\/Instead of updating the entire document we only update the relevant attributes.\r\n\/\/The UPSERT method will either update the attributes if they already exist or create them in case they do not exist in within the document\r\nMutateInResult upsertResult = collection.mutateIn(hotelData.getString(\"hotel_id\"),\r\n    Arrays.asList(upsert(\"pets_ok\", hotelData.getBoolean(\"pets_ok\")),\r\n        upsert(\"free_internet\", hotelData.getBoolean(\"free_internet\"))));<\/pre>\n<p><span style=\"font-weight: 400\">The <\/span><i><span style=\"font-weight: 400\">mutateIn<\/span><\/i><span style=\"font-weight: 400\"> operation allows the update of one or more paths in a document. We identify the document in Couchbase by its ID and provide an array of paths and values we want to set.<\/span><\/p>\n<p><span style=\"font-weight: 400\">Last but not least, we run the <\/span><i><span style=\"font-weight: 400\">lookupIn<\/span><\/i><span style=\"font-weight: 400\"> operation to verify that the update was successful.<\/span><\/p>\n<pre class=\"decode-attributes:false lang:java decode:true\">\/\/Resolve and display the updated attributes\u00a0\u00a0\r\nLookupInResult result1 = collection.lookupIn(hotelData.getString(\"hotel_id\"),\r\n    Arrays.asList(get(\"pets_ok\"), get(\"free_internet\")));\r\nSystem.out.println(\"Values after the update: 'pets_ok': \" +\u00a0 result1.contentAs(0, String.class) + \", 'free_internet': \" + result1.contentAs(1, String.class));<\/pre>\n<h2><span style=\"font-weight: 400\">Next steps<\/span><\/h2>\n<p><span style=\"font-weight: 400\">This article taught us to integrate Solace event broker with Couchbase using the Couchbase &amp; Solace Java SDKs.<\/span><\/p>\n<ul>\n<li><span style=\"font-weight: 400\">The full code example is available in <a href=\"https:\/\/github.com\/puhhma\/cb_solace_blog_example\" target=\"_blank\" rel=\"noopener\">my GitHub repository for this project<\/a>.\u00a0<\/span><\/li>\n<li style=\"font-weight: 400\"><span style=\"font-weight: 400\">Learn to send messages <em>from<\/em> Couchbase to a Solace Topic <\/span><a href=\"https:\/\/www.couchbase.com\/blog\/event-driven-architecture-with-solace-event-broker-couchbase\/\"><span style=\"font-weight: 400\">in this blog post (Part 1)<\/span><\/a><span style=\"font-weight: 400\">.<\/span><\/li>\n<li style=\"font-weight: 400\"><span style=\"font-weight: 400\">Read about the available <\/span><a href=\"https:\/\/docs.couchbase.com\/home\/sdk.html\"><span style=\"font-weight: 400\">Couchbase SDKs here<\/span><\/a><span style=\"font-weight: 400\">.<\/span><\/li>\n<li style=\"font-weight: 400\"><span style=\"font-weight: 400\">Use the <\/span><a href=\"https:\/\/cloud.couchbase.com\/sign-up\"><span style=\"font-weight: 400\">Couchbase playground<\/span><\/a><span style=\"font-weight: 400\"> to start developing quickly.<\/span><\/li>\n<li style=\"font-weight: 400\"><span style=\"font-weight: 400\">Try <\/span><a href=\"https:\/\/solace.com\/products\/platform\/cloud\/\"><span style=\"font-weight: 400\">Solace PubSub+ Cloud<\/span><\/a><span style=\"font-weight: 400\"> with a trial.<\/span><\/li>\n<li style=\"font-weight: 400\"><span style=\"font-weight: 400\">Start using Couchbase today with the <\/span><a href=\"https:\/\/cloud.couchbase.com\/\"><span style=\"font-weight: 400\">Couchbase Capella cloud database<\/span><\/a><span style=\"font-weight: 400\">.<\/span><\/li>\n<\/ul>\n","protected":false},"excerpt":{"rendered":"<p>In the previous blog post we discussed how Couchbase can seamlessly integrate into an Event-Driven Architecture. Using the Couchbase Eventing Service, document mutations can be published to a Solace PubSub+ queue from where the data is made available to subscribing [&hellip;]<\/p>\n","protected":false},"author":77950,"featured_media":13023,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"inline_featured_image":false,"footnotes":""},"categories":[1814,2225,1818,2201],"tags":[1311,9564,9566,9565],"ppma_author":[9323],"class_list":["post-13061","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-application-design","category-cloud","category-java","category-tools-sdks","tag-architecture","tag-event-driven","tag-pubsub","tag-solace"],"acf":[],"yoast_head":"<!-- This site is optimized with the Yoast SEO Premium plugin v25.8 (Yoast SEO v25.8) - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<title>Event Broker Integration with Couchbase, Solace &amp; Java<\/title>\n<meta name=\"description\" content=\"Following up from an earlier post, learn to pull events from Solace PubSub topics to update a Couchbase datastore using a Java-based microservice.\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/www.couchbase.com\/blog\/event-broker-integration-with-couchbase-solace-java\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Event Broker Integration with Couchbase, Solace &amp; Java\" \/>\n<meta property=\"og:description\" content=\"Following up from an earlier post, learn to pull events from Solace PubSub topics to update a Couchbase datastore using a Java-based microservice.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.couchbase.com\/blog\/event-broker-integration-with-couchbase-solace-java\/\" \/>\n<meta property=\"og:site_name\" content=\"The Couchbase Blog\" \/>\n<meta property=\"article:published_time\" content=\"2022-04-12T17:11:38+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2024-05-08T14:18:22+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/2022\/04\/mobile-code-edit-vscode-couchbase-lite-scaled.jpg\" \/>\n\t<meta property=\"og:image:width\" content=\"2560\" \/>\n\t<meta property=\"og:image:height\" content=\"1704\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/jpeg\" \/>\n<meta name=\"author\" content=\"Marian Puhl, Solutions Engineer\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Marian Puhl, Solutions Engineer\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"7 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/event-broker-integration-with-couchbase-solace-java\/#article\",\"isPartOf\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/event-broker-integration-with-couchbase-solace-java\/\"},\"author\":{\"name\":\"Marian Puhl, Solutions Engineer\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/#\/schema\/person\/b2fc479528e2819b50082a425cf381e3\"},\"headline\":\"Event Broker Integration with Couchbase, Solace &#038; Java\",\"datePublished\":\"2022-04-12T17:11:38+00:00\",\"dateModified\":\"2024-05-08T14:18:22+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/event-broker-integration-with-couchbase-solace-java\/\"},\"wordCount\":1247,\"commentCount\":0,\"publisher\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/#organization\"},\"image\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/event-broker-integration-with-couchbase-solace-java\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2022\/04\/mobile-code-edit-vscode-couchbase-lite-scaled.jpg\",\"keywords\":[\"Architecture\",\"event-driven\",\"pubsub\",\"solace\"],\"articleSection\":[\"Application Design\",\"Couchbase Capella\",\"Java\",\"Tools &amp; SDKs\"],\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\/\/www.couchbase.com\/blog\/event-broker-integration-with-couchbase-solace-java\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/event-broker-integration-with-couchbase-solace-java\/\",\"url\":\"https:\/\/www.couchbase.com\/blog\/event-broker-integration-with-couchbase-solace-java\/\",\"name\":\"Event Broker Integration with Couchbase, Solace & Java\",\"isPartOf\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/event-broker-integration-with-couchbase-solace-java\/#primaryimage\"},\"image\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/event-broker-integration-with-couchbase-solace-java\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2022\/04\/mobile-code-edit-vscode-couchbase-lite-scaled.jpg\",\"datePublished\":\"2022-04-12T17:11:38+00:00\",\"dateModified\":\"2024-05-08T14:18:22+00:00\",\"description\":\"Following up from an earlier post, learn to pull events from Solace PubSub topics to update a Couchbase datastore using a Java-based microservice.\",\"breadcrumb\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/event-broker-integration-with-couchbase-solace-java\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/www.couchbase.com\/blog\/event-broker-integration-with-couchbase-solace-java\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/event-broker-integration-with-couchbase-solace-java\/#primaryimage\",\"url\":\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2022\/04\/mobile-code-edit-vscode-couchbase-lite-scaled.jpg\",\"contentUrl\":\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2022\/04\/mobile-code-edit-vscode-couchbase-lite-scaled.jpg\",\"width\":2560,\"height\":1704,\"caption\":\"Consume events from Solace into Couchbase\"},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/event-broker-integration-with-couchbase-solace-java\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/www.couchbase.com\/blog\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Event Broker Integration with Couchbase, Solace &#038; Java\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/#website\",\"url\":\"https:\/\/www.couchbase.com\/blog\/\",\"name\":\"The Couchbase Blog\",\"description\":\"Couchbase, the NoSQL Database\",\"publisher\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/www.couchbase.com\/blog\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Organization\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/#organization\",\"name\":\"The Couchbase Blog\",\"url\":\"https:\/\/www.couchbase.com\/blog\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/#\/schema\/logo\/image\/\",\"url\":\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/2023\/04\/admin-logo.png\",\"contentUrl\":\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/2023\/04\/admin-logo.png\",\"width\":218,\"height\":34,\"caption\":\"The Couchbase Blog\"},\"image\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/#\/schema\/logo\/image\/\"}},{\"@type\":\"Person\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/#\/schema\/person\/b2fc479528e2819b50082a425cf381e3\",\"name\":\"Marian Puhl, Solutions Engineer\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/#\/schema\/person\/image\/1f65549252c18bb3651eaa3a78e46169\",\"url\":\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2021\/07\/marian-puhl-couchbase-engineering.jpeg\",\"contentUrl\":\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2021\/07\/marian-puhl-couchbase-engineering.jpeg\",\"caption\":\"Marian Puhl, Solutions Engineer\"},\"description\":\"Marian Puhl is a Solutions Engineer at Couchbase in the Nordic region.\",\"url\":\"https:\/\/www.couchbase.com\/blog\/author\/marian-puhl\/\"}]}<\/script>\n<!-- \/ Yoast SEO Premium plugin. -->","yoast_head_json":{"title":"Event Broker Integration with Couchbase, Solace & Java","description":"Following up from an earlier post, learn to pull events from Solace PubSub topics to update a Couchbase datastore using a Java-based microservice.","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/www.couchbase.com\/blog\/event-broker-integration-with-couchbase-solace-java\/","og_locale":"en_US","og_type":"article","og_title":"Event Broker Integration with Couchbase, Solace & Java","og_description":"Following up from an earlier post, learn to pull events from Solace PubSub topics to update a Couchbase datastore using a Java-based microservice.","og_url":"https:\/\/www.couchbase.com\/blog\/event-broker-integration-with-couchbase-solace-java\/","og_site_name":"The Couchbase Blog","article_published_time":"2022-04-12T17:11:38+00:00","article_modified_time":"2024-05-08T14:18:22+00:00","og_image":[{"width":2560,"height":1704,"url":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/2022\/04\/mobile-code-edit-vscode-couchbase-lite-scaled.jpg","type":"image\/jpeg"}],"author":"Marian Puhl, Solutions Engineer","twitter_card":"summary_large_image","twitter_misc":{"Written by":"Marian Puhl, Solutions Engineer","Est. reading time":"7 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/www.couchbase.com\/blog\/event-broker-integration-with-couchbase-solace-java\/#article","isPartOf":{"@id":"https:\/\/www.couchbase.com\/blog\/event-broker-integration-with-couchbase-solace-java\/"},"author":{"name":"Marian Puhl, Solutions Engineer","@id":"https:\/\/www.couchbase.com\/blog\/#\/schema\/person\/b2fc479528e2819b50082a425cf381e3"},"headline":"Event Broker Integration with Couchbase, Solace &#038; Java","datePublished":"2022-04-12T17:11:38+00:00","dateModified":"2024-05-08T14:18:22+00:00","mainEntityOfPage":{"@id":"https:\/\/www.couchbase.com\/blog\/event-broker-integration-with-couchbase-solace-java\/"},"wordCount":1247,"commentCount":0,"publisher":{"@id":"https:\/\/www.couchbase.com\/blog\/#organization"},"image":{"@id":"https:\/\/www.couchbase.com\/blog\/event-broker-integration-with-couchbase-solace-java\/#primaryimage"},"thumbnailUrl":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2022\/04\/mobile-code-edit-vscode-couchbase-lite-scaled.jpg","keywords":["Architecture","event-driven","pubsub","solace"],"articleSection":["Application Design","Couchbase Capella","Java","Tools &amp; SDKs"],"inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/www.couchbase.com\/blog\/event-broker-integration-with-couchbase-solace-java\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/www.couchbase.com\/blog\/event-broker-integration-with-couchbase-solace-java\/","url":"https:\/\/www.couchbase.com\/blog\/event-broker-integration-with-couchbase-solace-java\/","name":"Event Broker Integration with Couchbase, Solace & Java","isPartOf":{"@id":"https:\/\/www.couchbase.com\/blog\/#website"},"primaryImageOfPage":{"@id":"https:\/\/www.couchbase.com\/blog\/event-broker-integration-with-couchbase-solace-java\/#primaryimage"},"image":{"@id":"https:\/\/www.couchbase.com\/blog\/event-broker-integration-with-couchbase-solace-java\/#primaryimage"},"thumbnailUrl":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2022\/04\/mobile-code-edit-vscode-couchbase-lite-scaled.jpg","datePublished":"2022-04-12T17:11:38+00:00","dateModified":"2024-05-08T14:18:22+00:00","description":"Following up from an earlier post, learn to pull events from Solace PubSub topics to update a Couchbase datastore using a Java-based microservice.","breadcrumb":{"@id":"https:\/\/www.couchbase.com\/blog\/event-broker-integration-with-couchbase-solace-java\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.couchbase.com\/blog\/event-broker-integration-with-couchbase-solace-java\/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.couchbase.com\/blog\/event-broker-integration-with-couchbase-solace-java\/#primaryimage","url":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2022\/04\/mobile-code-edit-vscode-couchbase-lite-scaled.jpg","contentUrl":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2022\/04\/mobile-code-edit-vscode-couchbase-lite-scaled.jpg","width":2560,"height":1704,"caption":"Consume events from Solace into Couchbase"},{"@type":"BreadcrumbList","@id":"https:\/\/www.couchbase.com\/blog\/event-broker-integration-with-couchbase-solace-java\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/www.couchbase.com\/blog\/"},{"@type":"ListItem","position":2,"name":"Event Broker Integration with Couchbase, Solace &#038; Java"}]},{"@type":"WebSite","@id":"https:\/\/www.couchbase.com\/blog\/#website","url":"https:\/\/www.couchbase.com\/blog\/","name":"The Couchbase Blog","description":"Couchbase, the NoSQL Database","publisher":{"@id":"https:\/\/www.couchbase.com\/blog\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/www.couchbase.com\/blog\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Organization","@id":"https:\/\/www.couchbase.com\/blog\/#organization","name":"The Couchbase Blog","url":"https:\/\/www.couchbase.com\/blog\/","logo":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.couchbase.com\/blog\/#\/schema\/logo\/image\/","url":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/2023\/04\/admin-logo.png","contentUrl":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/2023\/04\/admin-logo.png","width":218,"height":34,"caption":"The Couchbase Blog"},"image":{"@id":"https:\/\/www.couchbase.com\/blog\/#\/schema\/logo\/image\/"}},{"@type":"Person","@id":"https:\/\/www.couchbase.com\/blog\/#\/schema\/person\/b2fc479528e2819b50082a425cf381e3","name":"Marian Puhl, Solutions Engineer","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.couchbase.com\/blog\/#\/schema\/person\/image\/1f65549252c18bb3651eaa3a78e46169","url":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2021\/07\/marian-puhl-couchbase-engineering.jpeg","contentUrl":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2021\/07\/marian-puhl-couchbase-engineering.jpeg","caption":"Marian Puhl, Solutions Engineer"},"description":"Marian Puhl is a Solutions Engineer at Couchbase in the Nordic region.","url":"https:\/\/www.couchbase.com\/blog\/author\/marian-puhl\/"}]}},"authors":[{"term_id":9323,"user_id":77950,"is_guest":0,"slug":"marian-puhl","display_name":"Marian Puhl, Solutions Engineer","avatar_url":{"url":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2021\/07\/marian-puhl-couchbase-engineering.jpeg","url2x":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2021\/07\/marian-puhl-couchbase-engineering.jpeg"},"author_category":"","last_name":"Puhl","first_name":"Marian","job_title":"","user_url":"","description":"Marian Puhl is a Solutions Engineer at Couchbase in the Nordic region. "}],"_links":{"self":[{"href":"https:\/\/www.couchbase.com\/blog\/wp-json\/wp\/v2\/posts\/13061","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.couchbase.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.couchbase.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/wp-json\/wp\/v2\/users\/77950"}],"replies":[{"embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/wp-json\/wp\/v2\/comments?post=13061"}],"version-history":[{"count":0,"href":"https:\/\/www.couchbase.com\/blog\/wp-json\/wp\/v2\/posts\/13061\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/wp-json\/wp\/v2\/media\/13023"}],"wp:attachment":[{"href":"https:\/\/www.couchbase.com\/blog\/wp-json\/wp\/v2\/media?parent=13061"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/wp-json\/wp\/v2\/categories?post=13061"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/wp-json\/wp\/v2\/tags?post=13061"},{"taxonomy":"author","embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/wp-json\/wp\/v2\/ppma_author?post=13061"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}