{"id":4542,"date":"2018-02-08T07:00:16","date_gmt":"2018-02-08T15:00:16","guid":{"rendered":"https:\/\/www.couchbase.com\/blog\/?p=4542"},"modified":"2025-06-13T18:45:48","modified_gmt":"2025-06-14T01:45:48","slug":"use-openwhisk-for-faas-with-node-js-and-couchbase-nosql","status":"publish","type":"post","link":"https:\/\/www.couchbase.com\/blog\/pt\/use-openwhisk-for-faas-with-node-js-and-couchbase-nosql\/","title":{"rendered":"Use o OpenWhisk para FaaS com Node.js e Couchbase NoSQL"},"content":{"rendered":"<p>Se voc\u00ea tem acompanhado meu conte\u00fado, deve se lembrar que escrevi um artigo intitulado,\u00a0<a href=\"https:\/\/www.couchbase.com\/blog\/pt\/use-aws-lambda-api-gateway-node-js-couchbase-nosql\/\" target=\"_blank\" rel=\"noopener\">Use o AWS Lambda e o API Gateway com Node.js e Couchbase NoSQL<\/a>. Neste artigo, exploramos o uso dos servi\u00e7os sem servidor da Amazon para criar fun\u00e7\u00f5es Lambda que interagem com o Couchbase, nosso banco de dados NoSQL.<\/p>\n<p>No entanto, o Lambda n\u00e3o \u00e9 a \u00fanica tecnologia sem servidor, tamb\u00e9m conhecida como fun\u00e7\u00f5es como servi\u00e7o (FaaS), no mercado. Veja <a href=\"https:\/\/openwhisk.apache.org\/\" target=\"_blank\" rel=\"noopener\">Apache OpenWhisk<\/a> por exemplo. Com o OpenWhisk, voc\u00ea pode criar fun\u00e7\u00f5es de modo semelhante ao que faria com o Lambda, mas implant\u00e1-las em um conjunto mais diversificado de locais, sendo o mais popular o IBM Bluemix.<\/p>\n<p>Veremos como criar fun\u00e7\u00f5es sem servidor usando o OpenWhisk para se comunicar com nosso <a href=\"https:\/\/www.couchbase.com\/blog\/pt\/\" target=\"_blank\" rel=\"noopener\">Servidor Couchbase<\/a> banco de dados.<\/p>\n<p><!--more--><\/p>\n<p>Em seguida, h\u00e1 alguns aspectos a serem observados. Voc\u00ea precisar\u00e1 hospedar o Couchbase Server em algum lugar acess\u00edvel ao mundo exterior. Isso significa que seu computador local n\u00e3o funcionar\u00e1. Voc\u00ea precisar\u00e1 do Docker para que possamos compilar nossas depend\u00eancias para trabalhar com o OpenWhisk. Por fim, voc\u00ea precisar\u00e1 de uma conta Bluemix, pelo menos para este exemplo.<\/p>\n<h2>Instala\u00e7\u00e3o das ferramentas de CLI do Bluemix para o OpenWhisk<\/h2>\n<p>Como mencionei anteriormente, o OpenWhisk \u00e9 um projeto da Apache Foundation. No entanto, por conveni\u00eancia, vamos us\u00e1-lo no Bluemix da IBM.<\/p>\n<p>Crie uma conta para o <a href=\"https:\/\/console.bluemix.net\/openwhisk\/\" target=\"_blank\" rel=\"noopener\">Nuvem IBM<\/a> se voc\u00ea ainda n\u00e3o o fez.<\/p>\n<p>Em vez de usar uma ferramenta de estrutura como o Serverless, usaremos a CLI do Bluemix. Fa\u00e7a o download do <a href=\"https:\/\/console.bluemix.net\/openwhisk\/learn\/cli\" target=\"_blank\" rel=\"noopener\">CLI do IBM Cloud Functions<\/a> para podermos interagir com o OpenWhisk na IBM.<\/p>\n<p>Antes de come\u00e7ar a trabalhar com sua conta IBM Cloud, \u00e9 necess\u00e1rio fazer login por meio da CLI. Na linha de comando, execute o seguinte:<\/p>\n<pre class=\"lang:default decode:true\">bx login -a api.ng.bluemix.net -o your_email@example.com -s dev<\/pre>\n<p>Ao fazer o download da CLI, voc\u00ea receber\u00e1 o comando exato, mas ele deve ser semelhante ao que apresentei acima.<\/p>\n<p>Agora podemos come\u00e7ar a criar nosso projeto.<\/p>\n<h2>Entendendo a estrutura do projeto e o processo de cria\u00e7\u00e3o de pacotes do OpenWhisk<\/h2>\n<p>Se voc\u00ea nunca trabalhou com FaaS antes, as coisas s\u00e3o feitas de forma um pouco diferente da cria\u00e7\u00e3o de um aplicativo aut\u00f4nomo e dificilmente escal\u00e1vel.<\/p>\n<p>Por exemplo, cada endpoint em nosso projeto FaaS ser\u00e1 uma fun\u00e7\u00e3o separada. Combinadas, essas fun\u00e7\u00f5es criam o que \u00e9 chamado de pacote. Essas fun\u00e7\u00f5es s\u00e3o dimensionadas conforme necess\u00e1rio para atender \u00e0s mudan\u00e7as na demanda do seu aplicativo.<\/p>\n<p>Dito isso, crie o seguinte:<\/p>\n<pre class=\"lang:default decode:true\">criar\r\n--- package.json\r\n--- criar.js\r\nrecuperar\r\n--- pacote.json\r\n--- retrieve.js\r\nupdate\r\n--- pacote.json\r\n--- update.js\r\ndelete\r\n--- pacote.json\r\n--- delete.js<\/pre>\n<p>O projeto deve ter um diret\u00f3rio para cada fun\u00e7\u00e3o que desejamos criar. Cada fun\u00e7\u00e3o ter\u00e1 seu pr\u00f3prio\u00a0<strong>package.json<\/strong> arquivo. Cada\u00a0<strong>package.json<\/strong> pode ser criado executando o seguinte em cada um dos diret\u00f3rios:<\/p>\n<pre class=\"lang:default decode:true\">npm init -y<\/pre>\n<p>Em cada uma das\u00a0<strong>package.json<\/strong> voc\u00ea tamb\u00e9m precisar\u00e1 definir qual arquivo \u00e9 o seu c\u00f3digo de fun\u00e7\u00e3o. Por exemplo, abrir\u00a0<strong>create\/package.json<\/strong> e adicione ou altere a seguinte linha:<\/p>\n<pre class=\"lang:default decode:true\">\"main\": \"create.js\",<\/pre>\n<p>Ao definir o <code>principal<\/code> estamos informando qual arquivo JavaScript cont\u00e9m nossa fun\u00e7\u00e3o.<\/p>\n<p>Quando come\u00e7armos a implementar nossas fun\u00e7\u00f5es, faremos isso de modo que elas fa\u00e7am parte do mesmo pacote.<\/p>\n<h2>Projetando uma fun\u00e7\u00e3o para criar dados<\/h2>\n<p>Vamos come\u00e7ar o desenvolvimento com a cria\u00e7\u00e3o de dados em nosso banco de dados. Navegue at\u00e9 o diret\u00f3rio\u00a0<strong>criar<\/strong> e execute o seguinte comando em sua linha de comando:<\/p>\n<pre class=\"lang:default decode:true\">npm install couchbase uuid joi --save<\/pre>\n<p>O comando acima instalar\u00e1 nossas depend\u00eancias de fun\u00e7\u00f5es. Usaremos o SDK do Couchbase para Node.js, a biblioteca UUID para gerar chaves exclusivas e a biblioteca Joi para validar a entrada.<\/p>\n<p>Revisaremos a instala\u00e7\u00e3o da depend\u00eancia, mas, pelo menos, ela nos ajudar\u00e1 por enquanto.<\/p>\n<p>Agora, abra o arquivo\u00a0<strong>criar\/criar.js<\/strong> e inclua o seguinte:<\/p>\n<pre class=\"lang:default decode:true\">const Couchbase = require(\"couchbase\");\r\nconst UUID = require(\"uuid\");\r\nconst Joi = require(\"joi\");\r\n\r\nvar bucket = null;\r\n\r\nfunction main(params) {\r\n    if(bucket == null) {\r\n        var cluster = new Couchbase.Cluster(\"couchbase:\/\/\" + params.host);\r\n        cluster.authenticate(params.username, params.password);\r\n        bucket = cluster.openBucket(params.bucketName);\r\n    }\r\n    var schema = Joi.object().keys({\r\n        firstname: Joi.string().required(),\r\n        lastname: Joi.string().required(),\r\n        type: Joi.string().forbidden().default(\"person\")\r\n    });\r\n    var data = params;\r\n    var response = {};\r\n    return new Promise((resolve, reject) =&gt; {\r\n        var validation = Joi.validate(data, schema, { stripUnknown: true });\r\n        if(validation.error) {\r\n            response = {\r\n                statusCode: 500,\r\n                body: JSON.stringify(validation.error.details)\r\n            };\r\n            reject(response);\r\n        }\r\n        var id = UUID.v4();\r\n        bucket.insert(id, validation.value, (error, result) =&gt; {\r\n            if(error) {\r\n                response = {\r\n                    body: JSON.stringify({\r\n                        code: error.code,\r\n                        message: error.message\r\n                    })\r\n                };\r\n                reject(response);\r\n            }\r\n            data.id = id;\r\n            response = {\r\n                body: JSON.stringify(validation.value)\r\n            };\r\n            resolve(response);\r\n        });\r\n    });\r\n}\r\n\r\nexports.main = main;<\/pre>\n<p>O c\u00f3digo acima \u00e9 um pouco exagerado, portanto, precisamos descobrir o que est\u00e1 acontecendo. Vamos come\u00e7ar com a vari\u00e1vel que existe fora de nossa fun\u00e7\u00e3o:<\/p>\n<pre class=\"lang:default decode:true\">var bucket = null;<\/pre>\n<p>N\u00e3o \u00e9 a melhor ideia estabelecer uma nova conex\u00e3o toda vez que a fun\u00e7\u00e3o \u00e9 chamada. Em vez disso, podemos manter uma inst\u00e2ncia global do Couchbase Bucket aberto e, enquanto ele existir, us\u00e1-lo. Observe que ele nem sempre existir\u00e1 porque o OpenWhisk destruir\u00e1 as fun\u00e7\u00f5es ap\u00f3s algum tempo de inatividade.<\/p>\n<pre class=\"lang:default decode:true\">se (bucket == null) {\r\n    var cluster = new Couchbase.Cluster(\"couchbase:\/\/\" + params.host);\r\n    cluster.authenticate(params.username, params.password);\r\n    bucket = cluster.openBucket(params.bucketName);\r\n}<\/pre>\n<p>Dentro de nossa fun\u00e7\u00e3o, verificamos se o Bucket j\u00e1 est\u00e1 aberto. Se o Bucket n\u00e3o estiver aberto, estabelecemos uma conex\u00e3o usando os par\u00e2metros passados para a fun\u00e7\u00e3o. Quando chegar a hora, definiremos par\u00e2metros padr\u00e3o que cont\u00eam essas informa\u00e7\u00f5es de conex\u00e3o.<\/p>\n<p>Como estamos criando dados, precisamos validar se a entrada est\u00e1 correta.<\/p>\n<pre class=\"lang:default decode:true\">var schema = Joi.object().keys({\r\n    firstname: Joi.string().required(),\r\n    lastname: Joi.string().required(),\r\n    type: Joi.string().forbidden().default(\"person\")\r\n});<\/pre>\n<p>Estamos esperando um <code>primeiro nome<\/code> e <code>sobrenome<\/code> esteja presente. Tamb\u00e9m estamos esperando um <code>tipo<\/code> n\u00e3o esteja presente. Podemos validar isso com o seguinte:<\/p>\n<pre class=\"lang:default decode:true\">var validation = Joi.validate(data, schema, { stripUnknown: true });\r\nif(validation.error) {\r\n    response = {\r\n        statusCode: 500,\r\n        body: JSON.stringify(validation.error.details)\r\n    };\r\n    reject(response);\r\n}<\/pre>\n<p>O <code>stripUnknown<\/code> remover\u00e1 os dados n\u00e3o definidos no esquema. Precisamos remover os dados porque nossas informa\u00e7\u00f5es de entrada e conex\u00e3o existir\u00e3o na mesma carga \u00fatil. N\u00e3o queremos que as informa\u00e7\u00f5es de conex\u00e3o sejam salvas em nossos documentos. Se houver um erro de valida\u00e7\u00e3o, ele ser\u00e1 retornado. Se n\u00e3o houver erro de valida\u00e7\u00e3o, podemos prosseguir com a inser\u00e7\u00e3o dos dados.<\/p>\n<pre class=\"lang:default decode:true\">var id = UUID.v4();\r\nbucket.insert(id, validation.value, (error, result) =&gt; {\r\n    if(error) {\r\n        response = {\r\n            body: JSON.stringify({\r\n                code: error.code,\r\n                message: error.message\r\n            })\r\n        };\r\n        reject(response);\r\n    }\r\n    data.id = id;\r\n    resposta = {\r\n        body: JSON.stringify(validation.value)\r\n    };\r\n    resolve(response);\r\n});<\/pre>\n<p>Podemos gerar uma nova chave exclusiva e salvar os dados validados como um documento. Os dados em si ser\u00e3o retornados como uma resposta.<\/p>\n<p>As outras fun\u00e7\u00f5es seguir\u00e3o essa mesma estrat\u00e9gia, mais ou menos.<\/p>\n<h2>Projetando uma fun\u00e7\u00e3o para recuperar dados com N1QL<\/h2>\n<p>Agora que temos dados, vamos tentar recuper\u00e1-los do banco de dados com uma invoca\u00e7\u00e3o de fun\u00e7\u00e3o. Navegue at\u00e9 seu\u00a0<strong>recuperar<\/strong> e execute o seguinte na linha de comando:<\/p>\n<pre class=\"lang:default decode:true\">npm install couchbase --save<\/pre>\n<p>Como n\u00e3o criaremos dados, n\u00e3o precisamos gerar valores exclusivos nem validar nenhum dado do usu\u00e1rio. Por esse motivo, precisamos apenas do SDK do Couchbase para essa fun\u00e7\u00e3o.<\/p>\n<p>Abra o arquivo\u00a0<strong>recuperar\/retrieve.js<\/strong> e inclua o seguinte:<\/p>\n<pre class=\"lang:default decode:true\">const Couchbase = require(\"couchbase\");\r\n\r\nvar bucket = null;\r\n\r\nfunction main(params) {\r\n    if(bucket == null) {\r\n        var cluster = new Couchbase.Cluster(\"couchbase:\/\/\" + params.host);\r\n        cluster.authenticate(params.username, params.password);\r\n        bucket = cluster.openBucket(params.bucketName);\r\n    }\r\n    var response = {};\r\n    var statement = \"SELECT META().id, `\" + bucket._name + \"`.* FROM `\" + bucket._name + \"` WHERE type = 'person'\";\r\n    var query = Couchbase.N1qlQuery.fromString(statement);\r\n    return new Promise((resolve, reject) =&gt; {\r\n        bucket.query(query, (error, result) =&gt; {\r\n            if(error) {\r\n                response = {\r\n                    body: JSON.stringify({\r\n                        code: error.code,\r\n                        message: error.message\r\n                    })\r\n                };\r\n                reject(response);\r\n            }\r\n            response = {\r\n                body: JSON.stringify(result)\r\n            };\r\n            resolve(response);\r\n        });\r\n    });\r\n}\r\n\r\nexports.main = main;<\/pre>\n<p>Vamos pular o que j\u00e1 vimos na fun\u00e7\u00e3o anterior e pular para o que h\u00e1 de novo. Quando estivermos conectados a um Bucket aberto, poderemos criar uma consulta N1QL.<\/p>\n<pre class=\"lang:default decode:true\">var statement = \"SELECT META().id, `\" + bucket._name + \"`.* FROM `\" + bucket._name + \"` WHERE type = 'person'\";\r\nvar query = Couchbase.N1qlQuery.fromString(statement);\r\nreturn new Promise((resolve, reject) =&gt; {\r\n    bucket.query(query, (error, result) =&gt; {\r\n        if(error) {\r\n            response = {\r\n                body: JSON.stringify({\r\n                    code: error.code,\r\n                    message: error.message\r\n                })\r\n            };\r\n            reject(response);\r\n        }\r\n        response = {\r\n            body: JSON.stringify(result)\r\n        };\r\n        resolve(response);\r\n    });\r\n});<\/pre>\n<p>Essa consulta N1QL \u00e9 do tipo SQL e nos permitir\u00e1 recuperar todos os documentos que correspondem a determinados crit\u00e9rios. Se houver algum erro, retorne-o como resposta; caso contr\u00e1rio, retorne o conjunto de resultados.<\/p>\n<p>Como n\u00e3o estamos validando nada, essa fun\u00e7\u00e3o de recupera\u00e7\u00e3o de dados foi muito mais simples.<\/p>\n<h2>Projetando uma fun\u00e7\u00e3o para atualizar dados com muta\u00e7\u00f5es de subdocumentos<\/h2>\n<p>Agora, digamos que queiramos atualizar documentos no banco de dados. Em vez de recuperar documentos, fazer altera\u00e7\u00f5es e salv\u00e1-las, enviaremos as altera\u00e7\u00f5es diretamente ao banco de dados e deixaremos que ele resolva o problema.<\/p>\n<p>Navegue at\u00e9 a se\u00e7\u00e3o\u00a0<strong>atualiza\u00e7\u00e3o<\/strong> e execute o seguinte na linha de comando:<\/p>\n<pre class=\"lang:default decode:true\">npm install couchbase joi --save<\/pre>\n<p>Como estamos aceitando dados de usu\u00e1rios, queremos validar esses dados. Como n\u00e3o estamos criando dados, n\u00e3o precisamos gerar nenhuma chave exclusiva.<\/p>\n<p>Abra o arquivo\u00a0<strong>update\/update.js<\/strong> e inclua o seguinte:<\/p>\n<pre class=\"lang:default decode:true\">const Couchbase = require(\"couchbase\");\r\nconst Joi = require(\"joi\");\r\n\r\nvar bucket = null;\r\n\r\nfunction main(params) {\r\n    if(bucket == null) {\r\n        var cluster = new Couchbase.Cluster(\"couchbase:\/\/\" + params.host);\r\n        cluster.authenticate(params.username, params.password);\r\n        bucket = cluster.openBucket(params.bucketName);\r\n    }\r\n    var schema = Joi.object().keys({\r\n        id: Joi.string().required(),\r\n        firstname: Joi.string().optional(),\r\n        lastname: Joi.string().optional()\r\n    });\r\n    var data = params;\r\n    var response = {};\r\n    return new Promise((resolve, reject) =&gt; {\r\n        var validation = Joi.validate(data, schema, { stripUnknown: true });\r\n        if(validation.error) {\r\n            response = {\r\n                statusCode: 500,\r\n                body: JSON.stringify(validation.error.details)\r\n            };\r\n            reject(response);\r\n        }\r\n        var builder = bucket.mutateIn(validation.value.id);\r\n        if(validation.value.firstname) {\r\n            builder.replace(\"firstname\", validation.value.firstname);\r\n        }\r\n        if(validation.value.lastname) {\r\n            builder.replace(\"lastname\", validation.value.lastname);\r\n        }\r\n        builder.execute((error, result) =&gt; {\r\n            if(error) {\r\n                response = {\r\n                    statusCode: 500,\r\n                    body: JSON.stringify({\r\n                        code: error.code,\r\n                        message: error.message\r\n                    })\r\n                };\r\n                reject(response);\r\n            }\r\n            response = {\r\n                statusCode: 200,\r\n                body: JSON.stringify(validation.value)\r\n            };\r\n            resolve(response);\r\n        });\r\n    });\r\n}\r\n\r\nexports.main = main;<\/pre>\n<p>O c\u00f3digo acima lhe parece familiar? Deveria, porque estamos seguindo a mesma estrat\u00e9gia.<\/p>\n<p>Nossa l\u00f3gica de valida\u00e7\u00e3o \u00e9 ligeiramente diferente neste exemplo:<\/p>\n<pre class=\"lang:default decode:true\">var schema = Joi.object().keys({\r\n    id: Joi.string().required(),\r\n    firstname: Joi.string().optional(),\r\n    lastname: Joi.string().optional()\r\n});<\/pre>\n<p>Queremos editar um documento espec\u00edfico, portanto, uma chave \u00e9 necess\u00e1ria. Como n\u00e3o sabemos o que o usu\u00e1rio deseja atualizar, definimos as propriedades como opcionais.<\/p>\n<p>Para fazer atualiza\u00e7\u00f5es, faremos opera\u00e7\u00f5es de subdocumento em nossos documentos. Para fazer isso, podemos usar um construtor de muta\u00e7\u00e3o.<\/p>\n<pre class=\"lang:default decode:true\">var builder = bucket.mutateIn(validation.value.id);\r\nif(validation.value.firstname) {\r\n    builder.replace(\"firstname\", validation.value.firstname);\r\n}\r\nif(validation.value.lastname) {\r\n    builder.replace(\"lastname\", validation.value.lastname);\r\n}<\/pre>\n<p>Fornecemos um documento para alterar e quaisquer caminhos nos quais as propriedades existam. Os caminhos podem ser muito mais complexos do que os exemplos usados aqui.<\/p>\n<p>Com o conjunto de muta\u00e7\u00f5es definido, podemos execut\u00e1-las no banco de dados.<\/p>\n<pre class=\"lang:default decode:true\">builder.execute((error, result) =&gt; {\r\n    if(error) {\r\n        response = {\r\n            statusCode: 500,\r\n            body: JSON.stringify({\r\n                code: error.code,\r\n                message: error.message\r\n            })\r\n        };\r\n        reject(response);\r\n    }\r\n    response = {\r\n        statusCode: 200,\r\n        body: JSON.stringify(validation.value)\r\n    };\r\n    resolve(response);\r\n});<\/pre>\n<p>Dependendo do resultado, uma resposta ser\u00e1 retornada da invoca\u00e7\u00e3o da fun\u00e7\u00e3o.<\/p>\n<h2>Projetando uma fun\u00e7\u00e3o para remo\u00e7\u00e3o de dados<\/h2>\n<p>Estamos em nossa fun\u00e7\u00e3o final em um pacote de opera\u00e7\u00f5es CRUD. Chegou a hora de excluir dados do banco de dados.<\/p>\n<p>Navegue at\u00e9 a se\u00e7\u00e3o\u00a0<strong>excluir<\/strong> e execute o seguinte comando:<\/p>\n<pre class=\"lang:default decode:true\">npm install couchbase joi --save<\/pre>\n<p>Aceitaremos a exclus\u00e3o de chaves de documentos, portanto, precisaremos validar a entrada. Da mesma forma, tamb\u00e9m precisamos do Couchbase SDK para trabalhar com o banco de dados.<\/p>\n<p>Abra o arquivo\u00a0<strong>delete\/delete.js<\/strong> e inclua o seguinte c\u00f3digo JavaScript:<\/p>\n<pre class=\"lang:default decode:true\">const Couchbase = require(\"couchbase\");\r\nconst Joi = require(\"joi\");\r\n\r\nvar bucket = null;\r\n\r\nfunction main(params) {\r\n    if(bucket == null) {\r\n        var cluster = new Couchbase.Cluster(\"couchbase:\/\/\" + params.host);\r\n        cluster.authenticate(params.username, params.password);\r\n        bucket = cluster.openBucket(params.bucketName);\r\n    }\r\n    var schema = Joi.object().keys({\r\n        id: Joi.string().required()\r\n    });\r\n    var data = params;\r\n    var response = {};\r\n    return new Promise((resolve, reject) =&gt; {\r\n        var validation = Joi.validate(data, schema, { stripUnknown: true });\r\n        if(validation.error) {\r\n            response = {\r\n                statusCode: 500,\r\n                body: JSON.stringify(validation.error.details)\r\n            };\r\n            reject(response);\r\n        }\r\n        bucket.remove(validation.value.id, (error, result) =&gt; {\r\n            if(error) {\r\n                response = {\r\n                    body: JSON.stringify({\r\n                        code: error.code,\r\n                        message: error.message\r\n                    })\r\n                };\r\n                reject(response);\r\n            }\r\n            response = {\r\n                body: JSON.stringify(validation.value)\r\n            };\r\n            resolve(response);\r\n        });\r\n    });\r\n}\r\n\r\nexports.main = main;<\/pre>\n<p>Voc\u00ea provavelmente est\u00e1 vendo o panorama geral agora em rela\u00e7\u00e3o \u00e0 cria\u00e7\u00e3o de fun\u00e7\u00f5es com o OpenWhisk e o Couchbase, portanto, n\u00e3o vamos analisar a fun\u00e7\u00e3o acima para excluir documentos.<\/p>\n<h2>Empacotamento e implementa\u00e7\u00e3o das fun\u00e7\u00f5es no OpenWhisk com o Docker<\/h2>\n<p>Temos um conjunto de fun\u00e7\u00f5es prontas para uso, mas n\u00e3o podemos simplesmente empacot\u00e1-las e implant\u00e1-las no Bluemix. Se fiz\u00e9ssemos isso, ter\u00edamos uma s\u00e9rie de erros. O Bluemix usa uma vers\u00e3o especial do Linux com uma determinada arquitetura. Baixei as depend\u00eancias em meu Mac, que n\u00e3o \u00e9 compat\u00edvel.<\/p>\n<p>Lembre-se do artigo que escrevi h\u00e1 algum tempo, intitulado,\u00a0<a href=\"https:\/\/www.thepolyglotdeveloper.com\/2017\/12\/deploying-native-nodejs-dependencies-aws-lambda\/\" target=\"_blank\" rel=\"noopener\">Implanta\u00e7\u00e3o de depend\u00eancias nativas do Node.js no AWS Lambda<\/a>? Precisamos fazer algo semelhante para o OpenWhisk com o Docker.<\/p>\n<p>Com o Docker instalado e pronto para funcionar, execute o seguinte na CLI:<\/p>\n<pre class=\"lang:default decode:true\">docker pull openwhisk\/nodejs6action\r\ndocker run -it -v \/Users\/nraboy\/Desktop\/couchbase-openwhisk:\/project openwhisk\/nodejs6action \/bin\/bash<\/pre>\n<p>Os comandos acima far\u00e3o o download de uma imagem apropriada do OpenWhisk Docker para o Node.js. Em seguida, implantamos um cont\u00eainer com essa imagem no modo de terminal interativo. Esse cont\u00eainer tamb\u00e9m ter\u00e1 um volume mapeado. Estou mapeando meu diret\u00f3rio de projeto local para um diret\u00f3rio dentro do cont\u00eainer.<\/p>\n<p>Depois que o comando for executado e o cont\u00eainer for implantado, voc\u00ea dever\u00e1 estar no shell dentro do cont\u00eainer.<\/p>\n<p>Para cada fun\u00e7\u00e3o, execute o seguinte:<\/p>\n<pre class=\"lang:default decode:true\">cd \/project\/create\r\nnpm install<\/pre>\n<p>Lembre-se de que instalar as depend\u00eancias de nosso computador host n\u00e3o \u00e9 suficiente. Precisamos compilar as depend\u00eancias para o Bluemix. O Docker compilar\u00e1 essas depend\u00eancias e, como o diret\u00f3rio est\u00e1 mapeado, podemos us\u00e1-las no computador host.<\/p>\n<p>Depois que todos os pacotes de fun\u00e7\u00f5es forem instalados, podemos agrup\u00e1-los e implant\u00e1-los.<\/p>\n<p>No computador host, crie um arquivo ZIP de cada uma das fun\u00e7\u00f5es. O arquivo deve conter os arquivos\u00a0<strong>package.json<\/strong> o arquivo JavaScript e o arquivo\u00a0<strong>m\u00f3dulos_n\u00f3<\/strong> diret\u00f3rio.<\/p>\n<p>Se voc\u00ea estiver em um Mac ou computador com uma CLI do ZIP, execute o seguinte:<\/p>\n<pre class=\"lang:default decode:true\">cd create\r\nzip -r create.zip *<\/pre>\n<p>Quando voc\u00ea tiver um ZIP de cada fun\u00e7\u00e3o, eles poder\u00e3o ser implantados executando o seguinte:<\/p>\n<pre class=\"lang:default decode:true\">bx wsk action create couchbase\/delete --kind nodejs:default delete.zip -p host ec2-45-236-32-140.compute-1.amazonaws.com -p username demo -p password bluemix -p bucketName example<\/pre>\n<p>Introduzi algumas coisas novas no comando acima.<\/p>\n<p>Primeiro, estamos criando um pacote chamado\u00a0<strong>couchbase<\/strong> e, nesse pacote, temos um\u00a0<strong>excluir<\/strong> que \u00e9 baseada na fun\u00e7\u00e3o\u00a0<strong>delete.zip<\/strong> arquivo. Tamb\u00e9m estou passando alguns par\u00e2metros padr\u00e3o. Esses par\u00e2metros ser\u00e3o nossas informa\u00e7\u00f5es de conex\u00e3o. Como essas informa\u00e7\u00f5es s\u00e3o confidenciais, n\u00e3o as estamos passando ao invocar a fun\u00e7\u00e3o, mas sim ao criar a fun\u00e7\u00e3o.<\/p>\n<p>Execute uma varia\u00e7\u00e3o do comando acima para cada uma de suas fun\u00e7\u00f5es.<\/p>\n<p>Para executar sua fun\u00e7\u00e3o, tente executar algo como o seguinte:<\/p>\n<pre class=\"lang:default decode:true\">bx wsk action invoke couchbase\/create -p firstname Nic -p lastname Raboy --blocking<\/pre>\n<p>O comando acima deve passar alguns par\u00e2metros para passar pela valida\u00e7\u00e3o. A fun\u00e7\u00e3o \u00e9 chamada de forma bloqueada e, se for bem-sucedida, nossos dados ser\u00e3o salvos no banco de dados e retornados na resposta.<\/p>\n<h2>Conclus\u00e3o<\/h2>\n<p>Voc\u00ea acabou de ver como criar um pacote de fun\u00e7\u00f5es sem servidor para o OpenWhisk que se comunica com o banco de dados NoSQL, <a href=\"https:\/\/www.couchbase.com\/blog\/pt\/\" target=\"_blank\" rel=\"noopener\">Couchbase<\/a>. O OpenWhisk pode ser usado como uma alternativa ao AWS Lambda, mas os dois certamente n\u00e3o s\u00e3o as \u00fanicas op\u00e7\u00f5es dispon\u00edveis. Independentemente da sua escolha, as fun\u00e7\u00f5es como servi\u00e7o (FaaS) s\u00e3o solu\u00e7\u00f5es muito escalon\u00e1veis para aplicativos de grande porte.<\/p>\n<p>Deseja ver outro exemplo do OpenWhisk? D\u00ea uma olhada em um tutorial que escrevi com o t\u00edtulo,\u00a0<a href=\"https:\/\/www.thepolyglotdeveloper.com\/2017\/12\/convert-nodejs-restful-api-serverless-openwhisk\/\">Converta uma API RESTful do Node.js em Serverless com o OpenWhisk<\/a>.<\/p>","protected":false},"excerpt":{"rendered":"<p>If you&#8217;ve been keeping up with my content, you&#8217;ll remember that I had written an article titled,\u00a0Use AWS Lambda and API Gateway with Node.js and Couchbase NoSQL. In this article we had explored using Amazon&#8217;s Serverless services to create Lambda [&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":[1814,1816,1822],"tags":[2134,2115,2133,1725,2099],"ppma_author":[9032],"class_list":["post-4542","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-application-design","category-couchbase-server","category-node-js","tag-actions","tag-faas","tag-functions","tag-nosql-database","tag-serverless"],"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>Use OpenWhisk for FaaS with Node.js and Couchbase NoSQL<\/title>\n<meta name=\"description\" content=\"Learn how to create and deploy highly scalable applications as functions using OpenWhisk on Bluemix for FaaS and Couchbase for NoSQL JSON data.\" \/>\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\/use-openwhisk-for-faas-with-node-js-and-couchbase-nosql\/\" \/>\n<meta property=\"og:locale\" content=\"pt_BR\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Use OpenWhisk for FaaS with Node.js and Couchbase NoSQL\" \/>\n<meta property=\"og:description\" content=\"Learn how to create and deploy highly scalable applications as functions using OpenWhisk on Bluemix for FaaS and Couchbase for NoSQL JSON data.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.couchbase.com\/blog\/pt\/use-openwhisk-for-faas-with-node-js-and-couchbase-nosql\/\" \/>\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=\"2018-02-08T15:00:16+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2025-06-14T01:45:48+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=\"13 minutos\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/use-openwhisk-for-faas-with-node-js-and-couchbase-nosql\/#article\",\"isPartOf\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/use-openwhisk-for-faas-with-node-js-and-couchbase-nosql\/\"},\"author\":{\"name\":\"Nic Raboy, Developer Advocate, Couchbase\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/#\/schema\/person\/bb545ebe83bb2d12f91095811d0a72e1\"},\"headline\":\"Use OpenWhisk for FaaS with Node.js and Couchbase NoSQL\",\"datePublished\":\"2018-02-08T15:00:16+00:00\",\"dateModified\":\"2025-06-14T01:45:48+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/use-openwhisk-for-faas-with-node-js-and-couchbase-nosql\/\"},\"wordCount\":1857,\"commentCount\":3,\"publisher\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/#organization\"},\"image\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/use-openwhisk-for-faas-with-node-js-and-couchbase-nosql\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2022\/11\/couchbase-nosql-dbaas.png\",\"keywords\":[\"actions\",\"faas\",\"functions\",\"NoSQL Database\",\"serverless\"],\"articleSection\":[\"Application Design\",\"Couchbase Server\",\"Node.js\"],\"inLanguage\":\"pt-BR\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\/\/www.couchbase.com\/blog\/use-openwhisk-for-faas-with-node-js-and-couchbase-nosql\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/use-openwhisk-for-faas-with-node-js-and-couchbase-nosql\/\",\"url\":\"https:\/\/www.couchbase.com\/blog\/use-openwhisk-for-faas-with-node-js-and-couchbase-nosql\/\",\"name\":\"Use OpenWhisk for FaaS with Node.js and Couchbase NoSQL\",\"isPartOf\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/use-openwhisk-for-faas-with-node-js-and-couchbase-nosql\/#primaryimage\"},\"image\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/use-openwhisk-for-faas-with-node-js-and-couchbase-nosql\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2022\/11\/couchbase-nosql-dbaas.png\",\"datePublished\":\"2018-02-08T15:00:16+00:00\",\"dateModified\":\"2025-06-14T01:45:48+00:00\",\"description\":\"Learn how to create and deploy highly scalable applications as functions using OpenWhisk on Bluemix for FaaS and Couchbase for NoSQL JSON data.\",\"breadcrumb\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/use-openwhisk-for-faas-with-node-js-and-couchbase-nosql\/#breadcrumb\"},\"inLanguage\":\"pt-BR\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/www.couchbase.com\/blog\/use-openwhisk-for-faas-with-node-js-and-couchbase-nosql\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"pt-BR\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/use-openwhisk-for-faas-with-node-js-and-couchbase-nosql\/#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\/use-openwhisk-for-faas-with-node-js-and-couchbase-nosql\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/www.couchbase.com\/blog\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Use OpenWhisk for FaaS with Node.js and Couchbase NoSQL\"}]},{\"@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":"Use o OpenWhisk para FaaS com Node.js e Couchbase NoSQL","description":"Saiba como criar e implementar aplicativos altamente dimension\u00e1veis como fun\u00e7\u00f5es usando o OpenWhisk no Bluemix para FaaS e o Couchbase para dados JSON NoSQL.","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\/use-openwhisk-for-faas-with-node-js-and-couchbase-nosql\/","og_locale":"pt_BR","og_type":"article","og_title":"Use OpenWhisk for FaaS with Node.js and Couchbase NoSQL","og_description":"Learn how to create and deploy highly scalable applications as functions using OpenWhisk on Bluemix for FaaS and Couchbase for NoSQL JSON data.","og_url":"https:\/\/www.couchbase.com\/blog\/pt\/use-openwhisk-for-faas-with-node-js-and-couchbase-nosql\/","og_site_name":"The Couchbase Blog","article_author":"https:\/\/www.facebook.com\/thepolyglotdeveloper","article_published_time":"2018-02-08T15:00:16+00:00","article_modified_time":"2025-06-14T01:45:48+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":"13 minutos"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/www.couchbase.com\/blog\/use-openwhisk-for-faas-with-node-js-and-couchbase-nosql\/#article","isPartOf":{"@id":"https:\/\/www.couchbase.com\/blog\/use-openwhisk-for-faas-with-node-js-and-couchbase-nosql\/"},"author":{"name":"Nic Raboy, Developer Advocate, Couchbase","@id":"https:\/\/www.couchbase.com\/blog\/#\/schema\/person\/bb545ebe83bb2d12f91095811d0a72e1"},"headline":"Use OpenWhisk for FaaS with Node.js and Couchbase NoSQL","datePublished":"2018-02-08T15:00:16+00:00","dateModified":"2025-06-14T01:45:48+00:00","mainEntityOfPage":{"@id":"https:\/\/www.couchbase.com\/blog\/use-openwhisk-for-faas-with-node-js-and-couchbase-nosql\/"},"wordCount":1857,"commentCount":3,"publisher":{"@id":"https:\/\/www.couchbase.com\/blog\/#organization"},"image":{"@id":"https:\/\/www.couchbase.com\/blog\/use-openwhisk-for-faas-with-node-js-and-couchbase-nosql\/#primaryimage"},"thumbnailUrl":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2022\/11\/couchbase-nosql-dbaas.png","keywords":["actions","faas","functions","NoSQL Database","serverless"],"articleSection":["Application Design","Couchbase Server","Node.js"],"inLanguage":"pt-BR","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/www.couchbase.com\/blog\/use-openwhisk-for-faas-with-node-js-and-couchbase-nosql\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/www.couchbase.com\/blog\/use-openwhisk-for-faas-with-node-js-and-couchbase-nosql\/","url":"https:\/\/www.couchbase.com\/blog\/use-openwhisk-for-faas-with-node-js-and-couchbase-nosql\/","name":"Use o OpenWhisk para FaaS com Node.js e Couchbase NoSQL","isPartOf":{"@id":"https:\/\/www.couchbase.com\/blog\/#website"},"primaryImageOfPage":{"@id":"https:\/\/www.couchbase.com\/blog\/use-openwhisk-for-faas-with-node-js-and-couchbase-nosql\/#primaryimage"},"image":{"@id":"https:\/\/www.couchbase.com\/blog\/use-openwhisk-for-faas-with-node-js-and-couchbase-nosql\/#primaryimage"},"thumbnailUrl":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2022\/11\/couchbase-nosql-dbaas.png","datePublished":"2018-02-08T15:00:16+00:00","dateModified":"2025-06-14T01:45:48+00:00","description":"Saiba como criar e implementar aplicativos altamente dimension\u00e1veis como fun\u00e7\u00f5es usando o OpenWhisk no Bluemix para FaaS e o Couchbase para dados JSON NoSQL.","breadcrumb":{"@id":"https:\/\/www.couchbase.com\/blog\/use-openwhisk-for-faas-with-node-js-and-couchbase-nosql\/#breadcrumb"},"inLanguage":"pt-BR","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.couchbase.com\/blog\/use-openwhisk-for-faas-with-node-js-and-couchbase-nosql\/"]}]},{"@type":"ImageObject","inLanguage":"pt-BR","@id":"https:\/\/www.couchbase.com\/blog\/use-openwhisk-for-faas-with-node-js-and-couchbase-nosql\/#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\/use-openwhisk-for-faas-with-node-js-and-couchbase-nosql\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/www.couchbase.com\/blog\/"},{"@type":"ListItem","position":2,"name":"Use OpenWhisk for FaaS with Node.js and Couchbase NoSQL"}]},{"@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\/4542","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=4542"}],"version-history":[{"count":0,"href":"https:\/\/www.couchbase.com\/blog\/pt\/wp-json\/wp\/v2\/posts\/4542\/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=4542"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/pt\/wp-json\/wp\/v2\/categories?post=4542"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/pt\/wp-json\/wp\/v2\/tags?post=4542"},{"taxonomy":"author","embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/pt\/wp-json\/wp\/v2\/ppma_author?post=4542"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}