{"id":2072,"date":"2015-07-14T16:37:22","date_gmt":"2015-07-14T16:37:21","guid":{"rendered":"https:\/\/www.couchbase.com\/blog\/?p=2072"},"modified":"2025-06-13T23:47:50","modified_gmt":"2025-06-14T06:47:50","slug":"traveling-with-couchbase-using-the-java-sdk","status":"publish","type":"post","link":"https:\/\/www.couchbase.com\/blog\/pt\/traveling-with-couchbase-using-the-java-sdk\/","title":{"rendered":"Viajando com o Couchbase usando o Java SDK"},"content":{"rendered":"<p>No Couchbase Connect 2015, demonstramos um aplicativo de exemplo que usa o N1QL para consultar dados de um bucket de amostra do Couchbase.<\/p>\n<p>Se voc\u00ea perdeu a confer\u00eancia, n\u00e3o h\u00e1 problema. Vamos explicar como reproduzir esse aplicativo e conferir alguns dos destaques do Couchbase 4.0.<\/p>\n<h2>Pr\u00e9-requisitos<\/h2>\n<ul>\n<li>Apache Maven 3<\/li>\n<li>Kit de desenvolvimento Java (JDK) 1.7<\/li>\n<li>Servidor Couchbase 4.0<\/li>\n<li>IntelliJ IDEA 14.1+, Eclipse ou NetBeans. O IntelliJ IDEA ser\u00e1 usado neste exemplo.<\/li>\n<\/ul>\n<h2>Cria\u00e7\u00e3o de um novo projeto<\/h2>\n<p>Abra o IntelliJ IDEA e escolha criar um novo projeto Java, certificando-se de usar o JDK 1.7, se solicitado. Para fins deste guia, vamos chamar o projeto de <strong>try-cb-java<\/strong>.<\/p>\n<p>Agora, clique com o bot\u00e3o direito do mouse <strong>try-cb-java<\/strong> em sua \u00e1rvore de projetos e, em seguida, selecione <strong>Adicionar suporte a estruturas<\/strong> e selecione <strong>Maven<\/strong>. Isso adicionar\u00e1 um <strong>pom.xml<\/strong> em seu projeto.<\/p>\n<h2>Configura\u00e7\u00e3o do Maven<\/h2>\n<p>Dentro do <strong>pom.xml<\/strong> comece dando ao projeto um nome de grupo mais atraente:<\/p>\n<pre>\n<code class=\"language-xml\">\n<groupId>com.couchbase.example<\/groupId>\n<\/code>\n<\/pre>\n<p>Em seguida, adicione o restante de nossas depend\u00eancias ao arquivo, que inclui o Spring Boot, o cliente Couchbase e a estrutura de seguran\u00e7a do Spring.<\/p>\n<pre>\n<code class=\"language-xml\">\n<parent>\n    <groupId>org.springframework.boot<\/groupId>\n    <artifactId>spring-boot-starter-parent<\/artifactId>\n    <version>1.2.3.RELEASE<\/version>\n<\/parent>\n\n<dependencies>\n    <dependency>\n        <groupId>org.springframework.boot<\/groupId>\n        <artifactId>spring-boot-starter-web<\/artifactId>\n    <\/dependency>\n    <dependency>\n        <groupId>org.springframework<\/groupId>\n        <artifactId>spring-tx<\/artifactId>\n    <\/dependency>\n    <dependency>\n        <groupId>org.springframework.security<\/groupId>\n        <artifactId>spring-security-core<\/artifactId>\n    <\/dependency>\n    <dependency>\n        <groupId>com.couchbase.client<\/groupId>\n        <artifactId>java-client<\/artifactId>\n        <version>2.2.0-dp<\/version>\n    <\/dependency>\n<\/dependencies>\n\n<repositories>\n    <repository>\n        <id>couchbase<\/id>\n        <name>couchbase repo<\/name>\n        <url>https:\/\/files.couchbase.com\/maven2<\/url>\n        <snapshots><enabled>false<\/enabled><\/snapshots>\n    <\/repository>\n<\/repositories>\n\n<build>\n    <plugins>\n        <plugin>\n            <groupId>org.springframework.boot<\/groupId>\n            <artifactId>spring-boot-maven-plugin<\/artifactId>\n        <\/plugin>\n    <\/plugins>\n<\/build>\n<\/code>\n<\/pre>\n<h2>Cria\u00e7\u00e3o de um perfil de execu\u00e7\u00e3o<\/h2>\n<p>No momento, se voc\u00ea tentar executar o aplicativo, ocorrer\u00e1 um erro ou nada acontecer\u00e1 porque n\u00e3o h\u00e1 nenhum perfil configurado no momento.<\/p>\n<p>Na barra de ferramentas, selecione <strong>Run -&gt; Edit Configurations (Executar -&gt; Editar configura\u00e7\u00f5es)<\/strong> e escolha adicionar uma nova configura\u00e7\u00e3o do Maven. Voc\u00ea pode dar a ela o nome que quiser, mas \u00e9 importante ter o seguinte no campo da linha de comando:<\/p>\n<pre>\n<code class=\"language-bash\">\nspring-boot:run\n<\/code>\n<\/pre>\n<p>Para este artigo, nomearemos a configura\u00e7\u00e3o como <strong>Inicializa\u00e7\u00e3o do Spring<\/strong>.<\/p>\n<p>O IntelliJ IDEA agora deve estar pronto para o desenvolvimento.<\/p>\n<h2>Cria\u00e7\u00e3o de \u00edndices no Bucket do Couchbase<\/h2>\n<p>Como este tutorial usa consultas N1QL, devemos primeiro adicionar \u00edndices ao nosso bucket do Couchbase Server. Isso pode ser feito facilmente por meio de c\u00f3digo, mas, para este exemplo, vamos fazer um atalho e adicion\u00e1-los por meio do cliente Couchbase Query (CBQ) que \u00e9 instalado automaticamente com uma instala\u00e7\u00e3o do Couchbase 4+ no Mac OS e no Windows.<\/p>\n<p>No Mac OS, inicie o CBQ encontrado em <strong>\/Applications\/Couchbase Server.app\/Contents\/Resources\/couchbase-core\/bin\/cbq<\/strong> e execute o seguinte:<\/p>\n<pre>\n<code class=\"language-sql\">\nCREATE PRIMARY INDEX def_primary ON `travel-sample` USING gsi;\n<\/code>\n<\/pre>\n<p>No Windows, inicie o CBQ encontrado em <strong>C:\/Arquivos de Programas\/Couchbase\/Server\/bin\/cbq.exe<\/strong> e execute o mesmo comando N1QL que \u00e9 feito no Mac OS.<\/p>\n<h2>Cria\u00e7\u00e3o de uma classe de aplicativo principal<\/h2>\n<p>A classe principal deste projeto ser\u00e1 <strong>Application.java<\/strong> e pode ser criado clicando com o bot\u00e3o direito do mouse no \u00edcone <strong>trycb<\/strong> da \u00e1rvore do projeto e escolhendo <strong>Novo -&gt; Classe Java<\/strong>.<\/p>\n<p>Adicione o seguinte para colocar a classe em seu estado execut\u00e1vel mais b\u00e1sico:<\/p>\n<pre>\n<code class=\"language-java\">\npackage trycb;\n\nimport org.springframework.boot.SpringApplication;\nimport org.springframework.boot.autoconfigure.SpringBootApplication;\nimport org.springframework.web.bind.annotation.RequestMapping;\nimport org.springframework.web.bind.annotation.RestController;\n\n@SpringBootApplication\n@RestController\n@RequestMapping(\"\/api\")\npublic class Application {\n\n    public static void main(String[] args) {\n        SpringApplication.run(Application.class, args);\n    }\n\n}\n<\/code>\n<\/pre>\n<p>Certifique-se de que o projeto seja executado sem erros, selecionando <strong>Executar -&gt; Executar 'Spring Boot'<\/strong> na barra de ferramentas do IntelliJ IDEA.<\/p>\n<h3>Manipula\u00e7\u00e3o do compartilhamento de recursos entre origens (CORS)<\/h3>\n<p>Como a maior parte dos nossos testes ser\u00e1 feita localmente, precisamos garantir que o CORS esteja ativado; caso contr\u00e1rio, o navegador da Web reclamar\u00e1 ao tentar acessar os pontos de extremidade da API com JavaScript.<\/p>\n<p>Certifique-se de que a classe Application implemente a classe Filter e adicione o seguinte c\u00f3digo:<\/p>\n<pre>\n<code class=\"language-java\">\n@Override\npublic void doFilter(ServletRequest req, ServletResponse res, FilterChain chain)\n        throws IOException, ServletException {\n    HttpServletResponse response = (HttpServletResponse) res;\n    response.setHeader(\"Access-Control-Allow-Origin\", \"*\");\n    response.setHeader(\"Access-Control-Allow-Headers\", \"Origin, X-Requested-With, Content-Type, Accept\");\n    chain.doFilter(req, res);\n}\n\n@Override\npublic void init(FilterConfig filterConfig) throws ServletException {}\n\n@Override\npublic void destroy() {}\n<\/code>\n<\/pre>\n<h3>Configurar op\u00e7\u00f5es de cluster e de bucket do Couchbase<\/h3>\n<p>No momento, temos basicamente um aplicativo Spring Boot sem intera\u00e7\u00e3o com o Couchbase. Inclu\u00edmos o cliente Java via Maven, portanto, \u00e9 hora de come\u00e7ar a us\u00e1-lo.<\/p>\n<p>Adicione o seguinte \u00e0 classe Application:<\/p>\n<pre>\n<code class=\"language-java\">\n@Value(\"${hostname}\")\nprivate String hostname;\n\n@Value(\"${bucket}\")\nprivate String bucket;\n\n@Value(\"${password}\")\nprivate String password;\n\npublic @Bean Cluster cluster() {\n   return CouchbaseCluster.create(hostname);\n}\n\npublic @Bean Bucket bucket() {\n   return cluster().openBucket(bucket, password);\n}\n<\/code>\n<\/pre>\n<p>N\u00e3o configuramos o <strong>nome do host<\/strong>, <strong>balde<\/strong>e <strong>senha<\/strong> mas elas ser\u00e3o usadas para se conectar a um cluster do Couchbase e a um determinado bucket.<\/p>\n<h4>Adicionar vari\u00e1veis de recursos<\/h4>\n<p>Voc\u00ea viu que est\u00e1vamos usando <strong>nome do host<\/strong>, <strong>balde<\/strong>e <strong>senha<\/strong>Portanto, agora \u00e9 hora de defini-los.<\/p>\n<p>Na \u00e1rvore de projetos do IntelliJ IDEA, clique com o bot\u00e3o direito do mouse em <strong>src\/main\/resources<\/strong> e escolha <strong>Novo -&gt; Arquivo<\/strong>. Nomeie o novo arquivo <strong>application.properties<\/strong> e adicione as seguintes linhas:<\/p>\n<pre>\nhostname=127.0.0.1\nbucket=travel-sample\npassword=<\/pre>\n<p>O Spring Boot vai captar isso <strong>application.properties<\/strong> para voc\u00ea. Mais informa\u00e7\u00f5es sobre as propriedades relacionadas ao aplicativo podem ser vistas na se\u00e7\u00e3o <a href=\"https:\/\/docs.spring.io\/spring-boot\/docs\/current\/reference\/html\/boot-features-external-config.html\">Documenta\u00e7\u00e3o oficial do Spring<\/a>.<\/p>\n<h3>Cria\u00e7\u00e3o de pontos de extremidade RESTful<\/h3>\n<p>Esse aplicativo ser\u00e1 baseado em API, portanto, determinados pontos de extremidade precisam ser criados:<\/p>\n<pre>\n<code class=\"language-java\">\n@RequestMapping(value=\"\/airport\/findAll\", method=RequestMethod.GET)\npublic List<Map<String, Object>> airports(@RequestParam String search) { }\n\n@RequestMapping(value=\"\/flightPath\/findAll\", method=RequestMethod.GET)\npublic List<Map<String, Object>> all(@RequestParam String from, @RequestParam String to, @RequestParam String leave) throws Exception { }\n\n@RequestMapping(value=\"\/user\/login\", method=RequestMethod.GET)\npublic Object login(@RequestParam String user, @RequestParam String password) { }\n\n@RequestMapping(value=\"\/user\/login\", method=RequestMethod.POST)\npublic Object createLogin(@RequestBody String json) { }\n\n@RequestMapping(value=\"\/user\/flights\", method=RequestMethod.POST)\npublic Object book(@RequestBody String json) { }\n\n@RequestMapping(value=\"\/user\/flights\", method=RequestMethod.GET)\npublic Object booked(@RequestParam String username) { }\n<\/code>\n<\/pre>\n<p>Essencialmente, teremos pontos de extremidade para registro e login de usu\u00e1rios, reserva e localiza\u00e7\u00e3o de voos, bem como pesquisa de informa\u00e7\u00f5es de voos.<\/p>\n<p>A l\u00f3gica por tr\u00e1s desses pontos de extremidade aparecer\u00e1 em outra classe para fins de limpeza.<\/p>\n<h2>Cria\u00e7\u00e3o de uma classe de banco de dados<\/h2>\n<p>Acabamos de configurar os pontos de extremidade de condu\u00e7\u00e3o do nosso aplicativo Spring Boot, mas agora \u00e9 hora de dar uma olhada na l\u00f3gica por tr\u00e1s da intera\u00e7\u00e3o com o banco de dados.<\/p>\n<p>A classe de banco de dados para este projeto ser\u00e1 <strong>Banco de dados.java<\/strong> e pode ser criado clicando com o bot\u00e3o direito do mouse no \u00edcone <strong>trycb<\/strong> na \u00e1rvore de projetos do IntelliJ IDEA e escolhendo <strong>Novo -&gt; Classe Java<\/strong>.<\/p>\n<p>Adicione o seguinte para obter a classe para um bom esqueleto de onde estamos indo:<\/p>\n<pre>\n<code class=\"language-java\">\npackage trycb;\n\npublic class Database {\n\n    private Database() { }\n\n    public static List<Map<String, Object>> findAllAirports(final Bucket bucket, final String params) { }\n\n    public static List<Map<String, Object>> findAllFlightPaths(final Bucket bucket, String from, String to, Calendar leave) { }\n\n    public static ResponseEntity<String> login(final Bucket bucket, final String username, final String password) { }\n\n    public static ResponseEntity<String> createLogin(final Bucket bucket, final String username, final String password) { }\n\n    private static List<Map<String, Object>> extractResultOrThrow(QueryResult result) { }\n\n}\n<\/code>\n<\/pre>\n<p>A partir daqui, completaremos cada um desses m\u00e9todos na ordem em que provavelmente ser\u00e3o interagidos pelo usu\u00e1rio.<\/p>\n<h3>Cria\u00e7\u00e3o de um novo usu\u00e1rio<\/h3>\n<p>Quando o usu\u00e1rio emite um POST para o <strong>\/api\/user\/login<\/strong>a seguinte fun\u00e7\u00e3o de banco de dados deve ser chamada:<\/p>\n<pre>\n<code class=\"language-java\">\npublic static ResponseEntity<String> createLogin(final Bucket bucket, final String username, final String password) {\n    JsonObject data = JsonObject.create()\n        .put(\"type\", \"user\")\n        .put(\"name\", username)\n        .put(\"password\", BCrypt.hashpw(password, BCrypt.gensalt()));\n    JsonDocument doc = JsonDocument.create(\"user::\" + username, data);\n\n    try {\n        bucket.insert(doc);\n        JsonObject responseData = JsonObject.create()\n            .put(\"success\", true)\n            .put(\"data\", data);\n        return new ResponseEntity<String>(responseData.toString(), HttpStatus.OK);\n    } catch (Exception e) {\n        JsonObject responseData = JsonObject.empty()\n            .put(\"success\", false)\n            .put(\"failure\", \"There was an error creating account\")\n            .put(\"exception\", e.getMessage());\n        return new ResponseEntity<String>(responseData.toString(), HttpStatus.OK);\n    }\n}\n<\/code>\n<\/pre>\n<p>O nome de usu\u00e1rio e a senha inclu\u00eddos na solicita\u00e7\u00e3o ser\u00e3o adicionados a um objeto JSON e, em seguida, a senha ser\u00e1 criptografada com a biblioteca Spring BCrypt. Para manter o controle dos dados do usu\u00e1rio, os novos usu\u00e1rios ser\u00e3o colocados em documentos intitulados <strong>usu\u00e1rio::{USERNAME_HERE}<\/strong>. Usando <strong>bucket.insert(doc)<\/strong>Se o bucket for inserido, ser\u00e1 feita uma tentativa de inserir os dados no bucket. Se n\u00e3o houver exce\u00e7\u00f5es lan\u00e7adas, a tentativa foi bem-sucedida e uma resposta \u00e9 retornada. Se houver uma exce\u00e7\u00e3o, a inser\u00e7\u00e3o falhou e o erro ser\u00e1 retornado.<\/p>\n<h3>Como fazer login como um usu\u00e1rio existente<\/h3>\n<p>Quando o usu\u00e1rio emite um GET para o mesmo <strong>\/api\/user\/login<\/strong> a seguinte fun\u00e7\u00e3o de banco de dados deve ser chamada:<\/p>\n<pre>\n<code class=\"language-java\">\npublic static ResponseEntity<String> login(final Bucket bucket, final String username, final String password) {\n   JsonDocument doc = bucket.get(\"user::\" + username);\n   JsonObject responseContent;\n   if(BCrypt.checkpw(password, doc.content().getString(\"password\"))) {\n       responseContent = JsonObject.create().put(\"success\", true).put(\"data\", doc.content());\n   } else {\n       responseContent = JsonObject.empty().put(\"success\", false).put(\"failure\", \"Bad Username or Password\");\n   }\n   return new ResponseEntity<String>(responseContent.toString(), HttpStatus.OK);\n}\n<\/code>\n<\/pre>\n<p>Usando <strong>bucket.get(\"user::\" + nome de usu\u00e1rio)<\/strong> com o nome de usu\u00e1rio fornecido, o aplicativo Java obt\u00e9m o documento do bucket, se ele existir. A biblioteca Spring BCrypt tem uma fun\u00e7\u00e3o excelente para verificar se a senha fornecida corresponde ou n\u00e3o \u00e0 senha criptografada que est\u00e1 armazenada. Se corresponder, retorna um objeto de sucesso; caso contr\u00e1rio, retorna um objeto de falha de login.<\/p>\n<h3>Extraindo o resultado do N1QL e tornando-o leg\u00edvel em Java<\/h3>\n<p>O N1QL retorna um <strong>Resultado da consulta<\/strong> que pode ser menos desej\u00e1vel se estiver retornando dados para um front-end solicitante. O que realmente queremos fazer \u00e9 convert\u00ea-lo em um objeto <strong>Lista<\/strong> objeto.<\/p>\n<pre>\n<code class=\"language-java\">\nprivate static List<Map<String, Object>> extractResultOrThrow(QueryResult result) {\n    if (!result.finalSuccess()) {\n        throw new DataRetrievalFailureException(\"Query error: \" + result.errors());\n    }\n    List<Map<String, Object>> content = new ArrayList<Map<String, Object>>();\n    for (QueryRow row : result) {\n        content.add(row.value().toMap());\n    }\n    return content;\n}\n<\/code>\n<\/pre>\n<p>Essa fun\u00e7\u00e3o ser\u00e1 chamada toda vez que os dados N1QL forem retornados.<\/p>\n<h3>Como encontrar todos os aeroportos<\/h3>\n<p>Agora veremos um pouco da m\u00e1gica por tr\u00e1s do N1QL quando se trata de pesquisar aeroportos.<\/p>\n<pre>\n<code class=\"language-java\">\npublic static List<Map<String, Object>> findAllAirports(final Bucket bucket, final String params) {\n    Statement query;\n\n    AsPath prefix = select(\"airportname\").from(i(bucket.name()));\n    if (params.length() == 3) {\n        query = prefix.where(x(\"faa\").eq(s(params.toUpperCase())));\n    } else if (params.length() == 4 && (params.equals(params.toUpperCase()) || params.equals(params.toLowerCase()))) {\n        query = prefix.where(x(\"icao\").eq(s(params.toUpperCase())));\n    } else {\n        query = prefix.where(i(\"airportname\").like(s(params + \"%\")));\n    }\n\n    QueryResult result = bucket.query(Query.simple(query));\n    return extractResultOrThrow(result);\n}\n<\/code>\n<\/pre>\n<p>Voc\u00ea pode ver no c\u00f3digo acima que estamos usando a API do Fluent com o IntelliJ IDEA para criar nossa consulta N1QL. Essencialmente, se voc\u00ea fosse olhar para o SQL bruto, ele teria a seguinte apar\u00eancia:<\/p>\n<pre>\n<code class=\"language-sql\">\nSELECT airportname FROM `travel-sample` WHERE faa = {{PARAMS}}\n<\/code>\n<\/pre>\n<p>No exemplo acima, {{PARAMS}} representa um aeroporto como LAX ou similar. \u00c9 claro que isso ocorre desde que o comprimento dos params seja tr\u00eas.<\/p>\n<h3>Como encontrar todas as rotas de voo<\/h3>\n<p>Por fim, ficamos com o m\u00e9todo respons\u00e1vel por encontrar rotas de voo:<\/p>\n<pre>\n<code class=\"language-java\">\npublic static List<Map<String, Object>> findAllFlightPaths(final Bucket bucket, String from, String to, Calendar leave) {\n    Statement query = select(x(\"faa\").as(\"fromAirport\"))\n        .from(i(bucket.name()))\n        .where(x(\"airportname\").eq(s(from)))\n        .union()\n        .select(x(\"faa\").as(\"toAirport\"))\n        .from(i(bucket.name()))\n        .where(x(\"airportname\").eq(s(to)));\n\n    QueryResult result = bucket.query(Query.simple(query));\n\n    if (!result.finalSuccess()) {\n        throw new DataRetrievalFailureException(\"Query error: \" + result.errors());\n    }\n\n    String fromAirport = null;\n    String toAirport = null;\n    for (QueryRow row : result) {\n        if (row.value().containsKey(\"fromAirport\")) {\n            fromAirport = row.value().getString(\"fromAirport\");\n        }\n        if (row.value().containsKey(\"toAirport\")) {\n            toAirport = row.value().getString(\"toAirport\");\n        }\n    }\n\n    Statement joinQuery = select(\"a.name\", \"s.flight\", \"s.utc\", \"r.sourceairport\", \"r.destinationairport\", \"r.equipment\")\n            .from(i(bucket.name()).as(\"r\"))\n            .unnest(\"r.schedule AS s\")\n            .join(i(bucket.name()).as(\"a\") + \" ON KEYS r.airlineid\")\n            .where(x(\"r.sourceairport\").eq(s(fromAirport)).and(x(\"r.destinationairport\").eq(s(toAirport))).and(x(\"s.day\").eq(leave.get(Calendar.DAY_OF_MONTH))))\n            .orderBy(Sort.asc(\"a.name\"));\n\n    QueryResult otherResult = bucket.query(joinQuery);\n    return extractResultOrThrow(otherResult);\n}\n<\/code>\n<\/pre>\n<p>Estamos fazendo duas consultas N1QL nesse m\u00e9todo. A primeira pode ser facilmente traduzida para o seguinte:<\/p>\n<pre>\n<code class=\"language-sql\">\nSELECT faa AS fromAirport FROM `travel-sample` WHERE airportname = {{PARAMS.FROM}} UNION SELECT faa AS toAirport FROM `travel-sample` WHERE airportname = {{PARAMS.TO}}\n<\/code>\n<\/pre>\n<p>\u00c9 claro que {{PARAMS}} \u00e9 o que foi passado para o seu endpoint. Na declara\u00e7\u00e3o, estamos combinando os conjuntos de resultados de todos os <strong>de<\/strong> aeroportos e todos os <strong>para<\/strong> aeroportos.<\/p>\n<p>Depois de obter os dois conjuntos de resultados, estamos percorrendo-os para garantir que o <strong>para<\/strong> e <strong>de<\/strong> existem, caso contr\u00e1rio, o padr\u00e3o ser\u00e1 NULL, o que impedir\u00e1 que a pr\u00f3xima consulta seja bem-sucedida.<\/p>\n<p>A segunda consulta pode ser traduzida na seguinte consulta bruta:<\/p>\n<pre>\n<code class=\"language-sql\">\nSELECT a.name, s.flight, s.utc, r.sourceairport, r.destinationairport, r.equipment FROM `travel-sample` AS r UNNEST r.schedule AS s JOIN `travel-sample` AS a ON KEYS r.airlineid WHERE r.sourceairport = {{TO}} AND r.destinationairport = {{TO}} AND s.day = 3 ORDER BY a.name ASC\n<\/code>\n<\/pre>\n<p>Estamos obtendo informa\u00e7\u00f5es de programa\u00e7\u00e3o sobre os voos, aninhando-as no documento JSON e, em seguida, unindo-as \u00e0 chave agora achatada.<\/p>\n<h2>Encerramento das classes de aplicativo e banco de dados<\/h2>\n<p>Agora temos nossos endpoints e m\u00e9todos de banco de dados, mas eles n\u00e3o est\u00e3o conectados uns aos outros. \u00c9 hora de revisitar o <strong>Application.java<\/strong> e adicione algum c\u00f3digo \u00e0s fun\u00e7\u00f5es que criamos anteriormente:<\/p>\n<pre>\n<code class=\"language-java\">\n@RequestMapping(value=\"\/user\/login\", method= RequestMethod.GET)\npublic Object login(@RequestParam String user, @RequestParam String password) {\n    return Database.login(bucket(), user, password);\n}\n\n@RequestMapping(value=\"\/user\/login\", method=RequestMethod.POST)\npublic Object createLogin(@RequestBody String json) {\n    JsonObject jsonData = JsonObject.fromJson(json);\n    return Database.createLogin(bucket(), jsonData.getString(\"user\"), jsonData.getString(\"password\"));\n}\n<\/code>\n<\/pre>\n<p>Voc\u00ea pode ver que as duas imagens est\u00e1ticas <strong>Banco de dados<\/strong> s\u00e3o chamados de cada um dos pontos de extremidade relacionados \u00e0s contas de usu\u00e1rio. O mesmo processo pode ser feito para os outros pontos de extremidade que criamos anteriormente:<\/p>\n<pre>\n<code class=\"language-java\">\n@RequestMapping(\"\/airport\/findAll\")\npublic List<Map<String, Object>> airports(@RequestParam String search) {\n    return Database.findAllAirports(bucket(), search);\n}\n\n@RequestMapping(\"\/flightPath\/findAll\")\npublic List<Map<String, Object>> all(@RequestParam String from, @RequestParam String to, @RequestParam String leave)\n    throws Exception {\n    Calendar calendar = Calendar.getInstance(Locale.US);\n    calendar.setTime(DateFormat.getDateInstance(DateFormat.SHORT, Locale.US).parse(leave));\n    return Database.findAllFlightPaths(bucket(), from, to, calendar);\n}\n<\/code>\n<\/pre>\n<h2>Teste dos pontos finais da amostra<\/h2>\n<p>H\u00e1 algumas maneiras de testar os endpoints do aplicativo. Neste exemplo, usaremos o cURL, mas voc\u00ea certamente pode usar o Postman para o Google Chrome ou algo semelhante.<\/p>\n<p>Com o cURL instalado, abra um Terminal ou Prompt de Comando e digite o seguinte:<\/p>\n<pre>\n<code class=\"language-bash\">\ncurl -X GET 'https:\/\/localhost:8080\/api\/airport\/findAll?search=LAX'\n<\/code>\n<\/pre>\n<p>O comando cURL acima atingir\u00e1 o <strong>api\/airport\/findAll<\/strong> e passar um par\u00e2metro de <strong>search=LAX<\/strong>. Se for bem-sucedido, voc\u00ea dever\u00e1 receber uma resposta de:<\/p>\n<pre>\n[{\"airportname\":\"Los Angeles Intl\"}]<\/pre>\n<p>O mesmo tipo de teste pode ser feito para todos os outros endpoints.<\/p>\n<h2>Conclus\u00e3o<\/h2>\n<p>Acabamos de ver como configurar um aplicativo de viagem de amostra que usa o Couchbase Server e o Spring Boot para Java. Embora n\u00e3o tenhamos configurado um front-end, \u00e9 muito poss\u00edvel adicionar um usando linguagens como AngularJS, jQuery ou ReactJS.<\/p>\n<p>Esse projeto completo, juntamente com um front-end AngularJS, pode ser obtido no site <a href=\"https:\/\/github.com\/couchbaselabs\/try-cb-java\">GitHub do Couchbase Labs<\/a> canal.<\/p>","protected":false},"excerpt":{"rendered":"<p>At Couchbase Connect 2015 we demonstrated an example application that uses N1QL to query data from a sample Couchbase bucket. If you missed the conference, not a problem. We&#39;re going to go through how to reproduce this application and check [&hellip;]<\/p>","protected":false},"author":63,"featured_media":13873,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"inline_featured_image":false,"footnotes":""},"categories":[1812,2201],"tags":[1725],"ppma_author":[9032],"class_list":["post-2072","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-n1ql-query","category-tools-sdks","tag-nosql-database"],"acf":[],"yoast_head":"<!-- This site is optimized with the Yoast SEO Premium plugin v26.2 (Yoast SEO v26.2) - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<title>Traveling with Couchbase using the 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\/traveling-with-couchbase-using-the-java-sdk\/\" \/>\n<meta property=\"og:locale\" content=\"pt_BR\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Traveling with Couchbase using the Java SDK\" \/>\n<meta property=\"og:description\" content=\"At Couchbase Connect 2015 we demonstrated an example application that uses N1QL to query data from a sample Couchbase bucket. If you missed the conference, not a problem. We&#039;re going to go through how to reproduce this application and check [&hellip;]\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.couchbase.com\/blog\/pt\/traveling-with-couchbase-using-the-java-sdk\/\" \/>\n<meta property=\"og:site_name\" content=\"The Couchbase Blog\" \/>\n<meta property=\"article:author\" content=\"https:\/\/www.facebook.com\/thepolyglotdeveloper\" \/>\n<meta property=\"article:published_time\" content=\"2015-07-14T16:37:21+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2025-06-14T06:47:50+00:00\" \/>\n<meta name=\"author\" content=\"Nic Raboy, Developer Advocate, Couchbase\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:creator\" content=\"@nraboy\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Nic Raboy, Developer Advocate, Couchbase\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"12 minutos\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/traveling-with-couchbase-using-the-java-sdk\/#article\",\"isPartOf\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/traveling-with-couchbase-using-the-java-sdk\/\"},\"author\":{\"name\":\"Nic Raboy, Developer Advocate, Couchbase\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/#\/schema\/person\/bb545ebe83bb2d12f91095811d0a72e1\"},\"headline\":\"Traveling with Couchbase using the Java SDK\",\"datePublished\":\"2015-07-14T16:37:21+00:00\",\"dateModified\":\"2025-06-14T06:47:50+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/traveling-with-couchbase-using-the-java-sdk\/\"},\"wordCount\":1474,\"commentCount\":0,\"publisher\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/#organization\"},\"image\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/traveling-with-couchbase-using-the-java-sdk\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2022\/11\/couchbase-nosql-dbaas.png\",\"keywords\":[\"NoSQL Database\"],\"articleSection\":[\"SQL++ \/ N1QL Query\",\"Tools &amp; SDKs\"],\"inLanguage\":\"pt-BR\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\/\/www.couchbase.com\/blog\/traveling-with-couchbase-using-the-java-sdk\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/traveling-with-couchbase-using-the-java-sdk\/\",\"url\":\"https:\/\/www.couchbase.com\/blog\/traveling-with-couchbase-using-the-java-sdk\/\",\"name\":\"Traveling with Couchbase using the Java SDK - The Couchbase Blog\",\"isPartOf\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/traveling-with-couchbase-using-the-java-sdk\/#primaryimage\"},\"image\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/traveling-with-couchbase-using-the-java-sdk\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2022\/11\/couchbase-nosql-dbaas.png\",\"datePublished\":\"2015-07-14T16:37:21+00:00\",\"dateModified\":\"2025-06-14T06:47:50+00:00\",\"breadcrumb\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/traveling-with-couchbase-using-the-java-sdk\/#breadcrumb\"},\"inLanguage\":\"pt-BR\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/www.couchbase.com\/blog\/traveling-with-couchbase-using-the-java-sdk\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"pt-BR\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/traveling-with-couchbase-using-the-java-sdk\/#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\/traveling-with-couchbase-using-the-java-sdk\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/www.couchbase.com\/blog\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Traveling with Couchbase using the 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\/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\/bb545ebe83bb2d12f91095811d0a72e1\",\"name\":\"Nic Raboy, Developer Advocate, Couchbase\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"pt-BR\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/#\/schema\/person\/image\/8863514d8bed0cf6080f23db40e00354\",\"url\":\"https:\/\/secure.gravatar.com\/avatar\/bedeb68368d4681aca4c74fe5f697f0c423b80d498ec50fd915ba018b72c101f?s=96&d=mm&r=g\",\"contentUrl\":\"https:\/\/secure.gravatar.com\/avatar\/bedeb68368d4681aca4c74fe5f697f0c423b80d498ec50fd915ba018b72c101f?s=96&d=mm&r=g\",\"caption\":\"Nic Raboy, Developer Advocate, Couchbase\"},\"description\":\"Nic Raboy is an advocate of modern web and mobile development technologies. He has experience in Java, JavaScript, Golang and a variety of frameworks such as Angular, NativeScript, and Apache Cordova. Nic writes about his development experiences related to making web and mobile development easier to understand.\",\"sameAs\":[\"https:\/\/www.thepolyglotdeveloper.com\",\"https:\/\/www.facebook.com\/thepolyglotdeveloper\",\"https:\/\/x.com\/nraboy\"],\"url\":\"https:\/\/www.couchbase.com\/blog\/pt\/author\/nic-raboy-2\/\"}]}<\/script>\n<!-- \/ Yoast SEO Premium plugin. -->","yoast_head_json":{"title":"Traveling with Couchbase using the 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\/traveling-with-couchbase-using-the-java-sdk\/","og_locale":"pt_BR","og_type":"article","og_title":"Traveling with Couchbase using the Java SDK","og_description":"At Couchbase Connect 2015 we demonstrated an example application that uses N1QL to query data from a sample Couchbase bucket. If you missed the conference, not a problem. We&#39;re going to go through how to reproduce this application and check [&hellip;]","og_url":"https:\/\/www.couchbase.com\/blog\/pt\/traveling-with-couchbase-using-the-java-sdk\/","og_site_name":"The Couchbase Blog","article_author":"https:\/\/www.facebook.com\/thepolyglotdeveloper","article_published_time":"2015-07-14T16:37:21+00:00","article_modified_time":"2025-06-14T06:47:50+00:00","author":"Nic Raboy, Developer Advocate, Couchbase","twitter_card":"summary_large_image","twitter_creator":"@nraboy","twitter_misc":{"Written by":"Nic Raboy, Developer Advocate, Couchbase","Est. reading time":"12 minutos"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/www.couchbase.com\/blog\/traveling-with-couchbase-using-the-java-sdk\/#article","isPartOf":{"@id":"https:\/\/www.couchbase.com\/blog\/traveling-with-couchbase-using-the-java-sdk\/"},"author":{"name":"Nic Raboy, Developer Advocate, Couchbase","@id":"https:\/\/www.couchbase.com\/blog\/#\/schema\/person\/bb545ebe83bb2d12f91095811d0a72e1"},"headline":"Traveling with Couchbase using the Java SDK","datePublished":"2015-07-14T16:37:21+00:00","dateModified":"2025-06-14T06:47:50+00:00","mainEntityOfPage":{"@id":"https:\/\/www.couchbase.com\/blog\/traveling-with-couchbase-using-the-java-sdk\/"},"wordCount":1474,"commentCount":0,"publisher":{"@id":"https:\/\/www.couchbase.com\/blog\/#organization"},"image":{"@id":"https:\/\/www.couchbase.com\/blog\/traveling-with-couchbase-using-the-java-sdk\/#primaryimage"},"thumbnailUrl":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2022\/11\/couchbase-nosql-dbaas.png","keywords":["NoSQL Database"],"articleSection":["SQL++ \/ N1QL Query","Tools &amp; SDKs"],"inLanguage":"pt-BR","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/www.couchbase.com\/blog\/traveling-with-couchbase-using-the-java-sdk\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/www.couchbase.com\/blog\/traveling-with-couchbase-using-the-java-sdk\/","url":"https:\/\/www.couchbase.com\/blog\/traveling-with-couchbase-using-the-java-sdk\/","name":"Traveling with Couchbase using the Java SDK - The Couchbase Blog","isPartOf":{"@id":"https:\/\/www.couchbase.com\/blog\/#website"},"primaryImageOfPage":{"@id":"https:\/\/www.couchbase.com\/blog\/traveling-with-couchbase-using-the-java-sdk\/#primaryimage"},"image":{"@id":"https:\/\/www.couchbase.com\/blog\/traveling-with-couchbase-using-the-java-sdk\/#primaryimage"},"thumbnailUrl":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2022\/11\/couchbase-nosql-dbaas.png","datePublished":"2015-07-14T16:37:21+00:00","dateModified":"2025-06-14T06:47:50+00:00","breadcrumb":{"@id":"https:\/\/www.couchbase.com\/blog\/traveling-with-couchbase-using-the-java-sdk\/#breadcrumb"},"inLanguage":"pt-BR","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.couchbase.com\/blog\/traveling-with-couchbase-using-the-java-sdk\/"]}]},{"@type":"ImageObject","inLanguage":"pt-BR","@id":"https:\/\/www.couchbase.com\/blog\/traveling-with-couchbase-using-the-java-sdk\/#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\/traveling-with-couchbase-using-the-java-sdk\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/www.couchbase.com\/blog\/"},{"@type":"ListItem","position":2,"name":"Traveling with Couchbase using the Java SDK"}]},{"@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\/bb545ebe83bb2d12f91095811d0a72e1","name":"Nic Raboy, defensor dos desenvolvedores, Couchbase","image":{"@type":"ImageObject","inLanguage":"pt-BR","@id":"https:\/\/www.couchbase.com\/blog\/#\/schema\/person\/image\/8863514d8bed0cf6080f23db40e00354","url":"https:\/\/secure.gravatar.com\/avatar\/bedeb68368d4681aca4c74fe5f697f0c423b80d498ec50fd915ba018b72c101f?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/bedeb68368d4681aca4c74fe5f697f0c423b80d498ec50fd915ba018b72c101f?s=96&d=mm&r=g","caption":"Nic Raboy, Developer Advocate, Couchbase"},"description":"Nic Raboy \u00e9 um defensor das modernas tecnologias de desenvolvimento m\u00f3vel e da Web. Ele tem experi\u00eancia em Java, JavaScript, Golang e uma variedade de estruturas, como Angular, NativeScript e Apache Cordova. Nic escreve sobre suas experi\u00eancias de desenvolvimento relacionadas a tornar o desenvolvimento m\u00f3vel e da Web mais f\u00e1cil de entender.","sameAs":["https:\/\/www.thepolyglotdeveloper.com","https:\/\/www.facebook.com\/thepolyglotdeveloper","https:\/\/x.com\/nraboy"],"url":"https:\/\/www.couchbase.com\/blog\/pt\/author\/nic-raboy-2\/"}]}},"authors":[{"term_id":9032,"user_id":63,"is_guest":0,"slug":"nic-raboy-2","display_name":"Nic Raboy, Developer Advocate, Couchbase","avatar_url":"https:\/\/secure.gravatar.com\/avatar\/bedeb68368d4681aca4c74fe5f697f0c423b80d498ec50fd915ba018b72c101f?s=96&d=mm&r=g","author_category":"","last_name":"Raboy","first_name":"Nic","job_title":"","user_url":"https:\/\/www.thepolyglotdeveloper.com","description":"Nic Raboy \u00e9 um defensor das modernas tecnologias de desenvolvimento m\u00f3vel e da Web. Ele tem experi\u00eancia em Java, JavaScript, Golang e uma variedade de estruturas, como Angular, NativeScript e Apache Cordova. Nic escreve sobre suas experi\u00eancias de desenvolvimento relacionadas a tornar o desenvolvimento m\u00f3vel e da Web mais f\u00e1cil de entender."}],"_links":{"self":[{"href":"https:\/\/www.couchbase.com\/blog\/pt\/wp-json\/wp\/v2\/posts\/2072","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\/63"}],"replies":[{"embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/pt\/wp-json\/wp\/v2\/comments?post=2072"}],"version-history":[{"count":0,"href":"https:\/\/www.couchbase.com\/blog\/pt\/wp-json\/wp\/v2\/posts\/2072\/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=2072"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/pt\/wp-json\/wp\/v2\/categories?post=2072"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/pt\/wp-json\/wp\/v2\/tags?post=2072"},{"taxonomy":"author","embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/pt\/wp-json\/wp\/v2\/ppma_author?post=2072"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}