{"id":2320,"date":"2016-07-05T11:24:12","date_gmt":"2016-07-05T11:24:12","guid":{"rendered":"https:\/\/www.couchbase.com\/blog\/?p=2320"},"modified":"2019-05-07T02:40:56","modified_gmt":"2019-05-07T09:40:56","slug":"give-some-ratpack-love-to-your-spring-boot-application","status":"publish","type":"post","link":"https:\/\/www.couchbase.com\/blog\/pt\/give-some-ratpack-love-to-your-spring-boot-application\/","title":{"rendered":"D\u00ea um pouco de amor do Ratpack ao seu aplicativo Spring Boot"},"content":{"rendered":"<p>Recentemente, comecei a trabalhar com o Ratpack e estou gostando bastante. Na maioria das vezes, fiz projetos r\u00e1pidos do zero. Mas gostaria de us\u00e1-lo em um aplicativo Spring Boot existente para substituir a parte tradicional do MVC. Na verdade, isso \u00e9 f\u00e1cil de fazer, pois tudo j\u00e1 foi pensado gra\u00e7as ao <a href=\"https:\/\/ratpack.io\/manual\/current\/spring.html\">M\u00f3dulo de mola<\/a>.<\/p>\n<p>Se voc\u00ea acompanha este blog, talvez se lembre de uma postagem antiga sobre <a href=\"https:\/\/www.couchbase.com\/blog\/pt\/storing-indexing-searching-files-couchbase-spring-boot\/\">armazenamento, indexa\u00e7\u00e3o e pesquisa<\/a> arquivos com <a href=\"https:\/\/developer.couchbase.com\/?utm_source=blogs&amp;utm_medium=link&amp;utm_campaign=blogs\">Couchbase<\/a> e Spring Boot. Usarei o <a href=\"https:\/\/github.com\/ldoguin\/store-search-files\">c\u00f3digo relacionado<\/a> como exemplo. A ideia \u00e9 substituir o Spring MVC pelo Ratpack e tornar meus servi\u00e7os legados, s\u00edncronos e bloqueadores, ass\u00edncronos e n\u00e3o bloqueadores. O c\u00f3digo resultante est\u00e1 dispon\u00edvel em <a href=\"https:\/\/github.com\/ldoguin\/store-search-files\">github<\/a> tamb\u00e9m.<\/p>\n<h2>Adi\u00e7\u00e3o das depend\u00eancias corretas<\/h2>\n<p>Estou usando o Gradle. O Ratpack \u00e9 muito bem integrado a ele. Tudo o que voc\u00ea precisa fazer para adicionar um m\u00f3dulo \u00e9 adicionar a depend\u00eancia correta chamando <code>ratpack.dependency(\"myFavoriteModule\")<\/code>. Portanto, em nosso caso, para adicionar suporte ao Spring Boot, voc\u00ea precisa adicionar <code>ratpack.dependency(\"spring-boot\")<\/code>. Infelizmente, a vers\u00e3o gerenciada automaticamente pelo Ratpack \u00e9 inferior a 1.4.0.M3, que \u00e9 a vers\u00e3o que traz a configura\u00e7\u00e3o autom\u00e1tica do Couchbase. Portanto, desta vez terei que adicionar as depend\u00eancias manualmente.<\/p>\n<pre><code>    dependencies {\r\n      compile ratpack.dependency(\"guice\"),\r\n              ratpack.dependency(\"rx\"),\r\n              ratpack.dependency(\"handlebars\"),\r\n              \"com.couchbase.client:java-client:2.3.1\",\r\n              \"org.springframework.boot:spring-boot-autoconfigure:1.4.0.M3\",\r\n              \"io.ratpack:ratpack-spring-boot:1.3.3\",\r\n              \"org.slf4j:slf4j-simple:1.7.12\",\r\n              \"org.codehaus.plexus:plexus-utils:3.0.21\",\r\n              \"commons-codec:commons-codec:1.10\" \r\n    }\r\n<\/code><\/pre>\n<p>O que voc\u00ea pode ver aqui \u00e9 que <code>ratpack.dependency(\"spring-boot\")<\/code> \u00e9 um atalho para adicionar <code>org.springframework.boot:spring-boot-autoconfigure:1.4.0.M3<\/code> e <code>io.ratpack:ratpack-spring-boot:1.3.3<\/code>. O que este m\u00f3dulo oferece a voc\u00ea \u00e9 a capacidade de integrar um servidor Ratpack ao seu aplicativo Spring. Voc\u00ea poder\u00e1 recuperar o Spring @Beans do contexto do Ratpack e declarar manipuladores como configura\u00e7\u00e3o do Spring.<\/p>\n<h2>Declarar a configura\u00e7\u00e3o do Ratpack<\/h2>\n<p>Uma coisa que voc\u00ea deve adorar no Spring Boot \u00e9 a configura\u00e7\u00e3o autom\u00e1tica. Voc\u00ea s\u00f3 precisa ter certeza de que o SDK do Couchbase est\u00e1 no classpath e que a propriedade <code>spring.couchbase.bootstrap-hosts<\/code> \u00e9 declarado. Nesse momento, os Spring beans ser\u00e3o instanciados para um Bucket padr\u00e3o. E essa inst\u00e2ncia do bucket estar\u00e1 dispon\u00edvel como um bean ou no contexto do Ratpack. Portanto, voc\u00ea n\u00e3o precisa declarar nenhuma liga\u00e7\u00e3o para o Couchbase na camada do Ratpack.<\/p>\n<p>A primeira coisa que voc\u00ea tradicionalmente faz com o Ratpack \u00e9 iniciar um servidor e definir a configura\u00e7\u00e3o e os manipuladores. Aqui j\u00e1 temos um aplicativo Spring Boot em execu\u00e7\u00e3o. Todas as classes anotadas com @Configuration ser\u00e3o coletadas automaticamente e adicionadas \u00e0 configura\u00e7\u00e3o do aplicativo. A primeira etapa para declarar essa configura\u00e7\u00e3o \u00e9 criar uma classe que implemente <em>RatpackServerCustomizer<\/em> e anot\u00e1-lo com @Confguration. Isso permite que voc\u00ea defina uma lista de manipuladores, associa\u00e7\u00f5es e configura\u00e7\u00e3o do servidor. No exemplo a seguir, estou registrando algumas propriedades do servidor e vinculando v\u00e1rias classes ao contexto do Ratpack. A propriedade 'server.maxContentLength' \u00e9 o tamanho m\u00e1ximo do arquivo que voc\u00ea pode carregar.<\/p>\n<pre><code>    package org.couchbase.devex;\r\n\r\n    import java.util.ArrayList;\r\n    import java.util.Collections;\r\n    import java.util.List;\r\n    import java.util.Map;\r\n\r\n    import org.couchbase.devex.domain.StoredFileRenderer;\r\n    import org.couchbase.devex.service.SearchService;\r\n    import org.springframework.context.annotation.Configuration;\r\n\r\n    import com.google.common.collect.ImmutableMap;\r\n\r\n    import ratpack.form.Form;\r\n    import ratpack.func.Action;\r\n    import ratpack.guice.BindingsSpec;\r\n    import ratpack.handlebars.HandlebarsModule;\r\n    import ratpack.handlebars.Template;\r\n    import ratpack.handling.Chain;\r\n    import ratpack.rx.RxRatpack;\r\n    import ratpack.server.BaseDir;\r\n    import ratpack.server.ServerConfigBuilder;\r\n    import ratpack.spring.config.RatpackServerCustomizer;\r\n    import rx.Observable;\r\n\r\n    @Configuration\r\n    public class RatpackConfiguration implements RatpackServerCustomizer {\r\n\r\n        @Override\r\n        public List&lt;action&gt; getHandlers() {\r\n            List&lt;action&gt; handlers = new ArrayList&lt;action&gt;();\r\n            handlers.add(fileApi());\r\n            return handlers;\r\n        }\r\n\r\n        @Override\r\n        public Action getServerConfig() {\r\n            return config -&gt; config.baseDir(BaseDir.find())\r\n                    .props(ImmutableMap.of(\"server.maxContentLength\", \"100000000\", \"app.name\", \"Search Store File\"));\r\n\r\n        }\r\n\r\n        @Override\r\n        public Action getBindings() {\r\n            return bindingConfig -&gt; bindingConfig.module(HandlebarsModule.class).bind(FileHandler.class)\r\n                    .bind(StoredFileRenderer.class).bind(ErrorHandlerImpl.class).bind(ClientHandlerImpl.class);\r\n        }\r\n\r\n        private Action fileApi() {\r\n            return chain -&gt; chain.prefix(\"file\", FileHandler.class).post(\"fulltext\", ctx -&gt; {\r\n                ctx.parse(Form.class).then(form -&gt; {\r\n                    String queryString = form.get(\"queryString\");\r\n                    SearchService searchService = ctx.get(SearchService.class);\r\n                    Observable&lt;map&lt;string, object=\"\"&gt;&gt; files = searchService.searchFulltextFiles(queryString);\r\n                    RxRatpack.promise(files).then(response -&gt; ctx\r\n                            .render(Template.handlebarsTemplate(\"uploadForm\", \"text\/html\", m -&gt; m.put(\"files\", response))));\r\n                });\r\n            }).post(\"n1ql\", ctx -&gt; {\r\n                ctx.parse(Form.class).then(form -&gt; {\r\n                    String queryString = form.get(\"queryString\");\r\n                    SearchService searchService = ctx.get(SearchService.class);\r\n                    Observable&lt;map&lt;string, object=\"\"&gt;&gt; files = searchService.searchN1QLFiles(queryString);\r\n                    RxRatpack.promise(files).then(response -&gt; ctx\r\n                            .render(Template.handlebarsTemplate(\"uploadForm\", \"text\/html\", m -&gt; m.put(\"files\", response))));\r\n                });\r\n            });\r\n        }\r\n    }\r\n&lt;\/map&lt;string,&gt;&lt;\/map&lt;string,&gt;&lt;\/action&lt;\/action&lt;\/action<\/code><\/pre>\n<p>O sistema de modelos de aplicativos depende do Handlebars, portanto, voc\u00ea precisa do HandlebarsModule. O FileHandler tratar\u00e1 de todas as chamadas para a API '\/file' e o StoredFileRenderer garantir\u00e1 que o StoredFile seja renderizado corretamente. As duas \u00faltimas associa\u00e7\u00f5es s\u00e3o para gerenciamento de erros.<\/p>\n<p>A coisa mais importante que est\u00e1 acontecendo aqui \u00e9 a <code>fileAPI<\/code> que declara meu manipulador. Um manipulador define o que acontece quando um usu\u00e1rio acessa um determinado URL. Aqui associamos todas as chamadas '\/file\/*' \u00e0 classe FileHandler. Tamb\u00e9m definimos o comportamento para POST em '\/fulltext' e '\/n1ql'.<\/p>\n<p>O Ratpack usa promessas. Portanto, quando voc\u00ea analisa um formul\u00e1rio proveniente de uma solicita\u00e7\u00e3o POST, obt\u00e9m uma promessa. O que voc\u00ea pode ver em cada um desses POST \u00e9 que o SearchService \u00e9 obtido do contexto do Ratpack. Mesmo que ele nunca tenha sido vinculado na configura\u00e7\u00e3o. Isso ocorre porque os Spring beans est\u00e3o dispon\u00edveis no contexto como parte da integra\u00e7\u00e3o.<\/p>\n<p>A pr\u00f3xima etapa \u00e9 chamar esse servi\u00e7o de pesquisa que retorna um Observable. Podemos usar o m\u00f3dulo rx-java do Ratpack que fornece um wrapper para Observables. Ele envolver\u00e1 isso como uma promessa. Em seguida, voc\u00ea pode simplesmente renderizar a resposta.<\/p>\n<p>Nesse ponto, nos livramos de todos os arquivos Spring MVC <a href=\"https:\/\/github.com\/ldoguin\/store-search-files\/blob\/master\/src\/main\/java\/org\/couchbase\/devex\/controller\/IndexController.java\">controladores<\/a>. Como voc\u00ea pode ver, meu servi\u00e7o retorna um Observable. O que n\u00e3o \u00e9 o caso em meu aplicativo anterior.<\/p>\n<h2>Migra\u00e7\u00e3o de servi\u00e7os para o Ratpack<\/h2>\n<p>A maioria dos meus servi\u00e7os depende do Couchbase. O SDK \u00e9 baseado no RxJava, portanto, \u00e9 muito f\u00e1cil converter a maioria deles em um modo ass\u00edncrono e sem bloqueio e fazer com que retornem Observable.<\/p>\n<h3>Usando o RxJava<\/h3>\n<p>Este \u00e9 um exemplo muito simples. \u00c9 uma consulta N1QL que mapeia os resultados para uma lista de mapas. As duas primeiras linhas n\u00e3o mudam em nada, pois est\u00e3o definindo principalmente a consulta. Voc\u00ea pode ver que o mapeamento parece mais natural quando se usa o bucket s\u00edncrono na segunda vers\u00e3o.<\/p>\n<pre><code>    public List&lt;map&lt;string, object=\"\"&gt;&gt; searchN1QLFiles(String whereClause) {\r\n        N1qlQuery query = N1qlQuery.simple(\r\n                \"SELECT binaryStoreLocation, binaryStoreDigest FROM `default` WHERE type= 'file' \" + whereClause);\r\n        query.params().consistency(ScanConsistency.STATEMENT_PLUS);\r\n        N1qlQueryResult res = bucket.query(query);\r\n        List&lt;map&lt;string, object=\"\"&gt;&gt; filenames = res.allRows().stream().map(row -&gt; row.value().toMap())\r\n                .collect(Collectors.toList());\r\n        return filenames;\r\n    }\r\n&lt;\/map&lt;string,&gt;&lt;\/map&lt;string,&gt;<\/code><\/pre>\n<p>Torna-se<\/p>\n<pre><code>    public Observable&lt;map&lt;string, object=\"\"&gt;&gt; searchN1QLFiles(String whereClause) {\r\n        N1qlQuery query = N1qlQuery.simple(\r\n                \"SELECT binaryStoreLocation, binaryStoreDigest FROM `default` WHERE type= 'file' \" + whereClause);\r\n        query.params().consistency(ScanConsistency.STATEMENT_PLUS);\r\n        return bucket.async().query(query).flatMap(AsyncN1qlQueryResult::rows).map(r -&gt; r.value().toMap());\r\n    }\r\n&lt;\/map&lt;string,&gt;<\/code><\/pre>\n<h3>E quanto ao bloqueio de c\u00f3digo legado?<\/h3>\n<p>Alguns dos meus servi\u00e7os dependem de c\u00f3digo antigo e bloqueador. Embora n\u00e3o exista uma maneira m\u00e1gica de torn\u00e1-los n\u00e3o bloqueantes, podemos facilmente envolv\u00ea-los em uma Promise. Isso nos permitir\u00e1 us\u00e1-las facilmente nos manipuladores. Envolver a chamada de bloqueio \u00e9 muito f\u00e1cil, tudo o que voc\u00ea precisa fazer \u00e9 envolver sua fun\u00e7\u00e3o com \"Blocking.get()\". Aqui est\u00e1 um exemplo muito simples:<\/p>\n<pre><code>    public String getSha1Digest(InputStream is) {\r\n        return DigestUtils.sha1Hex(is);\r\n    }\r\n<\/code><\/pre>\n<p>torna-se<\/p>\n<pre><code>    public Promise getSha1Digest(InputStream is) {\r\n        return Blocking.get(() -&gt; DigestUtils.sha1Hex(is));\r\n    }\r\n<\/code><\/pre>\n<h2>Conclus\u00e3o<\/h2>\n<p>Agora voc\u00ea sabe praticamente tudo o que precisa saber para dar um pouco de Ratpack Love ao seu aplicativo Spring Boot. Se achar que est\u00e1 faltando alguma coisa, entre em contato comigo em <a href=\"https:\/\/twitter.com\/ldoguin\">twitter<\/a> ou nos coment\u00e1rios abaixo.<\/p>","protected":false},"excerpt":{"rendered":"<p>I recently started working with Ratpack and I quite like it. I mostly did quick projects from scratch. But I would like to use it in an existing Spring Boot application to replace the traditional MVC part. This is actually [&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":[1815,1818],"tags":[],"ppma_author":[9023],"class_list":["post-2320","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-best-practices-and-tutorials","category-java"],"acf":[],"yoast_head":"<!-- This site is optimized with the Yoast SEO Premium plugin v26.1 (Yoast SEO v26.1.1) - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<title>Get start working with Ratpack - The Couchbase Blog<\/title>\n<meta name=\"description\" content=\"The idea used here in the post is to replace Spring MVC by Ratpack, and making my legacy, synchronous, blocking services async and non blocking.\" \/>\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\/give-some-ratpack-love-to-your-spring-boot-application\/\" \/>\n<meta property=\"og:locale\" content=\"pt_BR\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Give some Ratpack Love to your Spring Boot Application\" \/>\n<meta property=\"og:description\" content=\"The idea used here in the post is to replace Spring MVC by Ratpack, and making my legacy, synchronous, blocking services async and non blocking.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.couchbase.com\/blog\/pt\/give-some-ratpack-love-to-your-spring-boot-application\/\" \/>\n<meta property=\"og:site_name\" content=\"The Couchbase Blog\" \/>\n<meta property=\"article:published_time\" content=\"2016-07-05T11:24:12+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2019-05-07T09:40:56+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/2022\/11\/couchbase-nosql-dbaas.png\" \/>\n\t<meta property=\"og:image:width\" content=\"1800\" \/>\n\t<meta property=\"og:image:height\" content=\"630\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/png\" \/>\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=\"7 minutos\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/give-some-ratpack-love-to-your-spring-boot-application\/#article\",\"isPartOf\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/give-some-ratpack-love-to-your-spring-boot-application\/\"},\"author\":{\"name\":\"Laurent Doguin\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/#\/schema\/person\/c0aa9b8f1ed51b7a9e2f7cb755994a5e\"},\"headline\":\"Give some Ratpack Love to your Spring Boot Application\",\"datePublished\":\"2016-07-05T11:24:12+00:00\",\"dateModified\":\"2019-05-07T09:40:56+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/give-some-ratpack-love-to-your-spring-boot-application\/\"},\"wordCount\":853,\"commentCount\":0,\"publisher\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/#organization\"},\"image\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/give-some-ratpack-love-to-your-spring-boot-application\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2022\/11\/couchbase-nosql-dbaas.png\",\"articleSection\":[\"Best Practices and Tutorials\",\"Java\"],\"inLanguage\":\"pt-BR\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\/\/www.couchbase.com\/blog\/give-some-ratpack-love-to-your-spring-boot-application\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/give-some-ratpack-love-to-your-spring-boot-application\/\",\"url\":\"https:\/\/www.couchbase.com\/blog\/give-some-ratpack-love-to-your-spring-boot-application\/\",\"name\":\"Get start working with Ratpack - The Couchbase Blog\",\"isPartOf\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/give-some-ratpack-love-to-your-spring-boot-application\/#primaryimage\"},\"image\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/give-some-ratpack-love-to-your-spring-boot-application\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2022\/11\/couchbase-nosql-dbaas.png\",\"datePublished\":\"2016-07-05T11:24:12+00:00\",\"dateModified\":\"2019-05-07T09:40:56+00:00\",\"description\":\"The idea used here in the post is to replace Spring MVC by Ratpack, and making my legacy, synchronous, blocking services async and non blocking.\",\"breadcrumb\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/give-some-ratpack-love-to-your-spring-boot-application\/#breadcrumb\"},\"inLanguage\":\"pt-BR\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/www.couchbase.com\/blog\/give-some-ratpack-love-to-your-spring-boot-application\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"pt-BR\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/give-some-ratpack-love-to-your-spring-boot-application\/#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\/give-some-ratpack-love-to-your-spring-boot-application\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/www.couchbase.com\/blog\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Give some Ratpack Love to your Spring Boot Application\"}]},{\"@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":"Get start working with Ratpack - The Couchbase Blog","description":"A ideia usada aqui na postagem \u00e9 substituir o Spring MVC pelo Ratpack e tornar meus servi\u00e7os legados, s\u00edncronos e bloqueadores, ass\u00edncronos e n\u00e3o bloqueadores.","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\/give-some-ratpack-love-to-your-spring-boot-application\/","og_locale":"pt_BR","og_type":"article","og_title":"Give some Ratpack Love to your Spring Boot Application","og_description":"The idea used here in the post is to replace Spring MVC by Ratpack, and making my legacy, synchronous, blocking services async and non blocking.","og_url":"https:\/\/www.couchbase.com\/blog\/pt\/give-some-ratpack-love-to-your-spring-boot-application\/","og_site_name":"The Couchbase Blog","article_published_time":"2016-07-05T11:24:12+00:00","article_modified_time":"2019-05-07T09:40:56+00:00","og_image":[{"width":1800,"height":630,"url":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/2022\/11\/couchbase-nosql-dbaas.png","type":"image\/png"}],"author":"Laurent Doguin","twitter_card":"summary_large_image","twitter_creator":"@ldoguin","twitter_misc":{"Written by":"unstructured.io","Est. reading time":"7 minutos"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/www.couchbase.com\/blog\/give-some-ratpack-love-to-your-spring-boot-application\/#article","isPartOf":{"@id":"https:\/\/www.couchbase.com\/blog\/give-some-ratpack-love-to-your-spring-boot-application\/"},"author":{"name":"Laurent Doguin","@id":"https:\/\/www.couchbase.com\/blog\/#\/schema\/person\/c0aa9b8f1ed51b7a9e2f7cb755994a5e"},"headline":"Give some Ratpack Love to your Spring Boot Application","datePublished":"2016-07-05T11:24:12+00:00","dateModified":"2019-05-07T09:40:56+00:00","mainEntityOfPage":{"@id":"https:\/\/www.couchbase.com\/blog\/give-some-ratpack-love-to-your-spring-boot-application\/"},"wordCount":853,"commentCount":0,"publisher":{"@id":"https:\/\/www.couchbase.com\/blog\/#organization"},"image":{"@id":"https:\/\/www.couchbase.com\/blog\/give-some-ratpack-love-to-your-spring-boot-application\/#primaryimage"},"thumbnailUrl":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2022\/11\/couchbase-nosql-dbaas.png","articleSection":["Best Practices and Tutorials","Java"],"inLanguage":"pt-BR","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/www.couchbase.com\/blog\/give-some-ratpack-love-to-your-spring-boot-application\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/www.couchbase.com\/blog\/give-some-ratpack-love-to-your-spring-boot-application\/","url":"https:\/\/www.couchbase.com\/blog\/give-some-ratpack-love-to-your-spring-boot-application\/","name":"Get start working with Ratpack - The Couchbase Blog","isPartOf":{"@id":"https:\/\/www.couchbase.com\/blog\/#website"},"primaryImageOfPage":{"@id":"https:\/\/www.couchbase.com\/blog\/give-some-ratpack-love-to-your-spring-boot-application\/#primaryimage"},"image":{"@id":"https:\/\/www.couchbase.com\/blog\/give-some-ratpack-love-to-your-spring-boot-application\/#primaryimage"},"thumbnailUrl":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2022\/11\/couchbase-nosql-dbaas.png","datePublished":"2016-07-05T11:24:12+00:00","dateModified":"2019-05-07T09:40:56+00:00","description":"A ideia usada aqui na postagem \u00e9 substituir o Spring MVC pelo Ratpack e tornar meus servi\u00e7os legados, s\u00edncronos e bloqueadores, ass\u00edncronos e n\u00e3o bloqueadores.","breadcrumb":{"@id":"https:\/\/www.couchbase.com\/blog\/give-some-ratpack-love-to-your-spring-boot-application\/#breadcrumb"},"inLanguage":"pt-BR","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.couchbase.com\/blog\/give-some-ratpack-love-to-your-spring-boot-application\/"]}]},{"@type":"ImageObject","inLanguage":"pt-BR","@id":"https:\/\/www.couchbase.com\/blog\/give-some-ratpack-love-to-your-spring-boot-application\/#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\/give-some-ratpack-love-to-your-spring-boot-application\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/www.couchbase.com\/blog\/"},{"@type":"ListItem","position":2,"name":"Give some Ratpack Love to your Spring Boot Application"}]},{"@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\/2320","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=2320"}],"version-history":[{"count":0,"href":"https:\/\/www.couchbase.com\/blog\/pt\/wp-json\/wp\/v2\/posts\/2320\/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=2320"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/pt\/wp-json\/wp\/v2\/categories?post=2320"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/pt\/wp-json\/wp\/v2\/tags?post=2320"},{"taxonomy":"author","embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/pt\/wp-json\/wp\/v2\/ppma_author?post=2320"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}