{"id":2046,"date":"2015-12-16T19:35:31","date_gmt":"2015-12-16T19:35:30","guid":{"rendered":"https:\/\/www.couchbase.com\/blog\/?p=2046"},"modified":"2024-09-12T01:41:38","modified_gmt":"2024-09-12T08:41:38","slug":"couchbase-java-sdk-writing-vertx-verticle","status":"publish","type":"post","link":"https:\/\/www.couchbase.com\/blog\/couchbase-java-sdk-writing-vertx-verticle\/","title":{"rendered":"Using Couchbase Java SDK to write a Vert.x Verticle"},"content":{"rendered":"<p><!-- Using Couchbase Java SDK to write a Vert.x Verticle --><\/p>\n<p>In this post we&#8217;ll go reactive all the way!<\/p>\n<p>Some Couchbase customers use <code>Vert.x<\/code>, a framework for writing fully asynchronous applications, knowing that the <code>Couchbase Java SDK<\/code> fits well into this picture, being asynchronous from the ground up and exposing a <code>RxJava<\/code>-based asynchronous API.<\/p>\n<p>So we&#8217;ll see how to get going fast with a Couchbase <code>Verticle<\/code> that spins up a connection to a Couchbase <code>Cluster<\/code> and <code>Bucket<\/code> then serves JSON documents from the database, using Java 8.<\/p>\n<p>This blog post assumes that you are familiar with the <a href=\"https:\/\/vertx.io\/docs\/vertx-core\/java\/\">basics of Vert.x<\/a>. Here is a short table of content:<\/p>\n<p><!-- TOC depth:6 withLinks:1 updateOnSave:1 orderedList:0 --><\/p>\n<ul>\n<li><a href=\"#starting-a-new-vertx-project\">Starting a new Vert.x project<\/a>\n<ul>\n<li><a href=\"#skeleton-of-the-verticle\">Skeleton of the Verticle<\/a><\/li>\n<\/ul>\n<\/li>\n<li><a href=\"#asynchronously-obtaining-a-bucket\">Asynchronously Obtaining a Bucket<\/a><\/li>\n<li><a href=\"#gracefully-tearing-down-the-sdk\">Gracefully tearing down the SDK<\/a><\/li>\n<li><a href=\"#seeing-it-in-action\">Seeing it in action<\/a><\/li>\n<li><a href=\"#going-further\">Going further<\/a>\n<ul>\n<li><a href=\"#creating-sample-data-in-couchbase-on-startup\">Creating sample data in Couchbase on startup<\/a><\/li>\n<li><a href=\"#serving-json-data-from-couchbase\">Serving JSON data from Couchbase<\/a><\/li>\n<li><a href=\"#stopping-the-verticle-via-a-http-endpoint\">Stopping the Verticle via a HTTP endpoint<\/a><\/li>\n<\/ul>\n<\/li>\n<li><a href=\"#conclusion\">Conclusion<\/a><br \/>\n<!-- \/TOC --><\/li>\n<\/ul>\n<h2 id=\"starting-a-new-vert.x-project\">Starting a new Vert.x project<\/h2>\n<p>Let&#8217;s start by creating a new Maven based project: create a root folder for your project and initialize a maven directory structure (or use your favorite Maven archetype). For instance you can use the following command: &#8220;<code>mkdir -p cbvertx\/src\/main\/java\/com\/couchbase\/demo\/vertx\/<\/code>&#8220;.<\/p>\n<p>Now let&#8217;s initiate the <code>pom.xml<\/code> at the root of the project:<\/p>\n<pre class=\"xml\"><code class=\"language-xml\"><!--?xml version=\"1.0\" encoding=\"UTF-8\"?-->\r\n\r\n  4.0.0\r\n\r\n  com.couchbase.demo\r\n  cbvertx\r\n  1.0-SNAPSHOT\r\n\r\n  \r\n    \r\n      io.vertx\r\n      vertx-core\r\n      3.1.0\r\n    \r\n    \r\n      io.vertx\r\n      vertx-rx-java\r\n      3.1.0\r\n    \r\n    \r\n      com.couchbase.client\r\n      java-client\r\n      2.2.2\r\n    \r\n    \r\n      <!-- this is actually already a transitive dependency of the Java SDK-->\r\n      io.reactivex\r\n      rxjava\r\n      1.0.15\r\n    \r\n    \r\n      log4j\r\n      log4j\r\n      1.2.17\r\n    \r\n  \r\n\r\n  \r\n    \r\n      \r\n        maven-compiler-plugin\r\n        3.3\r\n        \r\n          1.8\r\n          1.8\r\n        \r\n      \r\n    \r\n  \r\n\r\n\r\n<\/code><\/pre>\n<p>As you can see we&#8217;ll be using <code>Vert.x<\/code> version <code>3.1.0<\/code> and its extension for bindings in RxJava, <code>Couchbase Java SDK<\/code> version <code>2.2.2<\/code> and <code>RxJava<\/code> version <code>1.0.15<\/code>&#8230;<\/p>\n<h2 id=\"skeleton-of-the-verticle\">Skeleton of the Verticle<\/h2>\n<p>We&#8217;ll base our <code>CouchbaseVerticle<\/code> on the <code>AbstractVerticle<\/code> in <code>io.vertx.rxjava.core<\/code> (from the vertx-rx-java extension). Let&#8217;s create its skeleton in the project:<\/p>\n<pre class=\"java\"><code class=\"language-java\">package com.couchbase.demo.vertx;\r\n\r\nimport java.util.ArrayList;\r\nimport java.util.List;\r\n\r\nimport com.couchbase.client.java.CouchbaseAsyncCluster;\r\nimport io.vertx.core.Context;\r\nimport io.vertx.core.Vertx;\r\nimport io.vertx.core.json.JsonArray;\r\nimport io.vertx.core.json.JsonObject;\r\nimport io.vertx.core.logging.Logger;\r\nimport io.vertx.core.logging.LoggerFactory;\r\nimport io.vertx.rxjava.core.AbstractVerticle;\r\n\r\npublic class CouchbaseVerticle extends AbstractVerticle {\r\n\r\n    private static final Logger LOGGER = LoggerFactory.getLogger(CouchbaseVerticle.class);\r\n\r\n    private CouchbaseAsyncCluster cluster;\r\n\r\n}<\/code><\/pre>\n<p>The init phase that we&#8217;ll write right after this will show how to use the Vert.x configuration to determine at runtime which node(s) in the Couchbase cluster we&#8217;ll bootstrap from. Instantiation of the <code>CouchbaseCluster<\/code> is still lightweight enough that it can be done like this during init.<\/p>\n<p>Add the following init method to the <code>CouchbaseVerticle<\/code>:<\/p>\n<pre class=\"java\"><code>@Override\r\npublic void init(Vertx vertx, Context context) {\r\n    super.init(vertx, context);\r\n    \/\/getting the configuration JSON\r\n    JsonObject config = context.config();\r\n\r\n    \/\/getting the bootstrap node, as a JSON array (default to localhost)\r\n    JsonArray seedNodeArray = config.getJsonArray(\"couchbase.seedNodes\", new JsonArray().add(\"localhost\"));\r\n    \/\/convert to a List\r\n    List seedNodes = new ArrayList&lt;&gt;(seedNodeArray.size());\r\n    for (Object seedNode : seedNodeArray) {\r\n        seedNodes.add((String) seedNode);\r\n    }\r\n    \/\/use that to bootstrap the Cluster\r\n    this.cluster = CouchbaseAsyncCluster.create(seedNodes);\r\n}<\/code><\/pre>\n<h2 id=\"asynchronously-obtaining-a-bucket\">Asynchronously Obtaining a Bucket<\/h2>\n<p>The main entry point to the Couchbase API is the <code>Bucket<\/code> interface for the sync API, or <code>AsyncBucket<\/code> for the async API. Establishing the connection to the bucket (&#8220;opening&#8221; it) is much more heavyweight, so it should be done asynchronously.<\/p>\n<p>Let&#8217;s see how we can start our Verticle by first opening the bucket we&#8217;ll use throughout the lifetime of the Verticle. We want to keep a reference to it, and use the <code>start(Future startFuture)<\/code> method to asynchronously notify Vert.x that the Verticle is ready:<\/p>\n<pre class=\"java\"><code>    private volatile AsyncBucket bucket;\r\n\r\n    @Override\r\n    public void start(Future startFuture) throws Exception {\r\n        cluster.openBucket(config().getString(\"couchbase.bucketName\", \"default\"), config().getString(\"couchbase.bucketPassword\", \"\"))\r\n                .doOnNext(openedBucket -&gt; LOGGER.info(\"Bucket opened \" + openedBucket.name()))\r\n                .subscribe(\r\n                        openedBucket -&gt; bucket = openedBucket,\r\n                        startFuture::fail,\r\n                        startFuture::complete);\r\n    }<\/code><\/pre>\n<p>Notice first we get the name of the bucket (and the associated password if relevant) dynamically, from the Vert.x configuration. We open the bucket asynchronously, establishing the connections and resources internal to the SDK.<\/p>\n<p>The <code>doOnNext<\/code> method is used to log the opening of the bucket.<\/p>\n<p>Then we subscribe to our <code>Observable<\/code> stream and describe how we want to &#8220;consume&#8221; the final data:<\/p>\n<ul>\n<li>upon receiving the bucket reference, we store it in a field for later use<\/li>\n<li>if there is an error along the way, we fail the startup of the Verticle using the <code>Future#fail<\/code> method.<\/li>\n<li>otherwise we notify Vert.x that the Verticle was successfully started using the <code>Future#complete<\/code> method.<\/li>\n<\/ul>\n<p>That&#8217;s a pretty good start!<\/p>\n<h2 id=\"gracefully-tearing-down-the-sdk\">Gracefully tearing down the SDK<\/h2>\n<p>When the Verticle stops, the resources created by the SDK should be properly disposed of. The <code>Cluster<\/code> object has a <code>disconnect<\/code> method that does this, recursively calling <code>close<\/code> on every <code>Bucket<\/code> it opened (close can be used to dispose of a single Bucket).<\/p>\n<p>Also since <code>1.0.15<\/code> RxJava has a method for shutting down its internal Threads: <code>Schedulers.shutdown<\/code>. This should be invoked only when there won&#8217;t be subsequent usage of RxJava in the application though, so it might be a better idea to do that upon Vert.x shutdown&#8230;<\/p>\n<p>Once again we&#8217;ll stop the Verticle asynchronously, using a <code>Future<\/code> to notify the framework of stop completion:<\/p>\n<pre class=\"java\"><code>    @Override\r\n    public void stop(Future stopFuture) throws Exception {\r\n        cluster.disconnect()\r\n                .doOnNext(isDisconnectedCleanly -&gt; LOGGER.info(\"Disconnected Cluster (cleaned threads: \" + isDisconnectedCleanly + \")\"))\r\n                .subscribe(\r\n                        isDisconnectedCleanly -&gt; stopFuture.complete(),\r\n                        stopFuture::fail,\r\n                        Schedulers::shutdown);\r\n    }<\/code><\/pre>\n<p>(we chose to shutdown RxJava upon completion of the SDK disconnection)<\/p>\n<blockquote><p><strong>Note<\/strong> You can tune the SDK by passing in a <code>CouchbaseEnvironment<\/code> upon creation of the <code>Cluster<\/code>. In that case, it is up to you to also call <code>shutdown<\/code> on the environment when tearing down the whole SDK (that is, when all Clusters you used the environment in, generally just the one, are shut down).<\/p>\n<p>If you didn&#8217;t create a specific environment the SDK will internally create one and shut it down properly, the result of which is seen above in the <code>isDisconnectedCleanly<\/code> variable.<\/p><\/blockquote>\n<h2 id=\"seeing-it-in-action\">Seeing it in action<\/h2>\n<p>Let&#8217;s create a quick <code>main<\/code> that embeds Vert.x, deploys the Verticle and then stops. Note this is a pretty naive implementation with CountDownLatches, where you would usually rather use the command line or <code>Launcher<\/code> as a main class.<\/p>\n<pre class=\"java\"><code>    public static void main(String[] args) throws InterruptedException {\r\n        Vertx vertx = Vertx.vertx();\r\n\r\n        final CountDownLatch startLatch = new CountDownLatch(1);\r\n        vertx.deployVerticle(new CouchbaseVerticle(), event -&gt; {\r\n            if (event.succeeded())\r\n                LOGGER.info(\"Verticle Deployed - \" + event.result());\r\n            else\r\n                LOGGER.error(\"Verticle deployment error\", event.cause());\r\n            startLatch.countDown();\r\n        });\r\n        startLatch.await();\r\n\r\n        final CountDownLatch stopLatch = new CountDownLatch(1);\r\n        vertx.close(event -&gt; {\r\n            if (event.succeeded())\r\n                LOGGER.info(\"Vert.x Stopped - \" + event.result());\r\n            else\r\n                LOGGER.error(\"Vert.x stopping error\", event.cause());\r\n            stopLatch.countDown();\r\n        });\r\n        stopLatch.await();\r\n    }<\/code><\/pre>\n<p>If you execute this, here is what you should see (notice the difference in timestamp format? <code>2015-12-11<\/code> ones are from the SDK while <code>Dec 11, 2015<\/code> ones are from Vert.x):<\/p>\n<pre class=\"txt\"><code>2015-12-11 16:21:20 INFO  Node:135 - Connected to Node localhost\r\n2015-12-11 16:21:20 INFO  ConfigurationProvider:263 - Opened bucket default\r\nDec 11, 2015 4:21:20 PM com.couchbase.demo.vertx.CouchbaseVerticle\r\nINFO: Bucket opened default\r\nDec 11, 2015 4:21:20 PM com.couchbase.demo.vertx.CouchbaseVerticle\r\nINFO: Verticle Deployed - caf06dd3-c8d1-4b89-8de0-58f09467b805\r\n2015-12-11 16:21:20 INFO  ConfigurationProvider:284 - Closed bucket default\r\n2015-12-11 16:21:20 INFO  Node:145 - Disconnected from Node localhost\r\nDec 11, 2015 4:21:22 PM com.couchbase.demo.vertx.CouchbaseVerticle\r\nINFO: Disconnected Cluster (cleaned threads: true)\r\nDec 11, 2015 4:21:22 PM com.couchbase.demo.vertx.CouchbaseVerticle\r\nINFO: Vert.x Stopped - null<\/code><\/pre>\n<p>How to verify the error behavior? We could simply change the password to one that is wrong, just to check the logs, which then look like:<\/p>\n<pre><code>2015-12-11 16:25:45 WARN  Endpoint:283 - [null][KeyValueEndpoint]: Authentication Failure.\r\n2015-12-11 16:25:45 WARN  ResponseStatusConverter:129 - Unknown ResponseStatus with Protocol HTTP: 401\r\n2015-12-11 16:25:45 WARN  ResponseStatusConverter:129 - Unknown ResponseStatus with Protocol HTTP: 401\r\nDec 11, 2015 4:25:45 PM com.couchbase.demo.vertx.CouchbaseVerticle\r\nSEVERE: Verticle deployment error\r\ncom.couchbase.client.java.error.InvalidPasswordException: Passwords for bucket \"default\" do not match.\r\n    at com.couchbase.client.java.CouchbaseAsyncCluster$1.call(CouchbaseAsyncCluster.java:210)\r\n    at com.couchbase.client.java.CouchbaseAsyncCluster$1.call(CouchbaseAsyncCluster.java:200)\r\n    at rx.internal.operators.OperatorOnErrorResumeNextViaFunction$1.onError(OperatorOnErrorResumeNextViaFunction.java:99)\r\n    at rx.internal.operators.OperatorMap$1.onError(OperatorMap.java:48)\r\n    at rx.observers.Subscribers$5.onError(Subscribers.java:229)\r\n    at rx.internal.operators.OperatorObserveOn$ObserveOnSubscriber.pollQueue(OperatorObserveOn.java:197)\r\n    at rx.internal.operators.OperatorObserveOn$ObserveOnSubscriber$2.call(OperatorObserveOn.java:170)\r\n    at rx.internal.schedulers.ScheduledAction.run(ScheduledAction.java:55)\r\n    at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)\r\n    at java.util.concurrent.FutureTask.run(FutureTask.java:266)\r\n    at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$201(ScheduledThreadPoolExecutor.java:180)\r\n    at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:293)\r\n    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)\r\n    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)\r\n    at java.lang.Thread.run(Thread.java:745)\r\n\r\nDec 11, 2015 4:25:45 PM com.couchbase.demo.vertx.CouchbaseVerticle\r\nINFO: Vert.x Stopped - null<\/code><\/pre>\n<p>So we successfully deployed (and stopped) our first Couchbase Verticle!<br \/>\n<strong>High five!<\/strong><\/p>\n<blockquote><p>\/! <em>don&#8217;t forget to change the password back to the correct one<\/em><\/p><\/blockquote>\n<h2 id=\"going-further\">Going further<\/h2>\n<p>Let&#8217;s try to do a little bit more with this Verticle. How about we try to prepare sample data in Couchbase and serve it in a REST endpoint managed by Vert.x?<\/p>\n<h2 id=\"creating-sample-data-in-couchbase-on-startup\">Creating sample data in Couchbase on startup<\/h2>\n<p>We&#8217;ll create two sample documents in Couchbase during the starting up of the Verticle, users Alice and Bob.<\/p>\n<p>One can store JSON in Couchbase using two <code>Document<\/code> implementations:<\/p>\n<ul>\n<li><code>JsonDocument<\/code> is the default one. It is based on a simple JSON representation provided by the SDK, the <code>JsonObject<\/code>.<\/li>\n<li><code>RawJsonDocument<\/code> is useful when you already have JSON marshalling\/unmarshalling in your application (or another way of representing JSON like Vert.x&#8217;s own <code>JsonObject<\/code>). In this implementation what you pass in is the raw JSON String representation.<\/li>\n<\/ul>\n<p>Here are Alice and Bob, created using both alternatives:<\/p>\n<pre class=\"java\"><code>JsonDocument.create(\"user1\", com.couchbase.client.java.document.json.JsonObject.create()\r\n                            .put(\"name\", \"Alice\").put(\"age\", 26))<\/code><\/pre>\n<p>and<\/p>\n<pre class=\"java\"><code>RawJsonDocument.create(\"user2\", new JsonObject().put(\"name\", \"Bob\").put(\"age\", 31).encode())<\/code><\/pre>\n<p>Now, the start method needs a little bit of adjustment. Instead of saving the reference to the bucket in the subscription, we&#8217;ll move that earlier in a <code>doOnNext<\/code>. After that, we&#8217;ll create the documents and make an Observable out of them using <code>Observable.just<\/code>. This can be forwarded to the SDK for insertion using <code>flatMap<\/code>:<\/p>\n<pre class=\"java\"><code>@Override\r\n    public void start(Future startFuture) throws Exception {\r\n        cluster.openBucket(config().getString(\"couchbase.bucketName\", \"default\"), config().getString(\"couchbase.bucketPassword\", \"\"))\r\n                .doOnNext(openedBucket -&gt; LOGGER.info(\"Bucket opened \" + openedBucket.name()))\r\n                .doOnNext(openedBucket -&gt; bucket = openedBucket)\r\n                .flatMap(nowIgnoreBucket -&gt; Observable.just(\r\n                            JsonDocument.create(\"user1\", com.couchbase.client.java.document.json.JsonObject.create()\r\n                                    .put(\"name\", \"Alice\").put(\"age\", 26)),\r\n                            RawJsonDocument.create(\"user2\", new JsonObject().put(\"name\", \"Bob\").put(\"age\", 31).encode())\r\n                    ))\r\n                .flatMap(doc -&gt; bucket.upsert(doc))\r\n                .subscribe(Actions.empty(),\r\n                        startFuture::fail,\r\n                        startFuture::complete);\r\n    }<\/code><\/pre>\n<p>The use of <code>upsert<\/code> here guarantees that the documents will be created, whether the key already exist in database or not.<\/p>\n<h2 id=\"serving-json-data-from-couchbase\">Serving JSON data from Couchbase<\/h2>\n<p>Let&#8217;s modify our verticle so that it doesn&#8217;t stop right away, instead spinning a HTTP Server that will try to retrieve a json document from the database and send it to a client when the route <code>user\/{id}<\/code> is used:<\/p>\n<p>Here is a quick and dirty way of using Vert.x&#8217;s <code>Launcher<\/code> to start the program (which will not stop the Vert.x core right away). Replace the content of our <code>main<\/code> method with the following:<\/p>\n<pre class=\"java\"><code>String[] vertxArgs = new String[] { \"run\", \"com.couchbase.demo.vertx.CouchbaseVerticle\" };\r\nLauncher.main(vertxArgs);<\/code><\/pre>\n<blockquote><p><strong>Note<\/strong>: In a real application, <code>Launcher<\/code> would usually be made the main class of the jar and you&#8217;d pass in command line arguments directly.<\/p><\/blockquote>\n<p>Now let&#8217;s spin a HTTP Server on Verticle startup. Chain in the following code in the <code>start<\/code> method, right after the <code>flatMap(doc -&gt; bucket.upsert(doc))<\/code> call:<\/p>\n<pre class=\"java\"><code>.last()\r\n.flatMap(ignore -&gt; vertx.createHttpServer()\r\n                        .requestHandler(this::handle)\r\n                        .listenObservable(8080))<\/code><\/pre>\n<p>We need to create the <code>handle<\/code> method to set up that route:<\/p>\n<pre class=\"java\"><code>\r\n    private void handle(HttpServerRequest r) {\r\n        String[] path = r.path().split(\"\/\");\r\n        if (path.length == 3 &amp;&amp; \"users\".equals(path[1])) {\r\n            bucket.get(path[2], RawJsonDocument.class)\r\n                    .switchIfEmpty(Observable.error(new DocumentDoesNotExistException(path[2])))\r\n                    .subscribe(doc -&gt; r.response()\r\n                                    .putHeader(\"content-type\", \"application\/json\")\r\n                                    .end(doc.content()),\r\n                        error -&gt; {\r\n                            r.response()\r\n                            .putHeader(\"content-type\", \"application\/json\")\r\n                                    .setStatusCode(500).setStatusMessage(error.toString())\r\n                                    .end(\"{\"error\": \"\" + error.toString() + \"\"}\");\r\n                        });\r\n        }\r\n    }<\/code><\/pre>\n<p>Let&#8217;s test it: run the application and go to this url: <a class=\"uri\" href=\"https:\/\/localhost:8080\/users\/user1\">https:\/\/localhost:8080\/users\/user1<\/a>. You should see Alice&#8217;s JSON, served directly from Couchbase!<\/p>\n<pre class=\"json\"><code>{\r\n    \"name\": \"Alice\",\r\n    \"age\": 26\r\n}<\/code><\/pre>\n<p>For <a href=\"https:\/\/localhost:8080\/users\/user3\">another key<\/a>, you should see the exception in JSON form:<\/p>\n<pre class=\"json\"><code>{\r\n    \"error\": \"com.couchbase.client.java.error.DocumentDoesNotExistException: user3\"\r\n}<\/code><\/pre>\n<h2 id=\"stopping-the-verticle-via-a-http-endpoint\">Stopping the Verticle via a HTTP endpoint<\/h2>\n<p>Let&#8217;s quickly add a route that stops Vert.x, for fun and profit :)<\/p>\n<pre class=\"java\"><code>\/\/...replacing from the last line in `handle`\r\n} else if (r.path().equals(\"\/stop\")) {\r\n    r.response()\r\n     .end(\"<\/code><\/pre>\n<h2>Closing Couchbase and Vertx<\/h2>\n<p><i>Note that running from a vertx Starter, this won&#8217;t kill the main thread<\/i><\/p>\n<p>&#8220;); vertx.close(); }<\/p>\n<p>Opening <a class=\"uri\" href=\"https:\/\/localhost:8080\/stop\">https:\/\/localhost:8080\/stop<\/a> will trigger the whole Vert.x application to stop, tearing down deployed Verticles.<\/p>\n<blockquote><p><strong>Note<\/strong>: As stated in the message, this doesn&#8217;t kill the process when run from the IDE.<\/p><\/blockquote>\n<h2 id=\"conclusion\">Conclusion<\/h2>\n<p>In this blog post, we&#8217;ve discovered how <code>Vert.x<\/code> and the <code>Couchbase Java SDK<\/code> can work together towards building a fully asynchronous application.<\/p>\n<p>Happy asynchronous coding!<\/p>\n","protected":false},"excerpt":{"rendered":"<p>In this post we&#8217;ll go reactive all the way! Some Couchbase customers use Vert.x, a framework for writing fully asynchronous applications, knowing that the Couchbase Java SDK fits well into this picture, being asynchronous from the ground up and exposing [&hellip;]<\/p>\n","protected":false},"author":48,"featured_media":13873,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"inline_featured_image":false,"footnotes":""},"categories":[1818],"tags":[1439,1516],"ppma_author":[9022],"class_list":["post-2046","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-java","tag-asynchronous","tag-reactive"],"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>Using Couchbase Java SDK to write a Vert.x Verticle - The Couchbase Blog<\/title>\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\/couchbase-java-sdk-writing-vertx-verticle\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Using Couchbase Java SDK to write a Vert.x Verticle\" \/>\n<meta property=\"og:description\" content=\"In this post we&#8217;ll go reactive all the way! Some Couchbase customers use Vert.x, a framework for writing fully asynchronous applications, knowing that the Couchbase Java SDK fits well into this picture, being asynchronous from the ground up and exposing [&hellip;]\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.couchbase.com\/blog\/couchbase-java-sdk-writing-vertx-verticle\/\" \/>\n<meta property=\"og:site_name\" content=\"The Couchbase Blog\" \/>\n<meta property=\"article:published_time\" content=\"2015-12-16T19:35:30+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2024-09-12T08:41:38+00:00\" \/>\n<meta name=\"author\" content=\"Simon Basle, Software Engineer, Pivotal\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Simon Basle, Software Engineer, Pivotal\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"5 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/couchbase-java-sdk-writing-vertx-verticle\/#article\",\"isPartOf\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/couchbase-java-sdk-writing-vertx-verticle\/\"},\"author\":{\"name\":\"Simon Basle, Software Engineer, Pivotal\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/#\/schema\/person\/a4086d75b59570cc2e5ff66d98c5d1a1\"},\"headline\":\"Using Couchbase Java SDK to write a Vert.x Verticle\",\"datePublished\":\"2015-12-16T19:35:30+00:00\",\"dateModified\":\"2024-09-12T08:41:38+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/couchbase-java-sdk-writing-vertx-verticle\/\"},\"wordCount\":1294,\"commentCount\":1,\"publisher\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/#organization\"},\"image\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/couchbase-java-sdk-writing-vertx-verticle\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2022\/11\/couchbase-nosql-dbaas.png\",\"keywords\":[\"asynchronous\",\"Reactive\"],\"articleSection\":[\"Java\"],\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\/\/www.couchbase.com\/blog\/couchbase-java-sdk-writing-vertx-verticle\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/couchbase-java-sdk-writing-vertx-verticle\/\",\"url\":\"https:\/\/www.couchbase.com\/blog\/couchbase-java-sdk-writing-vertx-verticle\/\",\"name\":\"Using Couchbase Java SDK to write a Vert.x Verticle - The Couchbase Blog\",\"isPartOf\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/couchbase-java-sdk-writing-vertx-verticle\/#primaryimage\"},\"image\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/couchbase-java-sdk-writing-vertx-verticle\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2022\/11\/couchbase-nosql-dbaas.png\",\"datePublished\":\"2015-12-16T19:35:30+00:00\",\"dateModified\":\"2024-09-12T08:41:38+00:00\",\"breadcrumb\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/couchbase-java-sdk-writing-vertx-verticle\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/www.couchbase.com\/blog\/couchbase-java-sdk-writing-vertx-verticle\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/couchbase-java-sdk-writing-vertx-verticle\/#primaryimage\",\"url\":\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2022\/11\/couchbase-nosql-dbaas.png\",\"contentUrl\":\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2022\/11\/couchbase-nosql-dbaas.png\",\"width\":1800,\"height\":630},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/couchbase-java-sdk-writing-vertx-verticle\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/www.couchbase.com\/blog\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Using Couchbase Java SDK to write a Vert.x Verticle\"}]},{\"@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\/a4086d75b59570cc2e5ff66d98c5d1a1\",\"name\":\"Simon Basle, Software Engineer, Pivotal\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/#\/schema\/person\/image\/4b2bcd169f85f21cee7b8a0e0c9e7854\",\"url\":\"https:\/\/secure.gravatar.com\/avatar\/3c3aec94782fea5f0a199368c15e836198faf05c1591e0ae0b91178a59457781?s=96&d=mm&r=g\",\"contentUrl\":\"https:\/\/secure.gravatar.com\/avatar\/3c3aec94782fea5f0a199368c15e836198faf05c1591e0ae0b91178a59457781?s=96&d=mm&r=g\",\"caption\":\"Simon Basle, Software Engineer, Pivotal\"},\"description\":\"Simon Basl_ is a Paris-based Software Engineer working in the Spring team at Pivotal. Previously, he worked in the Couchbase Java SDK team. His interests span software design aspects (OOP, design patterns, software architecture), rich clients, what lies beyond code (continuous integration, (D)VCS, best practices), and reactive programming. He is also an editor for the French version of InfoQ.com.\",\"url\":\"https:\/\/www.couchbase.com\/blog\/author\/simon-basle\/\"}]}<\/script>\n<!-- \/ Yoast SEO Premium plugin. -->","yoast_head_json":{"title":"Using Couchbase Java SDK to write a Vert.x Verticle - The Couchbase Blog","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\/couchbase-java-sdk-writing-vertx-verticle\/","og_locale":"en_US","og_type":"article","og_title":"Using Couchbase Java SDK to write a Vert.x Verticle","og_description":"In this post we&#8217;ll go reactive all the way! Some Couchbase customers use Vert.x, a framework for writing fully asynchronous applications, knowing that the Couchbase Java SDK fits well into this picture, being asynchronous from the ground up and exposing [&hellip;]","og_url":"https:\/\/www.couchbase.com\/blog\/couchbase-java-sdk-writing-vertx-verticle\/","og_site_name":"The Couchbase Blog","article_published_time":"2015-12-16T19:35:30+00:00","article_modified_time":"2024-09-12T08:41:38+00:00","author":"Simon Basle, Software Engineer, Pivotal","twitter_card":"summary_large_image","twitter_misc":{"Written by":"Simon Basle, Software Engineer, Pivotal","Est. reading time":"5 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/www.couchbase.com\/blog\/couchbase-java-sdk-writing-vertx-verticle\/#article","isPartOf":{"@id":"https:\/\/www.couchbase.com\/blog\/couchbase-java-sdk-writing-vertx-verticle\/"},"author":{"name":"Simon Basle, Software Engineer, Pivotal","@id":"https:\/\/www.couchbase.com\/blog\/#\/schema\/person\/a4086d75b59570cc2e5ff66d98c5d1a1"},"headline":"Using Couchbase Java SDK to write a Vert.x Verticle","datePublished":"2015-12-16T19:35:30+00:00","dateModified":"2024-09-12T08:41:38+00:00","mainEntityOfPage":{"@id":"https:\/\/www.couchbase.com\/blog\/couchbase-java-sdk-writing-vertx-verticle\/"},"wordCount":1294,"commentCount":1,"publisher":{"@id":"https:\/\/www.couchbase.com\/blog\/#organization"},"image":{"@id":"https:\/\/www.couchbase.com\/blog\/couchbase-java-sdk-writing-vertx-verticle\/#primaryimage"},"thumbnailUrl":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2022\/11\/couchbase-nosql-dbaas.png","keywords":["asynchronous","Reactive"],"articleSection":["Java"],"inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/www.couchbase.com\/blog\/couchbase-java-sdk-writing-vertx-verticle\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/www.couchbase.com\/blog\/couchbase-java-sdk-writing-vertx-verticle\/","url":"https:\/\/www.couchbase.com\/blog\/couchbase-java-sdk-writing-vertx-verticle\/","name":"Using Couchbase Java SDK to write a Vert.x Verticle - The Couchbase Blog","isPartOf":{"@id":"https:\/\/www.couchbase.com\/blog\/#website"},"primaryImageOfPage":{"@id":"https:\/\/www.couchbase.com\/blog\/couchbase-java-sdk-writing-vertx-verticle\/#primaryimage"},"image":{"@id":"https:\/\/www.couchbase.com\/blog\/couchbase-java-sdk-writing-vertx-verticle\/#primaryimage"},"thumbnailUrl":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2022\/11\/couchbase-nosql-dbaas.png","datePublished":"2015-12-16T19:35:30+00:00","dateModified":"2024-09-12T08:41:38+00:00","breadcrumb":{"@id":"https:\/\/www.couchbase.com\/blog\/couchbase-java-sdk-writing-vertx-verticle\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.couchbase.com\/blog\/couchbase-java-sdk-writing-vertx-verticle\/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.couchbase.com\/blog\/couchbase-java-sdk-writing-vertx-verticle\/#primaryimage","url":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2022\/11\/couchbase-nosql-dbaas.png","contentUrl":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2022\/11\/couchbase-nosql-dbaas.png","width":1800,"height":630},{"@type":"BreadcrumbList","@id":"https:\/\/www.couchbase.com\/blog\/couchbase-java-sdk-writing-vertx-verticle\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/www.couchbase.com\/blog\/"},{"@type":"ListItem","position":2,"name":"Using Couchbase Java SDK to write a Vert.x Verticle"}]},{"@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\/a4086d75b59570cc2e5ff66d98c5d1a1","name":"Simon Basle, Software Engineer, Pivotal","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.couchbase.com\/blog\/#\/schema\/person\/image\/4b2bcd169f85f21cee7b8a0e0c9e7854","url":"https:\/\/secure.gravatar.com\/avatar\/3c3aec94782fea5f0a199368c15e836198faf05c1591e0ae0b91178a59457781?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/3c3aec94782fea5f0a199368c15e836198faf05c1591e0ae0b91178a59457781?s=96&d=mm&r=g","caption":"Simon Basle, Software Engineer, Pivotal"},"description":"Simon Basl_ is a Paris-based Software Engineer working in the Spring team at Pivotal. Previously, he worked in the Couchbase Java SDK team. His interests span software design aspects (OOP, design patterns, software architecture), rich clients, what lies beyond code (continuous integration, (D)VCS, best practices), and reactive programming. He is also an editor for the French version of InfoQ.com.","url":"https:\/\/www.couchbase.com\/blog\/author\/simon-basle\/"}]}},"authors":[{"term_id":9022,"user_id":48,"is_guest":0,"slug":"simon-basle","display_name":"Simon Basle, Software Engineer, Pivotal","avatar_url":"https:\/\/secure.gravatar.com\/avatar\/3c3aec94782fea5f0a199368c15e836198faf05c1591e0ae0b91178a59457781?s=96&d=mm&r=g","author_category":"","last_name":"Basle","first_name":"Simon","job_title":"","user_url":"","description":"Simon Basl_ is a Paris-based Software Engineer working in the Spring team at Pivotal. Previously, he worked in the Couchbase Java SDK team. His interests span software design aspects (OOP, design patterns, software architecture), rich clients, what lies beyond code (continuous integration, (D)VCS, best practices), and reactive programming. He is also an editor for the French version of InfoQ.com."}],"_links":{"self":[{"href":"https:\/\/www.couchbase.com\/blog\/wp-json\/wp\/v2\/posts\/2046","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\/48"}],"replies":[{"embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/wp-json\/wp\/v2\/comments?post=2046"}],"version-history":[{"count":0,"href":"https:\/\/www.couchbase.com\/blog\/wp-json\/wp\/v2\/posts\/2046\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/wp-json\/wp\/v2\/media\/13873"}],"wp:attachment":[{"href":"https:\/\/www.couchbase.com\/blog\/wp-json\/wp\/v2\/media?parent=2046"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/wp-json\/wp\/v2\/categories?post=2046"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/wp-json\/wp\/v2\/tags?post=2046"},{"taxonomy":"author","embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/wp-json\/wp\/v2\/ppma_author?post=2046"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}