{"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\/es\/crud-rest-api-couchbase-rxjava-ratpack\/","title":{"rendered":"Una API CRUD REST con Couchbase, RxJava y Ratpack"},"content":{"rendered":"<p><img decoding=\"async\" align=\"right\" src=\"\/wp-content\/original-assets\/2016\/april\/crud-rest-api-couchbase-rxjava-ratpack\/ratpacklogo.png\" \/>En mis dos <a href=\"\/blog\/es\/getting-started-ratpack-couchbase\/\">anterior<\/a> <a href=\"\/blog\/es\/ratpack-couchbase-rxjava\/\">blog<\/a> posts he presentado Ratpack y la capa ODM ligera disponible en nuestro <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\">SDK de Java<\/a>. Este post se basar\u00e1 en ellos y mostrar\u00e1 una API REST para gestionar usuarios a trav\u00e9s del repositorio Couchbase.<\/p>\n<p>Quiero que mi API soporte los cuatro verbos HTTP b\u00e1sicos y soporte content-type. Todo ha sido pensado para eso en Ratpack. La direcci\u00f3n <a href=\"https:\/\/ratpack.io\/manual\/current\/api\/ratpack\/handling\/Chain.html\">Cadena<\/a> es como un constructor para componer manejadores. As\u00ed que escrib\u00ed un nuevo <a href=\"https:\/\/ratpack.io\/manual\/current\/api\/ratpack\/func\/Action.html\">Acci\u00f3n<\/a> para enlazar una cadena al prefijo &apos;user&apos; URL. Esto simplificar\u00e1 mucho mi 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 asegurarme de que mi instancia de UserHandler puede ser encontrada, tambi\u00e9n necesito a\u00f1adirla a mi 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>Tambi\u00e9n a\u00f1ado la clase UserRenderer que se utilizar\u00e1 para manejar los diferentes tipos de contenido.<\/p>\n<h2>Renderizador personalizado<\/h2>\n<p>En Ratpack puede registrar nuevos <a href=\"https:\/\/ratpack.io\/manual\/current\/api\/ratpack\/render\/RendererSupport.html\">RendererSupport<\/a> . Su objetivo es especificar una forma de renderizar su objeto T bas\u00e1ndose en la clase <a href=\"https:\/\/ratpack.io\/manual\/current\/context.html#context\">Contexto<\/a>. En mi caso quiero renderizar un objeto Usuario basado en el tipo de contenido del contexto. El objeto Context te da un <a href=\"https:\/\/ratpack.io\/manual\/current\/api\/ratpack\/handling\/ByContentSpec.html\">porContenido<\/a> que permite componer el renderizado bas\u00e1ndose en el tipo de contenido establecido en la solicitud. Los tipos habituales ya est\u00e1n predefinidos. En mi caso solo quiero soportar json y 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>La representaci\u00f3n del texto es un simple toString(). La versi\u00f3n JSON utiliza el objeto Jackson disponible por defecto en Ratpack. Te da acceso a un atajo para conversiones JSON\/Objeto. Una llamada al m\u00e9todo json con el objeto User como argumento es suficiente. Jackson tambi\u00e9n es utilizado internamente por nuestro Java SDK. Pero hay un truco. La anotaci\u00f3n @Field que utilic\u00e9 para mi ODM Couchabse no es recogida por el mapeador Jackson por defecto utilizado en Ratpack. As\u00ed que tengo que a\u00f1adir la anotaci\u00f3n @JsonProperty de Jackson para compensar. No habr\u00eda tenido que a\u00f1adir nada si no hubiera utilizado la anotaci\u00f3n @Field en primer lugar. Voy a tratar de encontrar una mejor manera de hacer que esto funcione, pero mientras tanto funciona muy bien.<\/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>Componer la API con manejadores<\/h2>\n<p>Ahora estoy en una buena posici\u00f3n para empezar a trabajar en la API. GET, PUT y DELETE necesitan un identificador de usuario para funcionar. As\u00ed que lo primero que estoy haciendo es comprobar si hay algo despu\u00e9s de la URL \/user\/. Los handlers est\u00e1n todos encadenados y se ejecutan en el orden en que los declaras. Una vez que entras en un manejador, la cadena se detiene. As\u00ed que aseg\u00farate de declarar \/user\/:userId antes de \/user\/. La vinculaci\u00f3n de rutas usa regex, encontrar\u00e1s ejemplos en la secci\u00f3n <a href=\"https:\/\/ratpack.io\/manual\/current\/api\/ratpack\/handling\/Chain.html\">Cadena<\/a> documentaci\u00f3n.<\/p>\n<p>Llamada al <code>ruta<\/code> me permite dar el path regex y un handler como argumento. En el Handler empiezo obteniendo el repositorio Couchbase y el userId de los tokens de la ruta. Luego llamo al m\u00e9todo <a href=\"https:\/\/ratpack.io\/manual\/current\/api\/ratpack\/handling\/ByMethodSpec.html\">byMethod<\/a> para definir una funci\u00f3n para cada verbo HTTP que necesito soportar. Aqu\u00ed devolver\u00e9 un usuario para GET, actualizar\u00e9 o crear\u00e9 un usuario para PUT y eliminar\u00e9 el usuario para REMOVE.<\/p>\n<p>El verbo m\u00e1s interesante aqu\u00ed es PUT, ya que requiere contenido de la solicitud. El contexto <code>analizar<\/code> toma un m\u00e9todo <a href=\"https:\/\/ratpack.io\/manual\/current\/api\/ratpack\/parse\/Parse.html\">Analice<\/a> como argumento y devuelve una Promise. Aqu\u00ed quiero parsear el JSON de la petici\u00f3n y mapearlo a un objeto User. As\u00ed que devuelve una Promise. Como soy usuario de RxJava mapeo esa Promise a un Observable, luego mapeo el objeto User a un EntityDocument para finalmente guardarlo en el repositorio de Couchbase. Luego convierto ese observable de nuevo en una promesa ratpack y env\u00edo de vuelta una simple cadena OK. Puede que quieras hacer algo m\u00e1s inteligente en casos reales :)<\/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>Una vez implementados los verbos HTTP que necesitan un userId, puedo terminar con todos los dem\u00e1s. Y puedo hacerlo f\u00e1cilmente con el m\u00e9todo <code>todos<\/code>. Aqu\u00ed obtengo el repositorio y el bucket del registro. Luego para el m\u00e9todo GET, como no tiene id de usuario, devuelvo la lista completa de Usuarios. Para ello ejecuto una consulta b\u00e1sica N1QL. Finalmente el POST es id\u00e9ntico al 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>Puede que no sea una API totalmente RESTFUL, pero deber\u00eda darte una buena idea de lo f\u00e1cil que es crear una con Ratpack, Couchbase y RxJava. Por favor, h\u00e1zmelo saber si quieres ver m\u00e1s cosas sucediendo alrededor de Ratpack, como un M\u00f3dulo Couchbase.<\/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 v25.9 (Yoast SEO v25.9) - 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\/es\/crud-rest-api-couchbase-rxjava-ratpack\/\" \/>\n<meta property=\"og:locale\" content=\"es_MX\" \/>\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\/es\/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\":\"es\",\"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\":\"es\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/www.couchbase.com\/blog\/crud-rest-api-couchbase-rxjava-ratpack\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"es\",\"@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\":\"es\"},{\"@type\":\"Organization\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/#organization\",\"name\":\"The Couchbase Blog\",\"url\":\"https:\/\/www.couchbase.com\/blog\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"es\",\"@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\":\"es\",\"@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\/es\/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\/es\/crud-rest-api-couchbase-rxjava-ratpack\/","og_locale":"es_MX","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\/es\/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":"es","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":"es","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.couchbase.com\/blog\/crud-rest-api-couchbase-rxjava-ratpack\/"]}]},{"@type":"ImageObject","inLanguage":"es","@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":"El blog de Couchbase","description":"Couchbase, la base de datos 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":"es"},{"@type":"Organization","@id":"https:\/\/www.couchbase.com\/blog\/#organization","name":"El blog de Couchbase","url":"https:\/\/www.couchbase.com\/blog\/","logo":{"@type":"ImageObject","inLanguage":"es","@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":"es","@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 es un metalero empoll\u00f3n que vive en Par\u00eds. Principalmente escribe c\u00f3digo en Java y texto estructurado en AsciiDoc, y a menudo habla sobre datos, programaci\u00f3n reactiva y otras cosas de moda. Tambi\u00e9n fue Developer Advocate de Clever Cloud y Nuxeo, donde dedic\u00f3 su tiempo y experiencia a ayudar a esas comunidades a crecer y fortalecerse. Ahora dirige las relaciones con los desarrolladores en 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\/es\/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 es un metalero empoll\u00f3n que vive en Par\u00eds. Principalmente escribe c\u00f3digo en Java y texto estructurado en AsciiDoc, y a menudo habla sobre datos, programaci\u00f3n reactiva y otras cosas de moda. Tambi\u00e9n fue Developer Advocate de Clever Cloud y Nuxeo, donde dedic\u00f3 su tiempo y experiencia a ayudar a esas comunidades a crecer y fortalecerse. Ahora dirige las relaciones con los desarrolladores en Couchbase."}],"_links":{"self":[{"href":"https:\/\/www.couchbase.com\/blog\/es\/wp-json\/wp\/v2\/posts\/2240","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.couchbase.com\/blog\/es\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.couchbase.com\/blog\/es\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/es\/wp-json\/wp\/v2\/users\/49"}],"replies":[{"embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/es\/wp-json\/wp\/v2\/comments?post=2240"}],"version-history":[{"count":0,"href":"https:\/\/www.couchbase.com\/blog\/es\/wp-json\/wp\/v2\/posts\/2240\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/es\/wp-json\/wp\/v2\/media\/13873"}],"wp:attachment":[{"href":"https:\/\/www.couchbase.com\/blog\/es\/wp-json\/wp\/v2\/media?parent=2240"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/es\/wp-json\/wp\/v2\/categories?post=2240"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/es\/wp-json\/wp\/v2\/tags?post=2240"},{"taxonomy":"author","embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/es\/wp-json\/wp\/v2\/ppma_author?post=2240"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}