{"id":12594,"date":"2021-12-15T14:44:31","date_gmt":"2021-12-15T22:44:31","guid":{"rendered":"https:\/\/www.couchbase.com\/blog\/?p=12594"},"modified":"2025-06-13T22:40:21","modified_gmt":"2025-06-14T05:40:21","slug":"data-validation-with-the-eventing-service","status":"publish","type":"post","link":"https:\/\/www.couchbase.com\/blog\/data-validation-with-the-eventing-service\/","title":{"rendered":"Data Validation with the Eventing Service"},"content":{"rendered":"<p><span style=\"font-weight: 400;\">Data Validation is an interesting topic to cover for a NoSQL technology, purely down to the fact that the core principles of the system revolve around a &#8220;schema-less&#8221; architecture. For many years, SQL and schemas have controlled application data, ensuring the conformity of information inside the database. These restrictions prevented the modernization of most applications by slowing down development time.<\/span><\/p>\n<p><span style=\"font-weight: 400;\">Regardless, you still need to govern and validate the information underneath your applications. With that in mind, how do we achieve this with Couchbase?<\/span><\/p>\n<p><span style=\"font-weight: 400;\">The flexibility of a schema-less architecture makes it harder to enforce the structure of information coming from multiple sources, such as sensor and edge device interaction, where the number of communication points is vast. There are ways to achieve <\/span><b>data validation within the database itself<\/b><span style=\"font-weight: 400;\">, using the Couchbase Eventing service. The service, on its own, is extremely powerful and flexible, giving the administrator control over the specifics of the validation on the documents and resulting actions to take.<\/span><\/p>\n<p><span style=\"font-weight: 400;\">The blog post will walk you an example of using the eventing service to validate the information living in your cluster. As you will see, there are many different ways to build this, but let&#8217;s just focus on one to begin with.<\/span><\/p>\n<h4><span style=\"font-weight: 400;\">NoSQL Fundamentals<\/span><\/h4>\n<p><span style=\"font-weight: 400;\">At the center of any database is the data \u2013 the actual information that we wish to store. Before adopting NoSQL, we would insert the data into our system, but it had to adhere to the structure developers or DBAs defined. DBAs would spend time <\/span><a href=\"https:\/\/en.wikipedia.org\/wiki\/Database_normalization\"><span style=\"font-weight: 400;\">normalizing<\/span><\/a><span style=\"font-weight: 400;\"> the information up to the 6th normal form to reduce data redundancy<\/span><span style=\"font-weight: 400;\">. <\/span><span style=\"font-weight: 400;\">This whole structure was commonly known as a schema and was great for validating the integrity of information, ensuring the system of record quality, and becoming a source of truth.<\/span><\/p>\n<p><span style=\"font-weight: 400;\">Despite the benefits, the schema-based architecture presented some disadvantages, mainly introduced when applications started operating on a higher level and companies started innovating faster. The structured approach to storing data began to slow down development, and schema changes became a nuisance.<\/span><\/p>\n<p><span style=\"font-weight: 400;\">This is where the schema-lass approach started to take precedence\u2014allowing users to store any information they wished to and allowing the acceleration of innovative development to flourish.<\/span><\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone wp-image-12595 size-full\" src=\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/2021\/12\/eventing.jpeg\" alt=\"\" width=\"512\" height=\"227\" srcset=\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2021\/12\/eventing.jpeg 512w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2021\/12\/eventing-300x133.jpeg 300w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2021\/12\/eventing-20x9.jpeg 20w\" sizes=\"auto, (max-width: 512px) 100vw, 512px\" \/><\/p>\n<h4><span style=\"font-weight: 400;\">SQL but NoSQL<\/span><\/h4>\n<p><span style=\"font-weight: 400;\">Despite the move to a more flexible and agile database, some attributes of the old model are desired with the new approach; Data Validation is one of those topics. Couchbase has made considerable changes in the recent releases to bridge the gap between SQL and NoSQL technologies.\u00a0<\/span><\/p>\n<p><b>Scopes and Collections were <\/b><span style=\"font-weight: 400;\">released in Couchbase Server 7.0 and opened the door to greater logical organization and multi-tenancy use cases. It allowed us to map data from schema to schema-less while still holding the flexible development practices at the core.\u00a0<\/span><\/p>\n<p><b>Providing ACID guarantees <\/b><span style=\"font-weight: 400;\">from a distributed system was another big step, ensuring all-or-nothing semantics across unrelated data for transactional workloads back in v6.5.1.<\/span><\/p>\n<p><b>Data Validation <\/b><span style=\"font-weight: 400;\">is another topic that comes through alongside these. How do I evaluate the information in my database when there is no schema to enforce it? Like the previous features that complemented the schema approach, the ability to choose whether you have this or not is beneficial. Although, it isn&#8217;t necessary to incorporate this into the fundamentals of the application itself.<\/span><\/p>\n<p><span style=\"font-weight: 400;\">With the proliferation of the 5G network and Mobile\/Edge devices, the chances are, the requirement of data governance and management may still be there. Utilizing tools in the Couchbase arsenal can provide you with an easy and fully controlled method of applying this validation without affecting the performance of either the application or database nodes.\u00a0<\/span><\/p>\n<h4><span style=\"font-weight: 400;\">Edge Computing with Multiple Application Sources<\/span><\/h4>\n<p><span style=\"font-weight: 400;\">Before we dive into the fun ways of validating on the server, let&#8217;s discuss the other option available. Validation at the application level will probably be the first thought that comes to mind. If we want to ensure that information is suitable for storing, why don&#8217;t we check it before inserting the documents into the database? Applying application logic on the data before ingestion by the system would guarantee that no document would get anywhere near the database unless the system had already validated it.<\/span><\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone wp-image-12596 size-full\" src=\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/2021\/12\/eventing2.jpeg\" alt=\"\" width=\"512\" height=\"150\" srcset=\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2021\/12\/eventing2.jpeg 512w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2021\/12\/eventing2-300x88.jpeg 300w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2021\/12\/eventing2-20x6.jpeg 20w\" sizes=\"auto, (max-width: 512px) 100vw, 512px\" \/><\/p>\n<p><span style=\"font-weight: 400;\">Theoretically, this sounds like a good idea\u2026. for a single application talking to a single dataset. However, when you start to look at the mobile application space, where we could be talking to several edge devices, all talking to multiple datasets, in a single database, the maintainability will suffer. All teams writing to the database would need to maintain and share the validation logic consistently, and you start to lose the guarantees which were there for the single app scenario.<\/span><\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone wp-image-12597 size-full\" src=\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/2021\/12\/eventing-3.jpeg\" alt=\"\" width=\"512\" height=\"420\" srcset=\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2021\/12\/eventing-3.jpeg 512w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2021\/12\/eventing-3-300x246.jpeg 300w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2021\/12\/eventing-3-20x16.jpeg 20w\" sizes=\"auto, (max-width: 512px) 100vw, 512px\" \/><\/p>\n<h4><span style=\"font-weight: 400;\">Eventing Service<\/span><\/h4>\n<p><span style=\"font-weight: 400;\">Considering the application validation problems, we need a way to achieve the same result but at a different point; this is where the eventing service comes in. For those that don&#8217;t know about it, the eventing service allows you to act on data mutations in the database programmatically. These actions are defined within JavaScript event handlers and are triggered on any updates or deletes to the data.<\/span><\/p>\n<table>\n<tbody>\n<tr>\n<td><em><span style=\"font-weight: 400;\">function<\/span> <span style=\"font-weight: 400;\">OnUpdate<\/span><span style=\"font-weight: 400;\">(doc, meta) {<\/span><span style=\"font-weight: 400;\"><br \/>\n<\/span><span style=\"font-weight: 400;\">\u00a0 \u00a0 log(<\/span><span style=\"font-weight: 400;\">&#8216;docId&#8217;<\/span><span style=\"font-weight: 400;\">, meta.id);<\/span><span style=\"font-weight: 400;\"><br \/>\n<\/span><span style=\"font-weight: 400;\">}<\/span><span style=\"font-weight: 400;\"><br \/>\n<\/span><span style=\"font-weight: 400;\"><br \/>\n<\/span><span style=\"font-weight: 400;\">function<\/span> <span style=\"font-weight: 400;\">OnDelete<\/span><span style=\"font-weight: 400;\">(meta, options) {<\/span><span style=\"font-weight: 400;\"><br \/>\n<\/span><span style=\"font-weight: 400;\">\u00a0 <\/span><span style=\"font-weight: 400;\"><br \/>\n<\/span><span style=\"font-weight: 400;\">}<\/span><\/em><\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p><span style=\"font-weight: 400;\">Since the eventing service can run this logic after the data has come into the database, nothing stops us from incorporating the application logic into these functions. We will pass the responsibility over to the eventing service to check the information whenever it is inserted or modified.<\/span><\/p>\n<p><span style=\"font-weight: 400;\">This does two things:<\/span><\/p>\n<ul>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><span style=\"font-weight: 400;\">Removes the duplication of validation logic across multiple applications<\/span><\/li>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><span style=\"font-weight: 400;\">Centralizing configuration and maintainability of what is considered &#8216;valid&#8217; data<\/span><\/li>\n<\/ul>\n<p><span style=\"font-weight: 400;\">Now we can use the eventing service to check document fields and values within a bucket, regardless of where the data came from. But there is still one consideration, what do we do with documents if we decide they are <\/span><i><span style=\"font-weight: 400;\">invalid<\/span><\/i><span style=\"font-weight: 400;\">? At the application level, an invalid document would not pass the checks and would throw an error or exception telling you, which you could then handle in whichever way was necessary.<\/span><\/p>\n<p><span style=\"font-weight: 400;\">Because the information is already in the bucket, we need to flag the document&#8217;s validity without tarnishing the integrity of the data. It&#8217;s up to you how you decide to handle this part, but in my example, we can keep a record of the invalid documents in a separate collection, and we can remove the record when it has been cleaned into a valid state.<\/span><\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone wp-image-12598 size-full\" src=\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/2021\/12\/eventing-4.jpeg\" alt=\"\" width=\"512\" height=\"447\" srcset=\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2021\/12\/eventing-4.jpeg 512w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2021\/12\/eventing-4-300x262.jpeg 300w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2021\/12\/eventing-4-20x17.jpeg 20w\" sizes=\"auto, (max-width: 512px) 100vw, 512px\" \/><\/p>\n<h4><span style=\"font-weight: 400;\">Implementation<\/span><\/h4>\n<p><span style=\"font-weight: 400;\">First, we need to build an eventing function on the target dataset. For this example, I have chosen the <\/span><i><span style=\"font-weight: 400;\">Users <\/span><\/i><span style=\"font-weight: 400;\">collection. We will also need to specify a location for the eventing metadata to be stored (see the <\/span><a href=\"https:\/\/docs.couchbase.com\/server\/current\/eventing\/eventing-Terminologies.html\"><span style=\"font-weight: 400;\">eventing documentation here<\/span><\/a><span style=\"font-weight: 400;\">).<\/span><\/p>\n<p><span style=\"font-weight: 400;\">Finally, I will need to define an alias for the location of the invalid data, which I can reference; for this, we have the <\/span><i><span style=\"font-weight: 400;\">Users_Invalid <\/span><\/i><span style=\"font-weight: 400;\">collection.<\/span><\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone wp-image-12599 size-full\" src=\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/2021\/12\/eventing5.png\" alt=\"\" width=\"451\" height=\"348\" srcset=\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2021\/12\/eventing5.png 451w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2021\/12\/eventing5-300x231.png 300w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2021\/12\/eventing5-20x15.png 20w\" sizes=\"auto, (max-width: 451px) 100vw, 451px\" \/><\/p>\n<p><span style=\"font-weight: 400;\">Once the structure has been created, we need to create something that represents a <\/span><i><span style=\"font-weight: 400;\">valid<\/span><\/i><span style=\"font-weight: 400;\"> document. This way, we can check all the new documents against this one to guarantee the information is correct. In this instance, I will create a document that lists all of the required fields and types they should contain. If you wanted to, you could correlate this to the schema we discussed before, hence I will call this the <\/span><i><span style=\"font-weight: 400;\">Users_Schema<\/span><\/i><span style=\"font-weight: 400;\">.<\/span><\/p>\n<table>\n<tbody>\n<tr>\n<td><em><span style=\"font-weight: 400;\">{<\/span><span style=\"font-weight: 400;\"><br \/>\n<\/span><span style=\"font-weight: 400;\">\u00a0 &#8220;fields&#8221;: [<\/span><span style=\"font-weight: 400;\"><br \/>\n<\/span> <span style=\"font-weight: 400;\">{<\/span><span style=\"font-weight: 400;\"><br \/>\n<\/span><span style=\"font-weight: 400;\">\u00a0 <\/span> <span style=\"font-weight: 400;\">&#8220;name&#8221;: <\/span><span style=\"font-weight: 400;\">&#8220;Name&#8221;<\/span><span style=\"font-weight: 400;\">,<\/span><span style=\"font-weight: 400;\"><br \/>\n<\/span><span style=\"font-weight: 400;\">\u00a0 <\/span> <span style=\"font-weight: 400;\">&#8220;type&#8221;: <\/span><span style=\"font-weight: 400;\">&#8220;string&#8221;<\/span><span style=\"font-weight: 400;\"><br \/>\n<\/span> <span style=\"font-weight: 400;\">},<\/span><span style=\"font-weight: 400;\"><br \/>\n<\/span> <span style=\"font-weight: 400;\">{<\/span><span style=\"font-weight: 400;\"><br \/>\n<\/span><span style=\"font-weight: 400;\">\u00a0 <\/span> <span style=\"font-weight: 400;\">&#8220;name&#8221;: <\/span><span style=\"font-weight: 400;\">&#8220;Age&#8221;<\/span><span style=\"font-weight: 400;\">,<\/span><span style=\"font-weight: 400;\"><br \/>\n<\/span><span style=\"font-weight: 400;\">\u00a0 <\/span> <span style=\"font-weight: 400;\">&#8220;type&#8221;: <\/span><span style=\"font-weight: 400;\">&#8220;number&#8221;<\/span><span style=\"font-weight: 400;\"><br \/>\n<\/span> <span style=\"font-weight: 400;\">},<\/span><span style=\"font-weight: 400;\"><br \/>\n<\/span> <span style=\"font-weight: 400;\">{<\/span><span style=\"font-weight: 400;\"><br \/>\n<\/span><span style=\"font-weight: 400;\">\u00a0 <\/span> <span style=\"font-weight: 400;\">&#8220;name&#8221;: <\/span><span style=\"font-weight: 400;\">&#8220;Subscriber&#8221;<\/span><span style=\"font-weight: 400;\">,<\/span><span style=\"font-weight: 400;\"><br \/>\n<\/span><span style=\"font-weight: 400;\">\u00a0 <\/span> <span style=\"font-weight: 400;\">&#8220;type&#8221;: <\/span><span style=\"font-weight: 400;\">&#8220;boolean&#8221;<\/span><span style=\"font-weight: 400;\"><br \/>\n<\/span> <span style=\"font-weight: 400;\">}<\/span><span style=\"font-weight: 400;\"><br \/>\n<\/span><span style=\"font-weight: 400;\">\u00a0 ]<\/span><span style=\"font-weight: 400;\"><br \/>\n<\/span><span style=\"font-weight: 400;\">}<\/span><\/em><\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p><span style=\"font-weight: 400;\">The next thing to create is the validation logic. Eventing will execute the logic every time there is a document mutation in the source collection, <\/span><i><span style=\"font-weight: 400;\">Users<\/span><\/i><span style=\"font-weight: 400;\">. It will check to see whether the document has a related schema document associated. If so, check all the field and value types and compare them to the document being referenced. If any of the fields don&#8217;t exist, or any of the types don&#8217;t match what is expected, then we create a record in the <\/span><i><span style=\"font-weight: 400;\">Invalid_Users <\/span><\/i><span style=\"font-weight: 400;\">collection.\u00a0<\/span><\/p>\n<p><span style=\"font-weight: 400;\">There is a condition at the bottom of the script that attempts to delete the record if the logic returns a valid result. It is removed from the invalid records when the document has been cleaned or fixed into a valid state.<\/span><\/p>\n<table>\n<tbody>\n<tr>\n<td><em><span style=\"font-weight: 400;\">function<\/span> <span style=\"font-weight: 400;\">OnUpdate<\/span><span style=\"font-weight: 400;\">(doc, meta) {<\/span><span style=\"font-weight: 400;\"><br \/>\n<\/span> <span style=\"font-weight: 400;\">log(<\/span><span style=\"font-weight: 400;\">&#8216;docId&#8217;<\/span><span style=\"font-weight: 400;\">, meta.id);<\/span><span style=\"font-weight: 400;\"><br \/>\n<\/span> <span style=\"font-weight: 400;\"><br \/>\n<\/span> <span style=\"font-weight: 400;\">var<\/span><span style=\"font-weight: 400;\"> schema, valid, reason<\/span><span style=\"font-weight: 400;\"><br \/>\n<\/span> <span style=\"font-weight: 400;\"><br \/>\n<\/span> <span style=\"font-weight: 400;\">\/\/Grab the schema document<\/span><span style=\"font-weight: 400;\"><br \/>\n<\/span> <span style=\"font-weight: 400;\">schema = inv[doc.type + <\/span><span style=\"font-weight: 400;\">&#8216;_schema&#8217;<\/span><span style=\"font-weight: 400;\">]<\/span><span style=\"font-weight: 400;\"><br \/>\n<\/span> <span style=\"font-weight: 400;\">reason = <\/span><span style=\"font-weight: 400;\">&#8221;<\/span><span style=\"font-weight: 400;\"><br \/>\n<\/span> <span style=\"font-weight: 400;\">valid = <\/span><span style=\"font-weight: 400;\">true<\/span><span style=\"font-weight: 400;\"><br \/>\n<\/span> <span style=\"font-weight: 400;\"><br \/>\n<\/span> <span style=\"font-weight: 400;\">\/\/Iterate through fields<\/span><span style=\"font-weight: 400;\"><br \/>\n<\/span> <span style=\"font-weight: 400;\">for<\/span><span style=\"font-weight: 400;\">(<\/span><span style=\"font-weight: 400;\">const<\/span><span style=\"font-weight: 400;\"> field <\/span><span style=\"font-weight: 400;\">of<\/span><span style=\"font-weight: 400;\"> schema.fields) {<\/span><span style=\"font-weight: 400;\"><br \/>\n<\/span><span style=\"font-weight: 400;\">\u00a0 \u00a0 <\/span> <span style=\"font-weight: 400;\">\u00a0 \u00a0 <\/span><span style=\"font-weight: 400;\">\/\/Check if field exists<\/span><span style=\"font-weight: 400;\"><br \/>\n<\/span><span style=\"font-weight: 400;\">\u00a0 \u00a0 <\/span> <span style=\"font-weight: 400;\">\u00a0 \u00a0 <\/span><span style=\"font-weight: 400;\">if<\/span><span style=\"font-weight: 400;\"> (field.name <\/span><span style=\"font-weight: 400;\">in<\/span><span style=\"font-weight: 400;\"> doc) {<\/span><\/em><em><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span><span style=\"font-weight: 400;\">\/\/Check if field type is correct<\/span><span style=\"font-weight: 400;\"><br \/>\n<\/span><span style=\"font-weight: 400;\">\u00a0 \u00a0 \u00a0 \u00a0 <\/span> <span style=\"font-weight: 400;\">\u00a0 \u00a0 \u00a0 \u00a0 <\/span><span style=\"font-weight: 400;\">if<\/span><span style=\"font-weight: 400;\"> (<\/span><span style=\"font-weight: 400;\">typeof<\/span><span style=\"font-weight: 400;\"> doc[field.name] == field.type) {<\/span><span style=\"font-weight: 400;\"><br \/>\n<\/span><span style=\"font-weight: 400;\">\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 valid = <\/span><span style=\"font-weight: 400;\">true<\/span><span style=\"font-weight: 400;\"><br \/>\n<\/span><span style=\"font-weight: 400;\">\u00a0 \u00a0 \u00a0 \u00a0 <\/span> <span style=\"font-weight: 400;\">\u00a0 \u00a0 \u00a0 \u00a0 }<\/span><span style=\"font-weight: 400;\"><br \/>\n<\/span><span style=\"font-weight: 400;\">\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 <\/span><span style=\"font-weight: 400;\">else<\/span><span style=\"font-weight: 400;\"> {<\/span><span style=\"font-weight: 400;\"><br \/>\n<\/span><span style=\"font-weight: 400;\">\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 reason = <\/span><span style=\"font-weight: 400;\">&#8216;Incorrect Type for Field: &#8216;<\/span><span style=\"font-weight: 400;\"> + field.name + <\/span><span style=\"font-weight: 400;\">&#8216;. Expected: &#8216;<\/span><span style=\"font-weight: 400;\"> + field.type + <\/span><span style=\"font-weight: 400;\">&#8216;. Actual: &#8216;<\/span><span style=\"font-weight: 400;\"> + <\/span><span style=\"font-weight: 400;\">typeof<\/span><span style=\"font-weight: 400;\"> doc[field.name]<\/span><span style=\"font-weight: 400;\"><br \/>\n<\/span><span style=\"font-weight: 400;\">\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 valid = <\/span><span style=\"font-weight: 400;\">false<\/span><span style=\"font-weight: 400;\"><br \/>\n<\/span><span style=\"font-weight: 400;\">\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 <\/span><span style=\"font-weight: 400;\">break<\/span><span style=\"font-weight: 400;\"><br \/>\n<\/span><span style=\"font-weight: 400;\">\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 }<\/span><span style=\"font-weight: 400;\"><br \/>\n<\/span><span style=\"font-weight: 400;\">\u00a0 \u00a0 <\/span> <span style=\"font-weight: 400;\">\u00a0 \u00a0 }<\/span><span style=\"font-weight: 400;\"><br \/>\n<\/span><span style=\"font-weight: 400;\">\u00a0 \u00a0 <\/span> <span style=\"font-weight: 400;\">\u00a0 \u00a0 <\/span><span style=\"font-weight: 400;\">else<\/span><span style=\"font-weight: 400;\"> {<\/span><span style=\"font-weight: 400;\"><br \/>\n<\/span><span style=\"font-weight: 400;\">\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 reason = <\/span><span style=\"font-weight: 400;\">&#8216;Field: &#8216;<\/span><span style=\"font-weight: 400;\"> + field.name + <\/span><span style=\"font-weight: 400;\">&#8216; does not exist&#8217;<\/span><span style=\"font-weight: 400;\"><br \/>\n<\/span><span style=\"font-weight: 400;\">\u00a0 \u00a0 \u00a0 \u00a0 <\/span> <span style=\"font-weight: 400;\">\u00a0 \u00a0 \u00a0 \u00a0 valid = <\/span><span style=\"font-weight: 400;\">false<\/span><span style=\"font-weight: 400;\"><br \/>\n<\/span><span style=\"font-weight: 400;\">\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 <\/span><span style=\"font-weight: 400;\">break<\/span><span style=\"font-weight: 400;\"><br \/>\n<\/span><span style=\"font-weight: 400;\">\u00a0 \u00a0 <\/span> <span style=\"font-weight: 400;\">\u00a0 \u00a0 }<\/span><span style=\"font-weight: 400;\"><br \/>\n<\/span> <span style=\"font-weight: 400;\">}<\/span><span style=\"font-weight: 400;\"><br \/>\n<\/span> <span style=\"font-weight: 400;\"><br \/>\n<\/span> <span style=\"font-weight: 400;\">if<\/span><span style=\"font-weight: 400;\"> (valid == <\/span><span style=\"font-weight: 400;\">true<\/span><span style=\"font-weight: 400;\">){<\/span><span style=\"font-weight: 400;\"><br \/>\n<\/span><span style=\"font-weight: 400;\">\u00a0 \u00a0 <\/span> <span style=\"font-weight: 400;\">\u00a0 \u00a0 <\/span><span style=\"font-weight: 400;\">delete<\/span><span style=\"font-weight: 400;\"> inv[meta.id]<\/span><span style=\"font-weight: 400;\"><br \/>\n<\/span> <span style=\"font-weight: 400;\">}<\/span><span style=\"font-weight: 400;\"><br \/>\n<\/span> <span style=\"font-weight: 400;\">else<\/span><span style=\"font-weight: 400;\"> {<\/span><span style=\"font-weight: 400;\"><br \/>\n<\/span><span style=\"font-weight: 400;\">\u00a0 \u00a0 <\/span> <span style=\"font-weight: 400;\">\u00a0 \u00a0 <\/span><span style=\"font-weight: 400;\">var<\/span><span style=\"font-weight: 400;\"> docContent = {<\/span><span style=\"font-weight: 400;\"><br \/>\n<\/span><span style=\"font-weight: 400;\">\u00a0 \u00a0 \u00a0 \u00a0 <\/span> <span style=\"font-weight: 400;\">\u00a0 \u00a0 \u00a0 \u00a0 <\/span><span style=\"font-weight: 400;\">&#8220;id&#8221;<\/span><span style=\"font-weight: 400;\">: meta.id,<\/span><span style=\"font-weight: 400;\"><br \/>\n<\/span><span style=\"font-weight: 400;\">\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 <\/span><span style=\"font-weight: 400;\">&#8220;reason&#8221;<\/span><span style=\"font-weight: 400;\">: reason<\/span><span style=\"font-weight: 400;\"><br \/>\n<\/span><span style=\"font-weight: 400;\">\u00a0 \u00a0 <\/span> <span style=\"font-weight: 400;\">\u00a0 \u00a0 }<\/span><span style=\"font-weight: 400;\"><br \/>\n<\/span><span style=\"font-weight: 400;\">\u00a0 \u00a0 <\/span> <span style=\"font-weight: 400;\">\u00a0 \u00a0 inv[meta.id] = docContent<\/span><span style=\"font-weight: 400;\"><br \/>\n<\/span> <span style=\"font-weight: 400;\">}<\/span><span style=\"font-weight: 400;\"><br \/>\n<\/span><span style=\"font-weight: 400;\">}<\/span><\/em><\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p><span style=\"font-weight: 400;\">All there is to do now is test it out, insert a <\/span><i><span style=\"font-weight: 400;\">User <\/span><\/i><span style=\"font-weight: 400;\">document with invalid fields\/types and check that a record is created in the <\/span><i><span style=\"font-weight: 400;\">Invalid_Users<\/span><\/i><span style=\"font-weight: 400;\"> collection&#8217;. Attempt to fix the invalid documents and check that the record is removed. Overall, this allows you to achieve asynchronous data validation after the point of save, in 3 easy steps.<\/span><\/p>\n<h4><span style=\"font-weight: 400;\">Taking it further\u2026<\/span><\/h4>\n<p><span style=\"font-weight: 400;\">Now as you can probably tell, this is a very simple example, and I have no doubt that I could have written JavaScript more efficiently. However, I was still able to validate all the information within a bucket against what we could call a schema, while maintaining the integrity of the information and ensuring there was no data lost in the process.<\/span><\/p>\n<p><span style=\"font-weight: 400;\">This approach was the one that I wanted to follow, but could be modified and extended in several different ways\u2026<\/span><\/p>\n<ul>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><span style=\"font-weight: 400;\">Validating actual values of the fields (e.g. Age must be in range 1-100 etc\u2026)<\/span><\/li>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><span style=\"font-weight: 400;\">Removing the documents entirely from the collection<\/span><\/li>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><span style=\"font-weight: 400;\">Moving the entire document out of the collection<\/span><\/li>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><span style=\"font-weight: 400;\">Sending notifications via cURL to an external service (Email response perhaps?)<\/span><\/li>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><span style=\"font-weight: 400;\">Writing extra logic to autonomously fix the invalid data with enrichment<\/span><\/li>\n<\/ul>\n<p><span style=\"font-weight: 400;\">This blog post has demonstrated a couple of things:<\/span><\/p>\n<ol>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><span style=\"font-weight: 400;\">Asynchronous data validation after the point of save<\/span><\/li>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><span style=\"font-weight: 400;\">The power of the eventing service as a whole<\/span><\/li>\n<\/ol>\n<p><span style=\"font-weight: 400;\">Returning to the original points, bridging the gap between SQL and NoSQL technologies is becoming more and more common, not as architectural changes, but as tools to achieve what was once a fundamental implementation.<\/span><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Data Validation is an interesting topic to cover for a NoSQL technology, purely down to the fact that the core principles of the system revolve around a &#8220;schema-less&#8221; architecture. For many years, SQL and schemas have controlled application data, ensuring [&hellip;]<\/p>\n","protected":false},"author":74466,"featured_media":12603,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"inline_featured_image":false,"footnotes":""},"categories":[1816,2273,1812],"tags":[1572,1725],"ppma_author":[9167],"class_list":["post-12594","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-couchbase-server","category-eventing","category-n1ql-query","tag-database","tag-nosql-database"],"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>Data Validation with the Eventing Service - The Couchbase Blog<\/title>\n<meta name=\"description\" content=\"The blog post shows you how to use the Couchbase Eventing Service to perform data validation within the NoSQL database.\" \/>\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\/data-validation-with-the-eventing-service\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Data Validation with the Eventing Service\" \/>\n<meta property=\"og:description\" content=\"The blog post shows you how to use the Couchbase Eventing Service to perform data validation within the NoSQL database.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.couchbase.com\/blog\/data-validation-with-the-eventing-service\/\" \/>\n<meta property=\"og:site_name\" content=\"The Couchbase Blog\" \/>\n<meta property=\"article:published_time\" content=\"2021-12-15T22:44:31+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2025-06-14T05:40:21+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2021\/12\/hannah-wei-aso6SYJZGps-unsplash-scaled.jpg\" \/>\n\t<meta property=\"og:image:width\" content=\"2560\" \/>\n\t<meta property=\"og:image:height\" content=\"1707\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/jpeg\" \/>\n<meta name=\"author\" content=\"Daniel Bull, Associate 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=\"Daniel Bull, Associate Solutions Engineer\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"9 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/data-validation-with-the-eventing-service\/#article\",\"isPartOf\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/data-validation-with-the-eventing-service\/\"},\"author\":{\"name\":\"Daniel Bull, Associate Solutions Engineer\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/#\/schema\/person\/7f9d5e0c7963a172db12fb5e5e2583e1\"},\"headline\":\"Data Validation with the Eventing Service\",\"datePublished\":\"2021-12-15T22:44:31+00:00\",\"dateModified\":\"2025-06-14T05:40:21+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/data-validation-with-the-eventing-service\/\"},\"wordCount\":1714,\"commentCount\":0,\"publisher\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/#organization\"},\"image\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/data-validation-with-the-eventing-service\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2021\/12\/hannah-wei-aso6SYJZGps-unsplash-scaled.jpg\",\"keywords\":[\"database\",\"NoSQL Database\"],\"articleSection\":[\"Couchbase Server\",\"Eventing\",\"SQL++ \/ N1QL Query\"],\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\/\/www.couchbase.com\/blog\/data-validation-with-the-eventing-service\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/data-validation-with-the-eventing-service\/\",\"url\":\"https:\/\/www.couchbase.com\/blog\/data-validation-with-the-eventing-service\/\",\"name\":\"Data Validation with the Eventing Service - The Couchbase Blog\",\"isPartOf\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/data-validation-with-the-eventing-service\/#primaryimage\"},\"image\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/data-validation-with-the-eventing-service\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2021\/12\/hannah-wei-aso6SYJZGps-unsplash-scaled.jpg\",\"datePublished\":\"2021-12-15T22:44:31+00:00\",\"dateModified\":\"2025-06-14T05:40:21+00:00\",\"description\":\"The blog post shows you how to use the Couchbase Eventing Service to perform data validation within the NoSQL database.\",\"breadcrumb\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/data-validation-with-the-eventing-service\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/www.couchbase.com\/blog\/data-validation-with-the-eventing-service\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/data-validation-with-the-eventing-service\/#primaryimage\",\"url\":\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2021\/12\/hannah-wei-aso6SYJZGps-unsplash-scaled.jpg\",\"contentUrl\":\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2021\/12\/hannah-wei-aso6SYJZGps-unsplash-scaled.jpg\",\"width\":2560,\"height\":1707,\"caption\":\"Couchbase ASP.NET Core tutorial\"},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/data-validation-with-the-eventing-service\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/www.couchbase.com\/blog\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Data Validation with the Eventing Service\"}]},{\"@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\/7f9d5e0c7963a172db12fb5e5e2583e1\",\"name\":\"Daniel Bull, Associate Solutions Engineer\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/#\/schema\/person\/image\/1a793e281f03204d89cd07cc2163a58e\",\"url\":\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2021\/07\/daniel-bull-couchbase-engineering.jpeg\",\"contentUrl\":\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2021\/07\/daniel-bull-couchbase-engineering.jpeg\",\"caption\":\"Daniel Bull, Associate Solutions Engineer\"},\"description\":\"Daniel Bull is an Associate Solutions Engineer at Couchbase\",\"sameAs\":[\"https:\/\/www.linkedin.com\/in\/daniel-bull-00a102b5\/\"],\"url\":\"https:\/\/www.couchbase.com\/blog\/author\/daniel-bull\/\"}]}<\/script>\n<!-- \/ Yoast SEO Premium plugin. -->","yoast_head_json":{"title":"Data Validation with the Eventing Service - The Couchbase Blog","description":"The blog post shows you how to use the Couchbase Eventing Service to perform data validation within the NoSQL database.","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\/data-validation-with-the-eventing-service\/","og_locale":"en_US","og_type":"article","og_title":"Data Validation with the Eventing Service","og_description":"The blog post shows you how to use the Couchbase Eventing Service to perform data validation within the NoSQL database.","og_url":"https:\/\/www.couchbase.com\/blog\/data-validation-with-the-eventing-service\/","og_site_name":"The Couchbase Blog","article_published_time":"2021-12-15T22:44:31+00:00","article_modified_time":"2025-06-14T05:40:21+00:00","og_image":[{"width":2560,"height":1707,"url":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2021\/12\/hannah-wei-aso6SYJZGps-unsplash-scaled.jpg","type":"image\/jpeg"}],"author":"Daniel Bull, Associate Solutions Engineer","twitter_card":"summary_large_image","twitter_misc":{"Written by":"Daniel Bull, Associate Solutions Engineer","Est. reading time":"9 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/www.couchbase.com\/blog\/data-validation-with-the-eventing-service\/#article","isPartOf":{"@id":"https:\/\/www.couchbase.com\/blog\/data-validation-with-the-eventing-service\/"},"author":{"name":"Daniel Bull, Associate Solutions Engineer","@id":"https:\/\/www.couchbase.com\/blog\/#\/schema\/person\/7f9d5e0c7963a172db12fb5e5e2583e1"},"headline":"Data Validation with the Eventing Service","datePublished":"2021-12-15T22:44:31+00:00","dateModified":"2025-06-14T05:40:21+00:00","mainEntityOfPage":{"@id":"https:\/\/www.couchbase.com\/blog\/data-validation-with-the-eventing-service\/"},"wordCount":1714,"commentCount":0,"publisher":{"@id":"https:\/\/www.couchbase.com\/blog\/#organization"},"image":{"@id":"https:\/\/www.couchbase.com\/blog\/data-validation-with-the-eventing-service\/#primaryimage"},"thumbnailUrl":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2021\/12\/hannah-wei-aso6SYJZGps-unsplash-scaled.jpg","keywords":["database","NoSQL Database"],"articleSection":["Couchbase Server","Eventing","SQL++ \/ N1QL Query"],"inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/www.couchbase.com\/blog\/data-validation-with-the-eventing-service\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/www.couchbase.com\/blog\/data-validation-with-the-eventing-service\/","url":"https:\/\/www.couchbase.com\/blog\/data-validation-with-the-eventing-service\/","name":"Data Validation with the Eventing Service - The Couchbase Blog","isPartOf":{"@id":"https:\/\/www.couchbase.com\/blog\/#website"},"primaryImageOfPage":{"@id":"https:\/\/www.couchbase.com\/blog\/data-validation-with-the-eventing-service\/#primaryimage"},"image":{"@id":"https:\/\/www.couchbase.com\/blog\/data-validation-with-the-eventing-service\/#primaryimage"},"thumbnailUrl":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2021\/12\/hannah-wei-aso6SYJZGps-unsplash-scaled.jpg","datePublished":"2021-12-15T22:44:31+00:00","dateModified":"2025-06-14T05:40:21+00:00","description":"The blog post shows you how to use the Couchbase Eventing Service to perform data validation within the NoSQL database.","breadcrumb":{"@id":"https:\/\/www.couchbase.com\/blog\/data-validation-with-the-eventing-service\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.couchbase.com\/blog\/data-validation-with-the-eventing-service\/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.couchbase.com\/blog\/data-validation-with-the-eventing-service\/#primaryimage","url":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2021\/12\/hannah-wei-aso6SYJZGps-unsplash-scaled.jpg","contentUrl":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2021\/12\/hannah-wei-aso6SYJZGps-unsplash-scaled.jpg","width":2560,"height":1707,"caption":"Couchbase ASP.NET Core tutorial"},{"@type":"BreadcrumbList","@id":"https:\/\/www.couchbase.com\/blog\/data-validation-with-the-eventing-service\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/www.couchbase.com\/blog\/"},{"@type":"ListItem","position":2,"name":"Data Validation with the Eventing Service"}]},{"@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\/7f9d5e0c7963a172db12fb5e5e2583e1","name":"Daniel Bull, Associate Solutions Engineer","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.couchbase.com\/blog\/#\/schema\/person\/image\/1a793e281f03204d89cd07cc2163a58e","url":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2021\/07\/daniel-bull-couchbase-engineering.jpeg","contentUrl":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2021\/07\/daniel-bull-couchbase-engineering.jpeg","caption":"Daniel Bull, Associate Solutions Engineer"},"description":"Daniel Bull is an Associate Solutions Engineer at Couchbase","sameAs":["https:\/\/www.linkedin.com\/in\/daniel-bull-00a102b5\/"],"url":"https:\/\/www.couchbase.com\/blog\/author\/daniel-bull\/"}]}},"authors":[{"term_id":9167,"user_id":74466,"is_guest":0,"slug":"daniel-bull","display_name":"Daniel Bull, Associate Solutions Engineer","avatar_url":{"url":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2021\/07\/daniel-bull-couchbase-engineering.jpeg","url2x":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2021\/07\/daniel-bull-couchbase-engineering.jpeg"},"author_category":"","last_name":"Bull","first_name":"Daniel","job_title":"","user_url":"","description":"Daniel Bull is an Associate Solutions Engineer at Couchbase"}],"_links":{"self":[{"href":"https:\/\/www.couchbase.com\/blog\/wp-json\/wp\/v2\/posts\/12594","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\/74466"}],"replies":[{"embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/wp-json\/wp\/v2\/comments?post=12594"}],"version-history":[{"count":0,"href":"https:\/\/www.couchbase.com\/blog\/wp-json\/wp\/v2\/posts\/12594\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/wp-json\/wp\/v2\/media\/12603"}],"wp:attachment":[{"href":"https:\/\/www.couchbase.com\/blog\/wp-json\/wp\/v2\/media?parent=12594"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/wp-json\/wp\/v2\/categories?post=12594"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/wp-json\/wp\/v2\/tags?post=12594"},{"taxonomy":"author","embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/wp-json\/wp\/v2\/ppma_author?post=12594"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}