{"id":2240,"date":"2016-04-30T19:49:25","date_gmt":"2016-04-30T19:49:24","guid":{"rendered":"https:\/\/www.couchbase.com\/blog\/?p=2240"},"modified":"2025-06-13T23:17:02","modified_gmt":"2025-06-14T06:17:02","slug":"crud-rest-api-couchbase-rxjava-ratpack","status":"publish","type":"post","link":"https:\/\/www.couchbase.com\/blog\/pt\/crud-rest-api-couchbase-rxjava-ratpack\/","title":{"rendered":"Uma API REST CRUD com Couchbase, RxJava e Ratpack"},"content":{"rendered":"<p><img decoding=\"async\" align=\"right\" src=\"\/wp-content\/original-assets\/2016\/april\/crud-rest-api-couchbase-rxjava-ratpack\/ratpacklogo.png\" \/>Em meus dois <a href=\"\/blog\/pt\/getting-started-ratpack-couchbase\/\">anterior<\/a> <a href=\"\/blog\/pt\/ratpack-couchbase-rxjava\/\">blog<\/a> Nas postagens, apresentei o Ratpack e a camada ODM leve dispon\u00edvel em nosso <a href=\"https:\/\/developer.couchbase.com\/documentation\/server\/4.1\/sdks\/java-2.2\/java-intro.html?utm_source=blogs&#038;utm_medium=link&#038;utm_campaign=blogs\">Java SDK<\/a>. Esta postagem se basear\u00e1 neles e apresentar\u00e1 uma API REST para gerenciar usu\u00e1rios por meio do reposit\u00f3rio do Couchbase.<\/p>\n<p>Quero que minha API seja compat\u00edvel com os quatro verbos HTTP b\u00e1sicos e com o tipo de conte\u00fado. Tudo foi pensado para isso no Ratpack. O <a href=\"https:\/\/ratpack.io\/manual\/current\/api\/ratpack\/handling\/Chain.html\">Cadeia<\/a> \u00e9 como um construtor para compor manipuladores. Ent\u00e3o, escrevi um novo objeto <a href=\"https:\/\/ratpack.io\/manual\/current\/api\/ratpack\/func\/Action.html\">A\u00e7\u00e3o<\/a> para vincular uma cadeia ao prefixo de URL &apos;user&apos;. Isso simplificar\u00e1 bastante meu m\u00e9todo principal:<\/p>\n<pre>\n<code>    public static void main(String... args) throws Exception {\n        RxRatpack.initialize();\n        RatpackServer.start(server -> server.registry(Guice.registry(b -> b.module(Config.class)))\n                .handlers(chain -> chain.prefix(\"user\", UserHandler.class)));\n    }\n<\/code><\/pre>\n<p>Para garantir que minha inst\u00e2ncia UserHandler possa ser encontrada, tamb\u00e9m preciso adicion\u00e1-la ao meu m\u00f3dulo Config Guice:<\/p>\n<pre>\n<code>    public class Config extends AbstractModule {\n\n        protected void configure() {\n            CouchbaseCluster cc = CouchbaseCluster.create();\n            Bucket bucket = cc.openBucket();\n            bind(AsyncBucket.class).toInstance(bucket.async());\n            bind(AsyncRepository.class).toInstance(bucket.repository().async());\n            bind(UserHandler.class);\n            bind(UserRenderer.class);\n        }\n    }\n<\/code><\/pre>\n<p>Tamb\u00e9m adiciono a classe UserRenderer que ser\u00e1 usada para lidar com os diferentes tipos de conte\u00fado.<\/p>\n<h2>Renderizador personalizado<\/h2>\n<p>No Ratpack, voc\u00ea pode registrar novos <a href=\"https:\/\/ratpack.io\/manual\/current\/api\/ratpack\/render\/RendererSupport.html\">RendererSupport<\/a> classes. Seu objetivo \u00e9 especificar uma maneira de renderizar seu objeto T com base na classe <a href=\"https:\/\/ratpack.io\/manual\/current\/context.html#context\">Contexto<\/a>. No meu caso, quero renderizar um objeto User com base no tipo de conte\u00fado do contexto. O objeto Context fornece a voc\u00ea um <a href=\"https:\/\/ratpack.io\/manual\/current\/api\/ratpack\/handling\/ByContentSpec.html\">porConte\u00fado<\/a> que permite compor a renderiza\u00e7\u00e3o com base no tipo de conte\u00fado definido na solicita\u00e7\u00e3o. Os tipos usuais j\u00e1 est\u00e3o predefinidos. No meu caso, quero apenas oferecer suporte a json e texto:<\/p>\n<pre>\n<code>    public class UserRenderer extends RendererSupport<User> {\n\n        @Override\n        public void render(Context context, User user) throws Exception {\n            context.byContent(byContentSpec -> byContentSpec\n                    .json(() -> context.render(Jackson.json(user)))\n                    .plainText(() -> context.render(user.toString()))\n            );\n        }\n\n    }\n<\/code><\/pre>\n<p>A renderiza\u00e7\u00e3o de texto \u00e9 apenas um simples toString(). A vers\u00e3o JSON usa o objeto Jackson dispon\u00edvel por padr\u00e3o no Ratpack. Ele lhe d\u00e1 acesso a um atalho para convers\u00f5es JSON\/Objeto. Uma chamada para o m\u00e9todo json fornecendo o objeto User como argumento \u00e9 suficiente. O Jackson tamb\u00e9m \u00e9 usado internamente pelo nosso Java SDK. Mas h\u00e1 um truque. A anota\u00e7\u00e3o @Field que usei no meu ODM do Couchabse n\u00e3o \u00e9 captada pelo mapeador Jackson padr\u00e3o usado no Ratpack. Portanto, preciso adicionar a anota\u00e7\u00e3o Jackson @JsonProperty para compensar. Eu n\u00e3o teria que adicionar nada se n\u00e3o tivesse usado a anota\u00e7\u00e3o @Field em primeiro lugar. Tentarei encontrar uma maneira melhor de fazer isso funcionar, mas, enquanto isso, est\u00e1 funcionando muito bem.<\/p>\n<pre>\n<code>    @Field(\"fName\")\n    @JsonProperty(\"fName\")\n    private String firstName;\n\n    @Field(\"lName\")\n    @JsonProperty(\"lName\")\n    private String lastName;\n<\/code><\/pre>\n<h2>Composi\u00e7\u00e3o da API com manipuladores<\/h2>\n<p>Agora estou em uma boa posi\u00e7\u00e3o para come\u00e7ar a trabalhar na API. GET, PUT e DELETE precisam de um ID de usu\u00e1rio para funcionar. Portanto, a primeira coisa que estou fazendo \u00e9 verificar se h\u00e1 algo ap\u00f3s o URL \/user\/. Os manipuladores s\u00e3o todos encadeados e executados na ordem em que voc\u00ea os declara. Quando voc\u00ea entra em um manipulador, a cadeia \u00e9 interrompida. Portanto, voc\u00ea deve certificar-se de declarar \/user\/:userId antes de \/user\/. A vincula\u00e7\u00e3o de caminho usa regex, e voc\u00ea encontrar\u00e1 exemplos na se\u00e7\u00e3o <a href=\"https:\/\/ratpack.io\/manual\/current\/api\/ratpack\/handling\/Chain.html\">Cadeia<\/a> documenta\u00e7\u00e3o.<\/p>\n<p>Chamando o <code>caminho<\/code> permite que eu forne\u00e7a o regex do caminho e um manipulador como argumento. No manipulador, come\u00e7o obtendo o reposit\u00f3rio do Couchbase e o userId dos tokens de caminho. Em seguida, chamo o m\u00e9todo <a href=\"https:\/\/ratpack.io\/manual\/current\/api\/ratpack\/handling\/ByMethodSpec.html\">porM\u00e9todo<\/a> para definir uma fun\u00e7\u00e3o para cada verbo HTTP que preciso suportar. Aqui, retornarei um usu\u00e1rio para GET, atualizarei ou criarei um usu\u00e1rio para PUT e removerei o usu\u00e1rio para REMOVE.<\/p>\n<p>O verbo mais interessante aqui \u00e9 o PUT, pois ele requer conte\u00fado da solicita\u00e7\u00e3o. O contexto <code>analisar<\/code> recebe um <a href=\"https:\/\/ratpack.io\/manual\/current\/api\/ratpack\/parse\/Parse.html\">Analisar<\/a> como argumento e retorna uma Promise. Aqui eu quero analisar o JSON da solicita\u00e7\u00e3o e mape\u00e1-lo para um objeto User. Portanto, ele retorna uma Promise. Como sou um usu\u00e1rio do RxJava, mapearei essa Promise para um Observable e, em seguida, mapearei o objeto User para um EntityDocument para finalmente salv\u00e1-lo no reposit\u00f3rio do Couchbase. Em seguida, converto esse observ\u00e1vel novamente em uma promessa do ratpack e envio de volta uma string OK simples. Talvez voc\u00ea queira fazer algo mais inteligente em casos reais :)<\/p>\n<pre>\n<code>            chain.path(\":userId\", ctx -> {\n                AsyncRepository repo = ctx.get(AsyncRepository.class);\n                String userId = ctx.getPathTokens().get(\"userId\");\n                ctx.byMethod(methodSpec -> {\n                    methodSpec.get(() -> {\n                        Observable<EntityDocument<User>> user = repo.get(userId, User.class);\n                        RxRatpack.promise(user).then(u -> ctx.render(u.get(0).content()));\n                    }).put(() -> {\n                        Promise<User> promise = ctx.parse(Jackson.fromJson(User.class));\n                        Observable<EntityDocument<User>> observable = RxRatpack.observe(promise)\n                                .map(user -> EntityDocument.create(user)).flatMap(doc -> repo.upsert(doc));\n                        RxRatpack.promise(observable).then(doc -> ctx.render(\"OK\"));\n                    }).delete(() -> {\n                        Observable<EntityDocument<User>> user = repo.remove(userId, User.class);\n                        RxRatpack.promise(user).then(u -> ctx.render(\"OK\"));\n                    });\n                });\n            });\n<\/code><\/pre>\n<p>Quando os verbos HTTP que precisam de um userId forem implementados, poderei concluir todos os outros. E posso fazer isso facilmente com o m\u00e9todo <code>todos<\/code>. Aqui eu obtenho o reposit\u00f3rio e o bucket do registro. Em seguida, para o m\u00e9todo GET, como ele n\u00e3o tem identifica\u00e7\u00e3o de usu\u00e1rio, retorno a lista completa de usu\u00e1rios. Para isso, executo uma consulta N1QL b\u00e1sica. Por fim, o m\u00e9todo POST \u00e9 id\u00eantico ao m\u00e9todo PUT.<\/p>\n<pre>\n<code>            chain.all(ctx -> {\n                AsyncBucket bucket = ctx.get(AsyncBucket.class);\n                AsyncRepository repo = ctx.get(AsyncRepository.class);\n                ctx.byMethod(methodSpec -> {\n                    methodSpec.get(() -> {\n                        N1qlQuery query = N1qlQuery.simple(\"SELECT Meta().id as username,age,fName,lName FROM default WHERE type = &apos;user&apos;\");\n                        Observable<User> observable = bucket.query(query)\n                                .flatMap(qRes -> qRes.rows()).map(row -> {\n                                    JsonObject jo = row.value();\n                                    String username = jo.getString(\"username\");\n                                    Integer age = jo.getInt(\"age\");\n                                    String fName = jo.getString(\"fName\");\n                                    String lName = jo.getString(\"lName\");\n                                    return new User(username, age, fName, lName);\n                                });\n                        RxRatpack.promise(observable).then(users -> ctx.render(Jackson.json(users)));\n                    }).post(() -> {\n                        Promise<User> promise = ctx.parse(Jackson.fromJson(User.class));\n                        Observable<EntityDocument<User>> observable = RxRatpack.observe(promise)\n                                .map(user -> EntityDocument.create(user)).flatMap(doc -> repo.upsert(doc));\n                        RxRatpack.promise(observable).then(doc -> ctx.render(\"OK\"));\n                    });\n                });\n            });\n<\/code><\/pre>\n<p>Essa pode n\u00e3o ser uma API totalmente RESTFUL, mas deve lhe dar uma boa ideia de como \u00e9 f\u00e1cil criar uma com o Ratpack, o Couchbase e o RxJava. Se voc\u00ea quiser ver mais coisas acontecendo com o Ratpack, como um m\u00f3dulo do Couchbase, entre em contato comigo.<\/p>","protected":false},"excerpt":{"rendered":"<p>In my two previous blog posts I have introduced Ratpack and the lightweight ODM layer available in our Java SDK. This post will build up on them and showcase a REST API to manage users through the Couchbase repository. I [&hellip;]<\/p>","protected":false},"author":49,"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":[1635,1950],"ppma_author":[9023],"class_list":["post-2240","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-java","tag-ratpack","tag-rest-api"],"acf":[],"yoast_head":"<!-- This site is optimized with the Yoast SEO Premium plugin v26.2 (Yoast SEO v26.2) - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<title>A CRUD REST API with Couchbase, RxJava and Ratpack - 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\/pt\/crud-rest-api-couchbase-rxjava-ratpack\/\" \/>\n<meta property=\"og:locale\" content=\"pt_BR\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"A CRUD REST API with Couchbase, RxJava and Ratpack\" \/>\n<meta property=\"og:description\" content=\"In my two previous blog posts I have introduced Ratpack and the lightweight ODM layer available in our Java SDK. This post will build up on them and showcase a REST API to manage users through the Couchbase repository. I [&hellip;]\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.couchbase.com\/blog\/pt\/crud-rest-api-couchbase-rxjava-ratpack\/\" \/>\n<meta property=\"og:site_name\" content=\"The Couchbase Blog\" \/>\n<meta property=\"article:published_time\" content=\"2016-04-30T19:49:24+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2025-06-14T06:17:02+00:00\" \/>\n<meta name=\"author\" content=\"Laurent Doguin\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:creator\" content=\"@ldoguin\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"unstructured.io\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"5 minutos\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/crud-rest-api-couchbase-rxjava-ratpack\/#article\",\"isPartOf\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/crud-rest-api-couchbase-rxjava-ratpack\/\"},\"author\":{\"name\":\"Laurent Doguin\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/#\/schema\/person\/c0aa9b8f1ed51b7a9e2f7cb755994a5e\"},\"headline\":\"A CRUD REST API with Couchbase, RxJava and Ratpack\",\"datePublished\":\"2016-04-30T19:49:24+00:00\",\"dateModified\":\"2025-06-14T06:17:02+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/crud-rest-api-couchbase-rxjava-ratpack\/\"},\"wordCount\":742,\"commentCount\":0,\"publisher\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/#organization\"},\"image\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/crud-rest-api-couchbase-rxjava-ratpack\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2022\/11\/couchbase-nosql-dbaas.png\",\"keywords\":[\"ratpack\",\"REST API\"],\"articleSection\":[\"Java\"],\"inLanguage\":\"pt-BR\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\/\/www.couchbase.com\/blog\/crud-rest-api-couchbase-rxjava-ratpack\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/crud-rest-api-couchbase-rxjava-ratpack\/\",\"url\":\"https:\/\/www.couchbase.com\/blog\/crud-rest-api-couchbase-rxjava-ratpack\/\",\"name\":\"A CRUD REST API with Couchbase, RxJava and Ratpack - The Couchbase Blog\",\"isPartOf\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/crud-rest-api-couchbase-rxjava-ratpack\/#primaryimage\"},\"image\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/crud-rest-api-couchbase-rxjava-ratpack\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2022\/11\/couchbase-nosql-dbaas.png\",\"datePublished\":\"2016-04-30T19:49:24+00:00\",\"dateModified\":\"2025-06-14T06:17:02+00:00\",\"breadcrumb\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/crud-rest-api-couchbase-rxjava-ratpack\/#breadcrumb\"},\"inLanguage\":\"pt-BR\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/www.couchbase.com\/blog\/crud-rest-api-couchbase-rxjava-ratpack\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"pt-BR\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/crud-rest-api-couchbase-rxjava-ratpack\/#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\/crud-rest-api-couchbase-rxjava-ratpack\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/www.couchbase.com\/blog\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"A CRUD REST API with Couchbase, RxJava and Ratpack\"}]},{\"@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\":\"pt-BR\"},{\"@type\":\"Organization\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/#organization\",\"name\":\"The Couchbase Blog\",\"url\":\"https:\/\/www.couchbase.com\/blog\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"pt-BR\",\"@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\/c0aa9b8f1ed51b7a9e2f7cb755994a5e\",\"name\":\"Laurent Doguin\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"pt-BR\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/#\/schema\/person\/image\/12929ce99397769f362b7a90d6b85071\",\"url\":\"https:\/\/secure.gravatar.com\/avatar\/b8c466908092b46634af916b6921f30187a051e4367ded7ac9b1a3f2c5692fd2?s=96&d=mm&r=g\",\"contentUrl\":\"https:\/\/secure.gravatar.com\/avatar\/b8c466908092b46634af916b6921f30187a051e4367ded7ac9b1a3f2c5692fd2?s=96&d=mm&r=g\",\"caption\":\"Laurent Doguin\"},\"description\":\"Laurent is a nerdy metal head who lives in Paris. He mostly writes code in Java and structured text in AsciiDoc, and often talks about data, reactive programming and other buzzwordy stuff. He is also a former Developer Advocate for Clever Cloud and Nuxeo where he devoted his time and expertise to helping those communities grow bigger and stronger. He now runs Developer Relations at Couchbase.\",\"sameAs\":[\"https:\/\/x.com\/ldoguin\"],\"honorificPrefix\":\"Mr\",\"birthDate\":\"1985-06-07\",\"gender\":\"male\",\"award\":[\"Devoxx Champion\",\"Couchbase Legend\"],\"knowsAbout\":[\"Java\"],\"knowsLanguage\":[\"English\",\"French\"],\"jobTitle\":\"Director Developer Relation & Strategy\",\"worksFor\":\"Couchbase\",\"url\":\"https:\/\/www.couchbase.com\/blog\/pt\/author\/laurent-doguin\/\"}]}<\/script>\n<!-- \/ Yoast SEO Premium plugin. -->","yoast_head_json":{"title":"A CRUD REST API with Couchbase, RxJava and Ratpack - 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\/pt\/crud-rest-api-couchbase-rxjava-ratpack\/","og_locale":"pt_BR","og_type":"article","og_title":"A CRUD REST API with Couchbase, RxJava and Ratpack","og_description":"In my two previous blog posts I have introduced Ratpack and the lightweight ODM layer available in our Java SDK. This post will build up on them and showcase a REST API to manage users through the Couchbase repository. I [&hellip;]","og_url":"https:\/\/www.couchbase.com\/blog\/pt\/crud-rest-api-couchbase-rxjava-ratpack\/","og_site_name":"The Couchbase Blog","article_published_time":"2016-04-30T19:49:24+00:00","article_modified_time":"2025-06-14T06:17:02+00:00","author":"Laurent Doguin","twitter_card":"summary_large_image","twitter_creator":"@ldoguin","twitter_misc":{"Written by":"unstructured.io","Est. reading time":"5 minutos"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/www.couchbase.com\/blog\/crud-rest-api-couchbase-rxjava-ratpack\/#article","isPartOf":{"@id":"https:\/\/www.couchbase.com\/blog\/crud-rest-api-couchbase-rxjava-ratpack\/"},"author":{"name":"Laurent Doguin","@id":"https:\/\/www.couchbase.com\/blog\/#\/schema\/person\/c0aa9b8f1ed51b7a9e2f7cb755994a5e"},"headline":"A CRUD REST API with Couchbase, RxJava and Ratpack","datePublished":"2016-04-30T19:49:24+00:00","dateModified":"2025-06-14T06:17:02+00:00","mainEntityOfPage":{"@id":"https:\/\/www.couchbase.com\/blog\/crud-rest-api-couchbase-rxjava-ratpack\/"},"wordCount":742,"commentCount":0,"publisher":{"@id":"https:\/\/www.couchbase.com\/blog\/#organization"},"image":{"@id":"https:\/\/www.couchbase.com\/blog\/crud-rest-api-couchbase-rxjava-ratpack\/#primaryimage"},"thumbnailUrl":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2022\/11\/couchbase-nosql-dbaas.png","keywords":["ratpack","REST API"],"articleSection":["Java"],"inLanguage":"pt-BR","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/www.couchbase.com\/blog\/crud-rest-api-couchbase-rxjava-ratpack\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/www.couchbase.com\/blog\/crud-rest-api-couchbase-rxjava-ratpack\/","url":"https:\/\/www.couchbase.com\/blog\/crud-rest-api-couchbase-rxjava-ratpack\/","name":"A CRUD REST API with Couchbase, RxJava and Ratpack - The Couchbase Blog","isPartOf":{"@id":"https:\/\/www.couchbase.com\/blog\/#website"},"primaryImageOfPage":{"@id":"https:\/\/www.couchbase.com\/blog\/crud-rest-api-couchbase-rxjava-ratpack\/#primaryimage"},"image":{"@id":"https:\/\/www.couchbase.com\/blog\/crud-rest-api-couchbase-rxjava-ratpack\/#primaryimage"},"thumbnailUrl":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2022\/11\/couchbase-nosql-dbaas.png","datePublished":"2016-04-30T19:49:24+00:00","dateModified":"2025-06-14T06:17:02+00:00","breadcrumb":{"@id":"https:\/\/www.couchbase.com\/blog\/crud-rest-api-couchbase-rxjava-ratpack\/#breadcrumb"},"inLanguage":"pt-BR","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.couchbase.com\/blog\/crud-rest-api-couchbase-rxjava-ratpack\/"]}]},{"@type":"ImageObject","inLanguage":"pt-BR","@id":"https:\/\/www.couchbase.com\/blog\/crud-rest-api-couchbase-rxjava-ratpack\/#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\/crud-rest-api-couchbase-rxjava-ratpack\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/www.couchbase.com\/blog\/"},{"@type":"ListItem","position":2,"name":"A CRUD REST API with Couchbase, RxJava and Ratpack"}]},{"@type":"WebSite","@id":"https:\/\/www.couchbase.com\/blog\/#website","url":"https:\/\/www.couchbase.com\/blog\/","name":"Blog do Couchbase","description":"Couchbase, o banco de dados NoSQL","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":"pt-BR"},{"@type":"Organization","@id":"https:\/\/www.couchbase.com\/blog\/#organization","name":"Blog do Couchbase","url":"https:\/\/www.couchbase.com\/blog\/","logo":{"@type":"ImageObject","inLanguage":"pt-BR","@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\/c0aa9b8f1ed51b7a9e2f7cb755994a5e","name":"Laurent Doguin","image":{"@type":"ImageObject","inLanguage":"pt-BR","@id":"https:\/\/www.couchbase.com\/blog\/#\/schema\/person\/image\/12929ce99397769f362b7a90d6b85071","url":"https:\/\/secure.gravatar.com\/avatar\/b8c466908092b46634af916b6921f30187a051e4367ded7ac9b1a3f2c5692fd2?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/b8c466908092b46634af916b6921f30187a051e4367ded7ac9b1a3f2c5692fd2?s=96&d=mm&r=g","caption":"Laurent Doguin"},"description":"Laurent \u00e9 um nerd metaleiro que mora em Paris. Em sua maior parte, ele escreve c\u00f3digo em Java e texto estruturado em AsciiDoc, e frequentemente fala sobre dados, programa\u00e7\u00e3o reativa e outras coisas que est\u00e3o na moda. Ele tamb\u00e9m foi Developer Advocate do Clever Cloud e do Nuxeo, onde dedicou seu tempo e experi\u00eancia para ajudar essas comunidades a crescerem e se fortalecerem. Atualmente, ele dirige as Rela\u00e7\u00f5es com Desenvolvedores na Couchbase.","sameAs":["https:\/\/x.com\/ldoguin"],"honorificPrefix":"Mr","birthDate":"1985-06-07","gender":"male","award":["Devoxx Champion","Couchbase Legend"],"knowsAbout":["Java"],"knowsLanguage":["English","French"],"jobTitle":"Director Developer Relation & Strategy","worksFor":"Couchbase","url":"https:\/\/www.couchbase.com\/blog\/pt\/author\/laurent-doguin\/"}]}},"authors":[{"term_id":9023,"user_id":49,"is_guest":0,"slug":"laurent-doguin","display_name":"Laurent Doguin","avatar_url":"https:\/\/secure.gravatar.com\/avatar\/b8c466908092b46634af916b6921f30187a051e4367ded7ac9b1a3f2c5692fd2?s=96&d=mm&r=g","author_category":"","last_name":"Doguin","first_name":"Laurent","job_title":"","user_url":"","description":"Laurent \u00e9 um nerd metaleiro que mora em Paris. Em sua maior parte, ele escreve c\u00f3digo em Java e texto estruturado em AsciiDoc, e frequentemente fala sobre dados, programa\u00e7\u00e3o reativa e outras coisas que est\u00e3o na moda. Ele tamb\u00e9m foi Developer Advocate do Clever Cloud e do Nuxeo, onde dedicou seu tempo e experi\u00eancia para ajudar essas comunidades a crescerem e se fortalecerem. Atualmente, ele dirige as Rela\u00e7\u00f5es com Desenvolvedores na Couchbase."}],"_links":{"self":[{"href":"https:\/\/www.couchbase.com\/blog\/pt\/wp-json\/wp\/v2\/posts\/2240","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.couchbase.com\/blog\/pt\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.couchbase.com\/blog\/pt\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/pt\/wp-json\/wp\/v2\/users\/49"}],"replies":[{"embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/pt\/wp-json\/wp\/v2\/comments?post=2240"}],"version-history":[{"count":0,"href":"https:\/\/www.couchbase.com\/blog\/pt\/wp-json\/wp\/v2\/posts\/2240\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/pt\/wp-json\/wp\/v2\/media\/13873"}],"wp:attachment":[{"href":"https:\/\/www.couchbase.com\/blog\/pt\/wp-json\/wp\/v2\/media?parent=2240"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/pt\/wp-json\/wp\/v2\/categories?post=2240"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/pt\/wp-json\/wp\/v2\/tags?post=2240"},{"taxonomy":"author","embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/pt\/wp-json\/wp\/v2\/ppma_author?post=2240"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}