{"id":229,"date":"2014-12-16T17:38:22","date_gmt":"2014-12-16T17:38:21","guid":{"rendered":"https:\/\/www.couchbase.com\/blog\/why-couchbase-chose-rxjava-new-java-sdk\/"},"modified":"2014-12-16T17:38:22","modified_gmt":"2014-12-16T17:38:21","slug":"why-couchbase-chose-rxjava-new-java-sdk","status":"publish","type":"post","link":"https:\/\/www.couchbase.com\/blog\/pt\/why-couchbase-chose-rxjava-new-java-sdk\/","title":{"rendered":"Por que o Couchbase escolheu o RxJava para o novo SDK Java"},"content":{"rendered":"<p class=\"wp-block-paragraph\">Esta postagem do blog explica nossos motivos e motiva\u00e7\u00e3o por tr\u00e1s da escolha do RxJava como um dos componentes integrais do nosso novo SDK Java.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Motiva\u00e7\u00e3o<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">H\u00e1 muitas maneiras de projetar uma API e cada uma tem seu pr\u00f3prio conjunto de benef\u00edcios (e desvantagens). No processo de cria\u00e7\u00e3o de nossas novas APIs, uma das principais perguntas era como exp\u00f4-la ao usu\u00e1rio.\u00a0<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Uma pergunta que n\u00e3o precis\u00e1vamos nos fazer era: deve ser s\u00edncrono ou ass\u00edncrono? Acreditamos firmemente que APIs ass\u00edncronas s\u00e3o a \u00fanica maneira sensata de obter o desempenho e a escalabilidade de que voc\u00ea frequentemente precisa, e tamb\u00e9m \u00e9 muito mais f\u00e1cil ir de ass\u00edncrono para s\u00edncrono do que o contr\u00e1rio. O SDK est\u00e1vel atual (1.4.3 no momento em que escrevo) j\u00e1 faz uso intenso de Futures de v\u00e1rias maneiras para fornecer respostas ass\u00edncronas, e isso remonta a 2006\/7, quando o spymemcached introduziu originalmente o conceito em sua API.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\u00c9 bem sabido que a interface Future do Java \u00e9 muito limitada em compara\u00e7\u00e3o com outras solu\u00e7\u00f5es (como os futures do Scala). Al\u00e9m disso, tamb\u00e9m \u00e9 um pouco mais complicado programar se voc\u00ea precisar construir fluxos de dados ass\u00edncronos onde uma computa\u00e7\u00e3o depende da outra e voc\u00ea quer que tudo seja ass\u00edncrono. Em vers\u00f5es recentes, adicionamos suporte a ouvintes, o que melhora bastante a situa\u00e7\u00e3o, mas ainda n\u00e3o \u00e9 uma solu\u00e7\u00e3o ideal.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Ao longo dos \u00faltimos anos, outras bibliotecas e padr\u00f5es surgiram, os quais acompanhamos de perto. Um dos conceitos maduros \u00e9 conhecido como Reactive Extensions, originado na Microsoft e no .NET. Ele se baseia na ideia de que as aplica\u00e7\u00f5es devem ser orientadas a eventos e reagir a esses eventos de maneira ass\u00edncrona. Ele define um conjunto muito rico de operadores sobre o que voc\u00ea pode fazer com os dados (modific\u00e1-los, combin\u00e1-los, filtr\u00e1-los e assim por diante). Recentemente, a Netflix o portou para o Java e o apelidou de RxJava (observe que, embora o projeto atualmente viva sob o namespace da Netflix, ele ser\u00e1 movido para \u201cio.reactivex\u201d mais cedo ou mais tarde). Ele \u00e9 muito est\u00e1vel e tamb\u00e9m fornece adaptadores para outras linguagens da JVM, como Scala, Groovy e JRuby, o que se alinha bem com nossos planos de ampliar o suporte tamb\u00e9m.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">O Conceito<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">A ideia principal do Rx gira em torno de Observables e seus observadores. Se voc\u00ea ainda n\u00e3o se deparou com esse conceito, pode pensar no Observable como o primo ass\u00edncrono e baseado em push (ou, mais formalmente, um dual) de um Iterable. Mais especificamente, aqui est\u00e1 a rela\u00e7\u00e3o entre eles:<\/p>\n\n\n\n<figure class=\"wp-block-table\"><table border=\"1\" cellpadding=\"1\" cellspacing=\"1\">\n<thead>\n<tr>\n<th scope=\"col\">Evento<\/th>\n<th scope=\"col\">Iter\u00e1vel (pull)<\/th>\n<th scope=\"col\">Observ\u00e1vel (push)<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td>recuperar dados<\/td>\n<td>T next()<\/td>\n<td>onNext(T)<\/td>\n<\/tr>\n<tr>\n<td>encontrar erro<\/td>\n<td>lan\u00e7a uma exce\u00e7\u00e3o<\/td>\n<td>onError(Exception)<\/td>\n<\/tr>\n<tr>\n<td>conclu\u00eddo<\/td>\n<td>devolu\u00e7\u00f5es<\/td>\n<td>onCompleted()<\/td>\n<\/tr>\n<\/tbody>\n<\/table><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">Toda vez que os dados s\u00e3o enviados para um Observable, cada observe que est\u00e1 inscrito nele recebe os dados em seu m\u00e9todo onNext(). Se o observ\u00e1vel for conclu\u00eddo eventualmente (o que n\u00e3o precisa ser sempre o caso), o m\u00e9todo onCompleted \u00e9 chamado. Agora, em qualquer lugar do processo, se ocorrer um erro, o m\u00e9todo onError \u00e9 chamado e o Observable tamb\u00e9m \u00e9 considerado conclu\u00eddo.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Se voc\u00ea gosta de gram\u00e1tica, o contrato se parece com isto:\u00a0<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">OnNext* (OnCompleted | OnError)?<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Observe especificamente que n\u00e3o h\u00e1 distin\u00e7\u00e3o se apenas 1 ou N dados s\u00e3o retornados, isso pode ser normalmente inferido a partir dos m\u00e9todos que voc\u00ea chama e de como ele est\u00e1 documentado. Isso n\u00e3o altera seu fluxo de programa\u00e7\u00e3o de qualquer maneira. Visto que isso \u00e9 um pouco abstrato, vamos ver um exemplo concreto. Na classe CouchbaseCluster, existe um m\u00e9todo chamado openBucket que inicializa todos os recursos necess\u00e1rios e ent\u00e3o retorna uma inst\u00e2ncia de Bucket para voc\u00ea trabalhar. Agora voc\u00ea pode imaginar que abrir sockets, obter uma configura\u00e7\u00e3o e assim por diante leva algum tempo, ent\u00e3o este \u00e9 um candidato perfeito. A API de bloqueio se pareceria com:<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">interface Cluster {<br>\u00a0 \u00a0 \u00a0 \u00a0 Bucket openBucket(String name, String password);<br>}<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Como podemos torn\u00e1-lo ass\u00edncrono? Precisamos envolv\u00ea-lo em um Observable:<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">interface Cluster {<br>\u00a0 \u00a0 \u00a0 \u00a0 Observ\u00e1vel<\/p>\n\n\n\n<bucket> openBucket(String name, String password);<br>}<\/bucket>\n\n\n\n<p class=\"wp-block-paragraph\">Ent\u00e3o, agora retornamos um observ\u00e1vel que eventualmente retornar\u00e1 com uma inst\u00e2ncia de bucket que podemos usar. Vamos adicionar um observador:<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">cluster.<span>abrirBucket<\/span><span>(<\/span><span>)<\/span>.<span>Inscrever-se<\/span><span>(<\/span><span>novo<\/span> Observador<span>Balde<span>&gt;<\/span><span>(<\/span><span>)<\/span> <span>{<\/span><br>\u00a0 \u00a0 @Override<br>\u00a0 \u00a0 <span>p\u00fablico<\/span> <span>vazio<\/span> aoConcluir<span>(<\/span><span>)<\/span> <span>{<\/span><br>\u00a0 \u00a0 \u00a0 \u00a0 <a href=\"https:\/\/www.google.com\/search?hl=en&amp;q=allinurl%3Asystem+java.sun.com&amp;btnI=I%27m%20Feeling%20Lucky\"><span>Sistema<\/span><\/a>.<span>fora<\/span>.<span>println<\/span><span>(<\/span><span>\u201cObserv\u00e1vel conclu\u00eddo!\u201d<\/span><span>)<\/span><span>;<\/span><br>\u00a0 \u00a0 <span>}<\/span>\n<p>\u00a0 \u00a0 @Override<br>\u00a0 \u00a0 <span>p\u00fablico<\/span> <span>vazio<\/span> aoErro<span>(<\/span><a href=\"https:\/\/www.google.com\/search?hl=en&amp;q=allinurl%3Athrowable+java.sun.com&amp;btnI=I%27m%20Feeling%20Lucky\"><span>Lan\u00e7\u00e1vel<\/span><\/a> e<span>)<\/span> <span>{<\/span><br>\u00a0 \u00a0 \u00a0 \u00a0 <a href=\"https:\/\/www.google.com\/search?hl=en&amp;q=allinurl%3Asystem+java.sun.com&amp;btnI=I%27m%20Feeling%20Lucky\"><span>Sistema<\/span><\/a>.<span>erro<\/span>.<span>println<\/span><span>(<\/span><span>\u201cAlgo aconteceu\u201d<\/span><span>)<\/span><span>;<\/span><br>\u00a0 \u00a0 \u00a0 \u00a0 e.<span>printStackTrace<\/span><span>(<\/span><span>)<\/span><span>;<\/span><br>\u00a0 \u00a0 <span>}<\/span><\/p>\n<p>\u00a0 \u00a0 @Override<br>\u00a0 \u00a0 <span>p\u00fablico<\/span> <span>vazio<\/span> emSeguida<span>(<\/span>Balde balde<span>)<\/span> <span>{<\/span><br>\u00a0 \u00a0 \u00a0 \u00a0 <a href=\"https:\/\/www.google.com\/search?hl=en&amp;q=allinurl%3Asystem+java.sun.com&amp;btnI=I%27m%20Feeling%20Lucky\"><span>Sistema<\/span><\/a>.<span>fora<\/span>.<span>println<\/span><span>(<\/span><span>\u201cBucket recebido: \u201c<\/span> <span>+<\/span> balde<span>)<\/span><span>;<\/span><br>\u00a0 \u00a0 <span>}<\/span><br><span>}<\/span><span>)<\/span><span>;<\/span><\/p><\/span><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Observe que esses m\u00e9todos s\u00e3o chamados em uma thread diferente, ent\u00e3o, se voc\u00ea deixar o c\u00f3digo assim e encerrar sua thread principal logo em seguida, provavelmente n\u00e3o ver\u00e1 nada. Embora agora voc\u00ea possa escrever todo o resto do seu c\u00f3digo no m\u00e9todo onNext, essa provavelmente n\u00e3o \u00e9 a melhor maneira de fazer isso. Como o bucket \u00e9 algo\u00a0<br>quero abrir de forma s\u00edncrona, voc\u00ea pode bloquear nisso e ent\u00e3o prosseguir com o resto do seu c\u00f3digo. Todo Observable pode ser convertido em um observable bloqueante, o que se parece com um Iterable:<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">BlockingObservable<\/p>\n\n\n\n<bucket> blockingObservable = cluster.openBucket().toBlocking();<\/bucket>\n\n\n\n<p class=\"wp-block-paragraph\">Voc\u00ea encontrar\u00e1 muitos m\u00e9todos para iterar sobre os dados recebidos de forma bloqueante, mas tamb\u00e9m existem m\u00e9todos de Atalho se voc\u00ea espera apenas um \u00fanico valor (o que sabemos ser o nosso caso):<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Bucket bucket = cluster.openBucket().toBlocking().single();<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">O que acontece aqui internamente \u00e9 que o valor chamado em onNext \u00e9 armazenado para n\u00f3s e retornado uma vez que onComplete \u00e9 chamado. Se onError for chamado, o throwable \u00e9 lan\u00e7ado diretamente e voc\u00ea pode captur\u00e1-lo.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Unificando APIs<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Agora, o que voc\u00ea j\u00e1 viu mal arranha a superf\u00edcie. A abertura da ca\u00e7amba tamb\u00e9m poderia muito bem ser tratada com um Future<bucket> sozinho. Onde os Observables realmente brilham \u00e9 quando voc\u00ea precisa trabalhar com mais de um resultado retornado. Nesse caso, um Future<t> n\u00e3o serve mais e Futuro<collection>ou algo semelhante n\u00e3o possui o mesmo contrato. Como os Observables implicam que mais de um T pode ser retornado, as APIs podem parecer iguais mesmo que \u00e0s vezes um e \u00e0s vezes mais de um T sejam retornados.<\/collection><\/t><\/bucket><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Novamente, vamos analisar um exemplo concreto. O SDK exp\u00f5e um m\u00e9todo get que retorna um documento. Ele se parece com isto:<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">interface Bucket {<br>\u00a0 \u00a0 \u00a0 \u00a0 Observ\u00e1vel<\/p>\n\n\n\n<jsondocument> get(String id);<br>}<\/jsondocument>\n\n\n\n<p class=\"wp-block-paragraph\">Mas tamb\u00e9m oferecemos suporte a Consultas (Views, N1QL) que potencialmente retornam mais de um resultado (ou mesmo nenhum). Gra\u00e7as ao contrato do Observable, podemos construir uma API assim:<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">interface Bucket {<br>\u00a0 \u00a0 \u00a0 \u00a0 Observ\u00e1vel<\/p>\n\n\n\n<viewresult> query(ViewQuery query);<br>}<\/viewresult>\n\n\n\n<p class=\"wp-block-paragraph\">Viu? O contrato diz implicitamente \u201cse voc\u00ea passar uma consulta, voc\u00ea recebe N ViewResults de volta\u201d, j\u00e1 que voc\u00ea sabe como um Observable precisa se comportar. E, para ter uma vis\u00e3o mais ampla, aqui est\u00e3o ainda mais m\u00e9todos que se comportam intuitivamente da maneira que voc\u00ea espera.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><span>interface<\/span> Balde <span>{<\/span><br>\u00a0 \u00a0 <span>D <span>estende<\/span> Documento<span>&gt;&gt;<\/span> Observ\u00e1vel<span>D<span>&gt;<\/span> inserir<span>(<\/span>Documento D<span>)<\/span><span>;<\/span><br>\u00a0 \u00a0 <span>D <span>estende<\/span> Documento<span>&gt;&gt;<\/span> Observ\u00e1vel<span>D<span>&gt;<\/span> atualiza\u00e7\u00e3o upsert<span>(<\/span>Documento D<span>)<\/span><span>;<\/span><br>\u00a0 \u00a0 <span>D <span>estende<\/span> Documento<span>&gt;&gt;<\/span> Observ\u00e1vel<span>D<span>&gt;<\/span> substituir<span>(<\/span>Documento D<span>)<\/span><span>;<\/span>\n<p>\u00a0 \u00a0 Observ\u00e1vel<span>ResultadoDaVisualiza\u00e7\u00e3o<span>&gt;<\/span> consulta<span>(<\/span>Consulta de View<span>)<\/span><span>;<\/span><br>\u00a0 \u00a0 Observ\u00e1vel<span>Resultado da Consulta<span>&gt;<\/span> consulta<span>(<\/span>Consulta consulta<span>)<\/span><span>;<\/span><br>\u00a0 \u00a0 Observ\u00e1vel<span>Resultado da Consulta<span>&gt;<\/span> consulta<span>(<\/span><a href=\"https:\/\/www.google.com\/search?hl=en&amp;q=allinurl%3Astring+java.sun.com&amp;btnI=I%27m%20Feeling%20Lucky\"><span>String<\/span><\/a> consulta<span>)<\/span><span>;<\/span><\/span><\/span><\/span><\/p>\n<p>\u00a0 \u00a0 Observ\u00e1vel<span>Booleano<span>&gt;<\/span> descarga<span>(<\/span><span>)<\/span><span>;<\/span><br><span>}<\/span><\/span><\/p><\/span><\/span><\/span><\/span><\/span><\/span><\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Torne meu dataflow ass\u00edncrono!<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">At\u00e9 agora vimos o que os Observables podem fazer por n\u00f3s e como eles nos ajudam a fornecer APIs coesas, simples e ainda assim ass\u00edncronas. Mas os Observables realmente se destacam por seus aspectos de composibilidade. Voc\u00ea pode fazer muitas coisas com Observables, e n\u00e3o podemos cobrir todas elas nesta postagem. O RxJava possui uma documenta\u00e7\u00e3o de refer\u00eancia muito boa que pode ser encontrada aqui, ent\u00e3o d\u00ea uma olhada. Ele usa diagramas de m\u00e1rmore para mostrar como os fluxos de dados ass\u00edncronos funcionam, algo que tamb\u00e9m queremos fornecer como parte de nossa documenta\u00e7\u00e3o no futuro.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Vamos considerar um exemplo pr\u00e1tico: voc\u00ea quer carregar um documento do Couchbase (que \u00e9 um objeto JSON completo com detalhes do usu\u00e1rio), mas quer apenas fazer algo com o primeiro nome (firstname) mais adiante no seu c\u00f3digo. Podemos usar a fun\u00e7\u00e3o map para mapear do JsonDocument para a String do primeiro nome:<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">balde<br>\u00a0 \u00a0 .<span>obter<\/span><span>(<\/span><span>\u201cuser::1\u201d<\/span><span>)<\/span><br>\u00a0 \u00a0 .<span>mapa<\/span><span>(<\/span><span>novo<\/span> Func1<span>JsonDocument, String<span>&gt;<\/span><span>(<\/span><span>)<\/span> <span>{<\/span><br>\u00a0 \u00a0 \u00a0 \u00a0 @Override<br>\u00a0 \u00a0 \u00a0 \u00a0 <span>p\u00fablico<\/span> <a href=\"https:\/\/www.google.com\/search?hl=en&amp;q=allinurl%3Astring+java.sun.com&amp;btnI=I%27m%20Feeling%20Lucky\"><span>String<\/span><\/a> ligar<span>(<\/span>JsonDocument jsonDocument<span>)<\/span> <span>{<\/span><br>\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 <span>retornar<\/span> documentoJson.<span>conte\u00fado<\/span><span>(<\/span><span>)<\/span>.<span>obterString<\/span><span>(<\/span><span>\u201cnome\u201d<\/span><span>)<\/span><span>;<\/span><br>\u00a0 \u00a0 \u00a0 \u00a0 <span>}<\/span><br>\u00a0 \u00a0 <span>}<\/span><span>)<\/span><br>\u00a0 \u00a0 .<span>Inscrever-se<\/span><span>(<\/span><span>novo<\/span> A\u00e7\u00e3o 1<span>String<span>&gt;<\/span><span>(<\/span><span>)<\/span> <span>{<\/span><br>\u00a0 \u00a0 \u00a0 \u00a0 @Override<br>\u00a0 \u00a0 \u00a0 \u00a0 <span>p\u00fablico<\/span> <span>vazio<\/span> ligar<span>(<\/span><a href=\"https:\/\/www.google.com\/search?hl=en&amp;q=allinurl%3Astring+java.sun.com&amp;btnI=I%27m%20Feeling%20Lucky\"><span>String<\/span><\/a> nome<span>)<\/span> <span>{<\/span><br>\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 <a href=\"https:\/\/www.google.com\/search?hl=en&amp;q=allinurl%3Asystem+java.sun.com&amp;btnI=I%27m%20Feeling%20Lucky\"><span>Sistema<\/span><\/a>.<span>fora<\/span>.<span>println<\/span><span>(<\/span>nome<span>)<\/span><span>;<\/span><br>\u00a0 \u00a0 \u00a0 \u00a0 <span>}<\/span><br>\u00a0 \u00a0 <span>}<\/span><span>)<\/span><span>;<\/span><\/span><\/span><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">H\u00e1 dois aspectos importantes aqui: Cada m\u00e9todo encadeado aqui tamb\u00e9m \u00e9 executado de forma ass\u00edncrona, portanto, n\u00e3o est\u00e1 bloqueando a thread de origem. Assim que a chamada get para o Couchbase retorna, mapeamos o primeiro nome (firstname) do documento JSON e, finalmente, o imprimimos. Voc\u00ea n\u00e3o precisa fornecer um Observer completo; se estiver interessado apenas no valor onNext, voc\u00ea pode implementar apenas esse m\u00e9todo (como mostrado aqui). Veja os m\u00e9todos sobrecarregados para mais exemplos.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Observe tamb\u00e9m que estou mostrando deliberadamente classes an\u00f4nimas no estilo Java 6\/7 aqui. Tamb\u00e9m oferecemos suporte ao Java 8, mas falaremos mais sobre isso depois. Agora, como poder\u00edamos estender esta cadeia se quisermos apenas imprimir o nome se ele come\u00e7ar com um \u201ca\u201d?<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">balde<br>\u00a0 \u00a0 .<span>obter<\/span><span>(<\/span><span>\u201cuser::1\u201d<\/span><span>)<\/span><br>\u00a0 \u00a0 .<span>mapa<\/span><span>(<\/span><span>novo<\/span> Func1<span>JsonDocument, String<span>&gt;<\/span><span>(<\/span><span>)<\/span> <span>{<\/span><br>\u00a0 \u00a0 \u00a0 \u00a0 @Override<br>\u00a0 \u00a0 \u00a0 \u00a0 <span>p\u00fablico<\/span> <a href=\"https:\/\/www.google.com\/search?hl=en&amp;q=allinurl%3Astring+java.sun.com&amp;btnI=I%27m%20Feeling%20Lucky\"><span>String<\/span><\/a> ligar<span>(<\/span>JsonDocument jsonDocument<span>)<\/span> <span>{<\/span><br>\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 <span>retornar<\/span> documentoJson.<span>conte\u00fado<\/span><span>(<\/span><span>)<\/span>.<span>obterString<\/span><span>(<\/span><span>\u201cnome\u201d<\/span><span>)<\/span><span>;<\/span><br>\u00a0 \u00a0 \u00a0 \u00a0 <span>}<\/span><br>\u00a0 \u00a0 <span>}<\/span><span>)<\/span><br>\u00a0 \u00a0 .<span>filtro<\/span><span>(<\/span><span>novo<\/span> Func1<span><a href=\"https:\/\/www.google.com\/search?hl=en&amp;q=allinurl%3Astring+java.sun.com&amp;btnI=I%27m%20Feeling%20Lucky\"><span>String<\/span><\/a>, Booleano<span>&gt;<\/span><span>(<\/span><span>)<\/span> <span>{<\/span><br>\u00a0 \u00a0 \u00a0 \u00a0 @Override<br>\u00a0 \u00a0 \u00a0 \u00a0 <span>p\u00fablico<\/span> <a href=\"https:\/\/www.google.com\/search?hl=en&amp;q=allinurl%3Aboolean+java.sun.com&amp;btnI=I%27m%20Feeling%20Lucky\"><span>Booleano<\/span><\/a> ligar<span>(<\/span><a href=\"https:\/\/www.google.com\/search?hl=en&amp;q=allinurl%3Astring+java.sun.com&amp;btnI=I%27m%20Feeling%20Lucky\"><span>String<\/span><\/a> s<span>)<\/span> <span>{<\/span><br>\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 <span>retornar<\/span> s.<span>come\u00e7aCom<\/span><span>(<\/span><span>\u201ca\u201d<\/span><span>)<\/span><span>;<\/span><br>\u00a0 \u00a0 \u00a0 \u00a0 <span>}<\/span><br>\u00a0 \u00a0 <span>}<\/span><span>)<\/span><br>\u00a0 \u00a0 .<span>Inscrever-se<\/span><span>(<\/span><span>novo<\/span> A\u00e7\u00e3o 1<span>String<span>&gt;<\/span><span>(<\/span><span>)<\/span> <span>{<\/span><br>\u00a0 \u00a0 \u00a0 \u00a0 @Override<br>\u00a0 \u00a0 \u00a0 \u00a0 <span>p\u00fablico<\/span> <span>vazio<\/span> ligar<span>(<\/span><a href=\"https:\/\/www.google.com\/search?hl=en&amp;q=allinurl%3Astring+java.sun.com&amp;btnI=I%27m%20Feeling%20Lucky\"><span>String<\/span><\/a> nome<span>)<\/span> <span>{<\/span><br>\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 <a href=\"https:\/\/www.google.com\/search?hl=en&amp;q=allinurl%3Asystem+java.sun.com&amp;btnI=I%27m%20Feeling%20Lucky\"><span>Sistema<\/span><\/a>.<span>fora<\/span>.<span>println<\/span><span>(<\/span>nome<span>)<\/span><span>;<\/span><br>\u00a0 \u00a0 \u00a0 \u00a0 <span>}<\/span><br>\u00a0 \u00a0 <span>}<\/span><span>)<\/span><span>;<\/span><\/span><\/span><\/span><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\u00c9 claro que uma simples instru\u00e7\u00e3o if seria suficiente, mas voc\u00ea pode imaginar que seu c\u00f3digo para filtrar pode ser muito mais complexo (e provavelmente chamando outra coisa tamb\u00e9m). Como exemplo final sobre a transforma\u00e7\u00e3o de observ\u00e1veis, vamos fazer algo que acontece com muita frequ\u00eancia: voc\u00ea carrega um documento, modifica seu conte\u00fado e depois o salva de volta no couchbase:<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">balde<br>\u00a0 \u00a0 .<span>obter<\/span><span>(<\/span><span>\u201cuser::1\u201d<\/span><span>)<\/span><br>\u00a0 \u00a0 .<span>mapa<\/span><span>(<\/span><span>novo<\/span> Func1<span>JsonDocument, JsonDocument<span>&gt;<\/span><span>(<\/span><span>)<\/span> <span>{<\/span><br>\u00a0 \u00a0 \u00a0 \u00a0 @Override<br>\u00a0 \u00a0 \u00a0 \u00a0 <span>p\u00fablico<\/span> Chamada JsonDocument<span>(<\/span>JsonDocument original<span>)<\/span> <span>{<\/span><br>\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 original.<span>conte\u00fado<\/span><span>(<\/span><span>)<\/span>.<span>colocar<\/span><span>(<\/span><span>\u201cnome\u201d<\/span>, <span>\u201cAlgoDiferente\u201d<\/span><span>)<\/span><span>;<\/span><br>\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 <span>retornar<\/span> original<span>;<\/span><br>\u00a0 \u00a0 \u00a0 \u00a0 <span>}<\/span><br>\u00a0 \u00a0 <span>}<\/span><span>)<\/span><br>\u00a0 \u00a0 .<span>flatMap<\/span><span>(<\/span><span>novo<\/span> Func1<span>JsonDocument, Observable<span>JsonDocument<span>&gt;&gt;<\/span><span>(<\/span><span>)<\/span> <span>{<\/span><br>\u00a0 \u00a0 \u00a0 \u00a0 @Override<br>\u00a0 \u00a0 \u00a0 \u00a0 <span>p\u00fablico<\/span> Observ\u00e1vel<span>JsonDocument<span>&gt;<\/span> ligar<span>(<\/span>JsonDocument modificado<span>)<\/span> <span>{<\/span><br>\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 <span>retornar<\/span> balde.<span>substituir<\/span><span>(<\/span>modificado<span>)<\/span><span>;<\/span><br>\u00a0 \u00a0 \u00a0 \u00a0 <span>}<\/span><br>\u00a0 \u00a0 <span>}<\/span><span>)<\/span>.<span>Inscrever-se<\/span><span>(<\/span><span>)<\/span><span>;<\/span><\/span><\/span><\/span><\/span><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">O FlatMap se comporta muito como o map, a diferen\u00e7a \u00e9 que ele retorna um observ\u00e1vel por si s\u00f3, tornando-se perfeitamente adequado para mapear sobre opera\u00e7\u00f5es ass\u00edncronas.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Outro aspecto \u00e9 que, com Observables, o tratamento de erros sofisticado est\u00e1 literalmente ao seu alcance. Vamos implementar um exemplo que aplica um tempo limite (timeout) de 2 segundos e, se a chamada n\u00e3o retornar, entrega outra coisa em troca:<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">balde<br>\u00a0 \u00a0 .<span>obter<\/span><span>(<\/span><span>\u201cuser::1\u201d<\/span><span>)<\/span><br>\u00a0 \u00a0 .<span>tempo esgotado<\/span><span>(<\/span><span>2<\/span>, TimeUnit.<span>SEGUNDOS<\/span><span>)<\/span><br>\u00a0 \u00a0 .<span>onErrorReturn<\/span><span>(<\/span><span>novo<\/span> Func1<span><a href=\"https:\/\/www.google.com\/search?hl=en&amp;q=allinurl%3Athrowable+java.sun.com&amp;btnI=I%27m%20Feeling%20Lucky\"><span>Lan\u00e7\u00e1vel<\/span><\/a>, JsonDocument<span>&gt;<\/span><span>(<\/span><span>)<\/span> <span>{<\/span><br>\u00a0 \u00a0 \u00a0 \u00a0 @Override<br>\u00a0 \u00a0 \u00a0 \u00a0 <span>p\u00fablico<\/span> Chamada JsonDocument<span>(<\/span><a href=\"https:\/\/www.google.com\/search?hl=en&amp;q=allinurl%3Athrowable+java.sun.com&amp;btnI=I%27m%20Feeling%20Lucky\"><span>Lan\u00e7\u00e1vel<\/span><\/a> lan\u00e7\u00e1vel<span>)<\/span> <span>{<\/span><br>\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 <span>retornar<\/span> JsonDocument.<span>criar<\/span><span>(<\/span><span>\u201cuser::anonymous\u201d<\/span>, JsonObject.<span>vazio<\/span><span>(<\/span><span>)<\/span>.<span>colocar<\/span><span>(<\/span><span>\u201cnome\u201d<\/span>, <span>\u201cjohn-doe\u201d<\/span><span>)<\/span><span>)<\/span><span>;<\/span><br>\u00a0 \u00a0 \u00a0 \u00a0 <span>}<\/span><br>\u00a0 \u00a0 <span>}<\/span><span>)<\/span><span>;<\/span><\/span><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Aqui, um documento fict\u00edcio \u00e9 retornado (assumindo alguns padr\u00f5es razo\u00e1veis para o nosso exemplo) se a chamada get n\u00e3o retornar em 2 segundos. Este \u00e9 apenas um exemplo simples, mas voc\u00ea pode fazer muito com exce\u00e7\u00f5es, como tentar novamente, ramificar para outros observ\u00e1veis e assim por diante. Consulte a documenta\u00e7\u00e3o oficial (e a documenta\u00e7\u00e3o do Rx) sobre como us\u00e1-las corretamente.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Espere, tem mais<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">H\u00e1 muito mais recursos dispon\u00edveis, como combinar (mesclar, juntar, concatenar) diferentes observables, agrupar os resultados em intervalos de tempo, realizar efeitos colaterais e outros. Assim que voc\u00ea supera o obst\u00e1culo inicial (pequeno) de entender o conceito, parece muito natural e prometemos que voc\u00ea n\u00e3o vai querer voltar atr\u00e1s (se estivermos errados, no entanto, voc\u00ea sempre pode bloquear em um Observable ou convert\u00ea-lo em um future).<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">O RxJava tamb\u00e9m tem um suporte razo\u00e1vel ao Java 8, ent\u00e3o se voc\u00ea \u00e9 um dos sortudos que j\u00e1 consegue us\u00e1-lo em seus projetos, voc\u00ea pode simplificar o exemplo acima para isto:<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">balde<br>\u00a0 \u00a0 .get(\u201cuser::1\u201d)<br>\u00a0 \u00a0 .map(jsonDocument -&gt; jsonDocument.content().getString(&#8220;firstname&#8221;))<br>\u00a0 \u00a0 .filter(s -&gt; s.startsWith(&#8220;a&#8221;))<br>\u00a0 \u00a0 .subscribe(System.out::println);<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Neat, right? RxJava also provides different language adaptors on top of it, at the time of writing Scala, Clojure, Groovy, JRuby and Kotlin. They can be used to provide even more language-specific integration and we are also planning to use some of them to enhance couchbase support for each of those languages as we see demand. Our topmost priority aside from the java SDK is definitely Scala, so be on the lookout for some announcements sooner than later!<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">We hope that you are now as excited as we are and looking forward to your feedback and questions through the usual channels!<\/p>","protected":false},"excerpt":{"rendered":"<p>This blog post explains our reasoning and motivation behind choosing RxJava as one of the integral components in our new Java SDK. Motivation There are many ways to design an API and every one has its own set of benefits (and drawbacks). In the process of designing our brand new APIs one of the main [&hellip;]<\/p>\n","protected":false},"author":19,"featured_media":18,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"inline_featured_image":false,"_acf":"","footnotes":""},"categories":[1],"tags":[],"ppma_author":[29],"class_list":["post-229","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-uncategorized"],"yoast_head":"<!-- This site is optimized with the Yoast SEO Premium plugin v27.6 (Yoast SEO v27.6) - https:\/\/yoast.com\/product\/yoast-seo-premium-wordpress\/ -->\n<title>Why Couchbase chose RxJava for the new Java SDK - 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\/why-couchbase-chose-rxjava-new-java-sdk\/\" \/>\n<meta property=\"og:locale\" content=\"pt_BR\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Why Couchbase chose RxJava for the new Java SDK\" \/>\n<meta property=\"og:description\" content=\"This blog post explains our reasoning and motivation behind choosing RxJava as one of the integral components in our new Java SDK. Motivation There are many ways to design an API and every one has its own set of benefits (and drawbacks). In the process of designing our brand new APIs one of the main [&hellip;]\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.couchbase.com\/blog\/pt\/why-couchbase-chose-rxjava-new-java-sdk\/\" \/>\n<meta property=\"og:site_name\" content=\"The Couchbase Blog\" \/>\n<meta property=\"article:published_time\" content=\"2014-12-16T17:38:21+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/5\/2026\/05\/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=\"Michael Nitschinger\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:creator\" content=\"@daschl\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Michael Nitschinger\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"10 minutos\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/why-couchbase-chose-rxjava-new-java-sdk\\\/#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/why-couchbase-chose-rxjava-new-java-sdk\\\/\"},\"author\":{\"name\":\"Michael Nitschinger\",\"@id\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/#\\\/schema\\\/person\\\/e5d4d332756da6f361dd88c1576de61d\"},\"headline\":\"Why Couchbase chose RxJava for the new Java SDK\",\"datePublished\":\"2014-12-16T17:38:21+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/why-couchbase-chose-rxjava-new-java-sdk\\\/\"},\"wordCount\":1976,\"commentCount\":2,\"publisher\":{\"@id\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/#organization\"},\"image\":{\"@id\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/why-couchbase-chose-rxjava-new-java-sdk\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/wp-content\\\/uploads\\\/sites\\\/5\\\/2026\\\/05\\\/couchbase-nosql-dbaas.png\",\"articleSection\":[\"Uncategorized\"],\"inLanguage\":\"pt-BR\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/why-couchbase-chose-rxjava-new-java-sdk\\\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/why-couchbase-chose-rxjava-new-java-sdk\\\/\",\"url\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/why-couchbase-chose-rxjava-new-java-sdk\\\/\",\"name\":\"Why Couchbase chose RxJava for the new Java SDK - The Couchbase Blog\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/why-couchbase-chose-rxjava-new-java-sdk\\\/#primaryimage\"},\"image\":{\"@id\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/why-couchbase-chose-rxjava-new-java-sdk\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/wp-content\\\/uploads\\\/sites\\\/5\\\/2026\\\/05\\\/couchbase-nosql-dbaas.png\",\"datePublished\":\"2014-12-16T17:38:21+00:00\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/why-couchbase-chose-rxjava-new-java-sdk\\\/#breadcrumb\"},\"inLanguage\":\"pt-BR\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/why-couchbase-chose-rxjava-new-java-sdk\\\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"pt-BR\",\"@id\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/why-couchbase-chose-rxjava-new-java-sdk\\\/#primaryimage\",\"url\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/wp-content\\\/uploads\\\/sites\\\/5\\\/2026\\\/05\\\/couchbase-nosql-dbaas.png\",\"contentUrl\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/wp-content\\\/uploads\\\/sites\\\/5\\\/2026\\\/05\\\/couchbase-nosql-dbaas.png\",\"width\":1800,\"height\":630},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/why-couchbase-chose-rxjava-new-java-sdk\\\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Why Couchbase chose RxJava for the new Java SDK\"}]},{\"@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\\\/sites\\\/5\\\/2026\\\/06\\\/logo.svg\",\"contentUrl\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/wp-content\\\/uploads\\\/sites\\\/5\\\/2026\\\/06\\\/logo.svg\",\"width\":\"1024\",\"height\":\"1024\",\"caption\":\"The Couchbase Blog\"},\"image\":{\"@id\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/#\\\/schema\\\/logo\\\/image\\\/\"}},{\"@type\":\"Person\",\"@id\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/#\\\/schema\\\/person\\\/e5d4d332756da6f361dd88c1576de61d\",\"name\":\"Michael Nitschinger\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"pt-BR\",\"@id\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/dad99b5e02a74ca4bec14352e9da710160647a97290814b669babb3aac0ea675?s=96&d=mm&r=g95e178617974d46e3b02dd1754a3f60b\",\"url\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/dad99b5e02a74ca4bec14352e9da710160647a97290814b669babb3aac0ea675?s=96&d=mm&r=g\",\"contentUrl\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/dad99b5e02a74ca4bec14352e9da710160647a97290814b669babb3aac0ea675?s=96&d=mm&r=g\",\"caption\":\"Michael Nitschinger\"},\"description\":\"Michael Nitschinger works as a Principal Software Engineer at Couchbase. He is the architect and maintainer of the Couchbase Java SDK, one of the first completely reactive database drivers on the JVM. He also authored and maintains the Couchbase Spark Connector. Michael is active in the open source community, a contributor to various other projects like RxJava and Netty.\",\"sameAs\":[\"https:\\\/\\\/nitschinger.at\",\"https:\\\/\\\/x.com\\\/daschl\"],\"url\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/pt\\\/author\\\/michael-nitschinger\\\/\"}]}<\/script>\n<!-- \/ Yoast SEO Premium plugin. -->","yoast_head_json":{"title":"Why Couchbase chose RxJava for the new Java SDK - 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\/why-couchbase-chose-rxjava-new-java-sdk\/","og_locale":"pt_BR","og_type":"article","og_title":"Why Couchbase chose RxJava for the new Java SDK","og_description":"This blog post explains our reasoning and motivation behind choosing RxJava as one of the integral components in our new Java SDK. Motivation There are many ways to design an API and every one has its own set of benefits (and drawbacks). In the process of designing our brand new APIs one of the main [&hellip;]","og_url":"https:\/\/www.couchbase.com\/blog\/pt\/why-couchbase-chose-rxjava-new-java-sdk\/","og_site_name":"The Couchbase Blog","article_published_time":"2014-12-16T17:38:21+00:00","og_image":[{"width":1800,"height":630,"url":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/5\/2026\/05\/couchbase-nosql-dbaas.png","type":"image\/png"}],"author":"Michael Nitschinger","twitter_card":"summary_large_image","twitter_creator":"@daschl","twitter_misc":{"Written by":"Michael Nitschinger","Est. reading time":"10 minutos"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/www.couchbase.com\/blog\/why-couchbase-chose-rxjava-new-java-sdk\/#article","isPartOf":{"@id":"https:\/\/www.couchbase.com\/blog\/why-couchbase-chose-rxjava-new-java-sdk\/"},"author":{"name":"Michael Nitschinger","@id":"https:\/\/www.couchbase.com\/blog\/#\/schema\/person\/e5d4d332756da6f361dd88c1576de61d"},"headline":"Why Couchbase chose RxJava for the new Java SDK","datePublished":"2014-12-16T17:38:21+00:00","mainEntityOfPage":{"@id":"https:\/\/www.couchbase.com\/blog\/why-couchbase-chose-rxjava-new-java-sdk\/"},"wordCount":1976,"commentCount":2,"publisher":{"@id":"https:\/\/www.couchbase.com\/blog\/#organization"},"image":{"@id":"https:\/\/www.couchbase.com\/blog\/why-couchbase-chose-rxjava-new-java-sdk\/#primaryimage"},"thumbnailUrl":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/5\/2026\/05\/couchbase-nosql-dbaas.png","articleSection":["Uncategorized"],"inLanguage":"pt-BR","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/www.couchbase.com\/blog\/why-couchbase-chose-rxjava-new-java-sdk\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/www.couchbase.com\/blog\/why-couchbase-chose-rxjava-new-java-sdk\/","url":"https:\/\/www.couchbase.com\/blog\/why-couchbase-chose-rxjava-new-java-sdk\/","name":"Why Couchbase chose RxJava for the new Java SDK - The Couchbase Blog","isPartOf":{"@id":"https:\/\/www.couchbase.com\/blog\/#website"},"primaryImageOfPage":{"@id":"https:\/\/www.couchbase.com\/blog\/why-couchbase-chose-rxjava-new-java-sdk\/#primaryimage"},"image":{"@id":"https:\/\/www.couchbase.com\/blog\/why-couchbase-chose-rxjava-new-java-sdk\/#primaryimage"},"thumbnailUrl":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/5\/2026\/05\/couchbase-nosql-dbaas.png","datePublished":"2014-12-16T17:38:21+00:00","breadcrumb":{"@id":"https:\/\/www.couchbase.com\/blog\/why-couchbase-chose-rxjava-new-java-sdk\/#breadcrumb"},"inLanguage":"pt-BR","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.couchbase.com\/blog\/why-couchbase-chose-rxjava-new-java-sdk\/"]}]},{"@type":"ImageObject","inLanguage":"pt-BR","@id":"https:\/\/www.couchbase.com\/blog\/why-couchbase-chose-rxjava-new-java-sdk\/#primaryimage","url":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/5\/2026\/05\/couchbase-nosql-dbaas.png","contentUrl":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/5\/2026\/05\/couchbase-nosql-dbaas.png","width":1800,"height":630},{"@type":"BreadcrumbList","@id":"https:\/\/www.couchbase.com\/blog\/why-couchbase-chose-rxjava-new-java-sdk\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/www.couchbase.com\/blog\/"},{"@type":"ListItem","position":2,"name":"Why Couchbase chose RxJava for the new Java SDK"}]},{"@type":"WebSite","@id":"https:\/\/www.couchbase.com\/blog\/#website","url":"https:\/\/www.couchbase.com\/blog\/","name":"O Blog da 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":"O Blog da 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\/sites\/5\/2026\/06\/logo.svg","contentUrl":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/5\/2026\/06\/logo.svg","width":"1024","height":"1024","caption":"The Couchbase Blog"},"image":{"@id":"https:\/\/www.couchbase.com\/blog\/#\/schema\/logo\/image\/"}},{"@type":"Person","@id":"https:\/\/www.couchbase.com\/blog\/#\/schema\/person\/e5d4d332756da6f361dd88c1576de61d","name":"Michael Nitschinger","image":{"@type":"ImageObject","inLanguage":"pt-BR","@id":"https:\/\/secure.gravatar.com\/avatar\/dad99b5e02a74ca4bec14352e9da710160647a97290814b669babb3aac0ea675?s=96&d=mm&r=g95e178617974d46e3b02dd1754a3f60b","url":"https:\/\/secure.gravatar.com\/avatar\/dad99b5e02a74ca4bec14352e9da710160647a97290814b669babb3aac0ea675?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/dad99b5e02a74ca4bec14352e9da710160647a97290814b669babb3aac0ea675?s=96&d=mm&r=g","caption":"Michael Nitschinger"},"description":"Michael Nitschinger works as a Principal Software Engineer at Couchbase. He is the architect and maintainer of the Couchbase Java SDK, one of the first completely reactive database drivers on the JVM. He also authored and maintains the Couchbase Spark Connector. Michael is active in the open source community, a contributor to various other projects like RxJava and Netty.","sameAs":["https:\/\/nitschinger.at","https:\/\/x.com\/daschl"],"url":"https:\/\/www.couchbase.com\/blog\/pt\/author\/michael-nitschinger\/"}]}},"acf":[],"authors":[{"term_id":29,"user_id":19,"is_guest":0,"slug":"michael-nitschinger","display_name":"Michael Nitschinger","avatar_url":"https:\/\/secure.gravatar.com\/avatar\/?s=96&d=mm&r=g","author_category":"","first_name":"Michael","last_name":"Nitschinger, Principal Software Engineer, Couchbase","user_url":"","job_title":"","description":"Michael Nitschinger works as a Principal Software Engineer at Couchbase. He is the architect and maintainer of the Couchbase Java SDK, one of the first completely reactive database drivers on the JVM. He also authored and maintains the Couchbase Spark Connector. Michael is active in the open source community, a contributor to various other projects like RxJava and Netty."}],"_links":{"self":[{"href":"https:\/\/www.couchbase.com\/blog\/pt\/wp-json\/wp\/v2\/posts\/229","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\/19"}],"replies":[{"embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/pt\/wp-json\/wp\/v2\/comments?post=229"}],"version-history":[{"count":0,"href":"https:\/\/www.couchbase.com\/blog\/pt\/wp-json\/wp\/v2\/posts\/229\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/pt\/wp-json\/wp\/v2\/media\/18"}],"wp:attachment":[{"href":"https:\/\/www.couchbase.com\/blog\/pt\/wp-json\/wp\/v2\/media?parent=229"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/pt\/wp-json\/wp\/v2\/categories?post=229"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/pt\/wp-json\/wp\/v2\/tags?post=229"},{"taxonomy":"author","embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/pt\/wp-json\/wp\/v2\/ppma_author?post=229"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}