{"id":2448,"date":"2016-12-20T15:00:00","date_gmt":"2016-12-20T15:00:00","guid":{"rendered":"https:\/\/www.couchbase.com\/blog\/?p=2448"},"modified":"2025-06-13T21:40:24","modified_gmt":"2025-06-14T04:40:24","slug":"create-a-url-shortener-using-ottoman-odm-with-nodejs-and-couchbase","status":"publish","type":"post","link":"https:\/\/www.couchbase.com\/blog\/pt\/create-a-url-shortener-using-ottoman-odm-with-nodejs-and-couchbase\/","title":{"rendered":"Criar um encurtador de URL usando Ottoman ODM com Node.js e Couchbase"},"content":{"rendered":"<p>N\u00e3o faz muito tempo, escrevi sobre <a href=\"https:\/\/www.couchbase.com\/blog\/pt\/create-a-url-shortener-with-nodejs-and-couchbase-using-n1ql\/\">Cria\u00e7\u00e3o de um encurtador de URL com Node.js e Couchbase N1QL<\/a>. Se voc\u00ea ainda n\u00e3o o viu, o artigo \u00e9 uma \u00f3tima introdu\u00e7\u00e3o ao Couchbase e \u00e0 cria\u00e7\u00e3o de APIs RESTful <a href=\"https:\/\/www.couchbase.com\/blog\/pt\/build-a-rest-api-with-node-js-express-and-couchbase\/\">usando Node.js<\/a> e Express Framework. A desvantagem desse artigo, e n\u00e3o \u00e9 uma desvantagem ruim, \u00e9 que voc\u00ea precisa preferir escrever consultas SQL para gerenciar seus dados NoSQL.<\/p>\n<p>E se voc\u00ea preferir usar um Modelo de Documento de Objeto (ODM) em vez de escrever consultas?<\/p>\n<p>Desta vez, vamos explorar o processo de desenvolvimento por tr\u00e1s da cria\u00e7\u00e3o de um encurtador de URL que usa Ottoman ODM, Couchbase Server e Node.js.<\/p>\n<h2 id=\"the-requirements\">Os requisitos<\/h2>\n<p>N\u00e3o h\u00e1 muitos requisitos para o sucesso desse aplicativo. Por exemplo, o que voc\u00ea precisar\u00e1 instalar e configurar \u00e9 o seguinte:<\/p>\n<ul>\n<li>Servidor Couchbase 4.1+<\/li>\n<li>Node.js 4.0+<\/li>\n<\/ul>\n<p>Como este \u00e9 um aplicativo Node.js, precisaremos dele instalado e usaremos o Node Package Manager (NPM) para reunir todas as depend\u00eancias do nosso projeto. Para aproveitar ao m\u00e1ximo o Ottoman, queremos usar o Couchbase 4.1 ou superior.<\/p>\n<h2 id=\"understanding-the-data-model-and-preparing-the-couchbase-database\">Entendendo o modelo de dados e preparando o banco de dados do Couchbase<\/h2>\n<p>Para este exemplo, vamos criar um bucket chamado <strong>exemplo<\/strong> no Couchbase Server. Voc\u00ea n\u00e3o precisa cham\u00e1-lo assim, mas ao longo do artigo faremos refer\u00eancia a ele como tal. N\u00e3o \u00e9 necess\u00e1rio nenhum \u00edndice ou configura\u00e7\u00e3o adicional em nosso cluster al\u00e9m da cria\u00e7\u00e3o do bucket.<\/p>\n<p>Em termos de dados, o plano \u00e9 armazenar um documento para cada URL que desejamos reduzir. Cada documento pode ter a seguinte apar\u00eancia:<\/p>\n<pre><code>{\r\n  \"_type\": \"Url\",\r\n  \"hash\": \"2xmx9qpyj\",\r\n  \"longUrl\": \"https:\/\/www.thepolyglotdeveloper.com\/2016\/05\/using-couchbase-nosql-nativescript-angular-2-mobile-app\/\",\r\n  \"shortUrl\": \"https:\/\/localhost:3000\/2xmx9qpyj\"\r\n}<\/code><\/pre>\n<p>O <code>_tipo<\/code> \u00e9 algo definido pelo modelo Ottoman, mas as outras tr\u00eas s\u00e3o propriedades que definiremos. O hash representar\u00e1 um hash exclusivo de um valor. Esse hash funcionar\u00e1 como identificador em cada um de nossos URLs curtos.<\/p>\n<h2 id=\"developing-the-node.js-url-shortener-application\">Desenvolvimento do aplicativo encurtador de URL do Node.js<\/h2>\n<p>Com o banco de dados pronto e um entendimento b\u00e1sico do nosso modelo de dados, podemos trabalhar na cria\u00e7\u00e3o do nosso aplicativo encurtador de URLs Node.js. O aplicativo depender\u00e1 muito do Express Framework e de uma biblioteca chamada <a href=\"https:\/\/www.npmjs.com\/package\/hashids\">Hashids<\/a>. Usaremos Hashids para evitar o trabalho de escrever nosso pr\u00f3prio algoritmo de hash curto.<\/p>\n<h3 id=\"creating-the-project-with-the-dependencies\">Criando o projeto com as depend\u00eancias<\/h3>\n<p>Vamos come\u00e7ar criando um novo projeto Node.js e instalando todas as depend\u00eancias necess\u00e1rias do projeto. No Terminal (Mac e Linux) ou no Prompt de Comando (Windows), execute o seguinte:<\/p>\n<pre><code>npm init --y<\/code><\/pre>\n<p>O comando acima criar\u00e1 um novo <strong>package.json<\/strong> para o nosso projeto. Esse arquivo conter\u00e1 todas as informa\u00e7\u00f5es de depend\u00eancia, al\u00e9m de outras coisas.<\/p>\n<p>Agora, precisamos instalar cada uma das depend\u00eancias necess\u00e1rias em nosso projeto:<\/p>\n<pre><code>npm install couchbase express ottoman body-parser hashids --save<\/code><\/pre>\n<p>O comando acima instalar\u00e1 o SDK do Couchbase, a estrutura Express, o Ottoman, o Hashids e a biblioteca Body Parser para aceitar dados do corpo em solicita\u00e7\u00f5es HTTP.<\/p>\n<p>Nesse ponto, podemos come\u00e7ar a inicializar o aplicativo para prepar\u00e1-lo para o trabalho pesado.<\/p>\n<h3 id=\"bootstrapping-the-application\">Inicializa\u00e7\u00e3o do aplicativo<\/h3>\n<p>Para simplificar, todo o c\u00f3digo do nosso aplicativo residir\u00e1 em um \u00fanico arquivo dentro do nosso projeto chamado <strong>index.js<\/strong>. Em um ambiente de produ\u00e7\u00e3o, voc\u00ea provavelmente desejaria dividi-lo para facilitar a manuten\u00e7\u00e3o, mas para este exemplo muito simples n\u00e3o haver\u00e1 problema.<\/p>\n<p>Abra o <strong>index.js<\/strong> e incluir importa\u00e7\u00f5es para cada uma das depend\u00eancias que instalamos:<\/p>\n<pre><code>var Couchbase = require(\"couchbase\");\r\nvar Ottoman = require(\"ottoman\");\r\nvar Express = require(\"express\");\r\nvar BodyParser = require(\"body-parser\");\r\nvar Hashids = require(\"hashids\");<\/code><\/pre>\n<p>Com as depend\u00eancias importadas, agora podemos inicializ\u00e1-las para uso no aplicativo:<\/p>\n<pre><code>var app = Express();\r\n\r\napp.use(BodyParser.json());\r\napp.use(BodyParser.urlencoded({ extended: true }));<\/code><\/pre>\n<p>No exemplo acima, estamos basicamente dizendo que queremos inicializar o Express Framework e aceitar JSON e dados do corpo codificados por URL das solicita\u00e7\u00f5es.<\/p>\n<p>Nesse ponto, podemos estabelecer uma conex\u00e3o com nosso cluster do Couchbase e abrir o bucket do aplicativo:<\/p>\n<pre><code>Ottoman.bucket = (new Couchbase.Cluster(\"couchbase:\/\/localhost\")).openBucket(\"example\");<\/code><\/pre>\n<p>Para usar o Ottoman, alguns \u00edndices precisam existir. Para nossa sorte, podemos fazer com que o Ottoman crie esses \u00edndices para n\u00f3s se eles ainda n\u00e3o existirem. Depois de termos certeza de que eles existem, podemos come\u00e7ar a servir o aplicativo.<\/p>\n<pre><code>Ottoman.ensureIndices(function(error) {\r\n    if(error) {\r\n        console.log(error);\r\n    }\r\n    var server = app.listen(3000, function() {\r\n        console.log(\"Listening on port %s...\", server.address().port);\r\n    });\r\n});<\/code><\/pre>\n<p>Em nosso exemplo, o aplicativo ser\u00e1 servido localmente na porta 3000.<\/p>\n<p>At\u00e9 agora, s\u00f3 temos a estrutura b\u00e1sica em funcionamento para nosso aplicativo encurtador de URL. Na verdade, n\u00e3o temos nenhuma l\u00f3gica de encolhimento ou intera\u00e7\u00e3o com o banco de dados em rela\u00e7\u00e3o a opera\u00e7\u00f5es CRUD ou de consulta.<\/p>\n<h3 id=\"creating-the-data-model\">Cria\u00e7\u00e3o do modelo de dados<\/h3>\n<p>Sabemos como os dados ser\u00e3o exibidos no banco de dados, mas ainda n\u00e3o sabemos como cri\u00e1-los. Como estamos usando um ODM em vez de consultas N1QL, precisamos definir o modelo em nosso c\u00f3digo.<\/p>\n<p>Nesse projeto espec\u00edfico, o modelo \u00e9 muito simples. Ele seria parecido com o seguinte:<\/p>\n<pre><code>var UrlModel = Ottoman.model(\"Url\", {\r\n    hash: {type: \"string\", readonly: true},\r\n    longUrl: \"string\",\r\n    shortUrl: \"string\"\r\n}, {\r\n    id: \"hash\"\r\n});<\/code><\/pre>\n<p>No modelo de dados acima, que estamos chamando de <code>URL<\/code>temos tr\u00eas propriedades. As <code>hash<\/code> representar\u00e1 o ID do nosso documento. N\u00e3o \u00e9 obrigat\u00f3rio definir manualmente o ID do documento, mas para este projeto faz sentido. A defini\u00e7\u00e3o manual de um id de documento exige que a propriedade seja somente leitura. As outras duas propriedades s\u00e3o valores de cadeia de caracteres padr\u00e3o.<\/p>\n<p>O modelo pode ser infinitamente mais complexo, dependendo de suas necessidades.<\/p>\n<h3 id=\"applying-the-data-model-in-a-series-of-restful-endpoint-methods\">Aplica\u00e7\u00e3o do modelo de dados em uma s\u00e9rie de m\u00e9todos de ponto de extremidade RESTful<\/h3>\n<p>O aplicativo que estamos criando \u00e9 um servi\u00e7o da Web RESTful, portanto, precisamos criar algumas fun\u00e7\u00f5es de endpoint. O aplicativo conter\u00e1 os tr\u00eas endpoints p\u00fablicos a seguir:<\/p>\n<pre><code>\/\r\n\/create\r\n\/expand<\/code><\/pre>\n<p>Quando o <strong>raiz<\/strong> for atingido, o aplicativo nos levar\u00e1 ao URL longo que est\u00e1 armazenado no Couchbase. Quando o <strong>\/criar<\/strong> for atingido, tentaremos encontrar um URL curto salvo anteriormente ou criaremos um, caso ele n\u00e3o exista. Fazemos isso porque n\u00e3o queremos salvar v\u00e1rias c\u00f3pias de um URL longo. Por fim, temos um <strong>\/expandir<\/strong> para que possamos ver para onde vai nosso URL curto.<\/p>\n<p>Come\u00e7ando com o <strong>\/criar<\/strong> temos o seguinte m\u00e9todo, que provavelmente \u00e9 a parte mais complexa do nosso aplicativo:<\/p>\n<pre><code>app.post(\"\/create\", function(req, res) {\r\n    if(!req.body.longUrl) {\r\n        return res.status(400).send({\"status\": \"error\", \"message\": \"A long URL is required\"});\r\n    }\r\n    UrlModel.find({\"longUrl\": req.body.longUrl}, function(error, url) {\r\n        if(error) {\r\n            return res.status(400).send(error);\r\n        }\r\n        if(url.length == 0) {\r\n            var hashids = new Hashids();\r\n            var urlObj = new UrlModel({\r\n                hash: hashids.encode((new Date).getTime()),\r\n                longUrl: req.body.longUrl\r\n            });\r\n            urlObj.shortUrl = \"https:\/\/localhost:3000\/\" + urlObj.hash;\r\n            urlObj.save(function(error, result) {\r\n                if(error) {\r\n                    return res.status(400).send(error);\r\n                }\r\n                res.send(urlObj);\r\n            });\r\n        } else {\r\n            res.send(url[0]);\r\n        }\r\n    });\r\n});<\/code><\/pre>\n<p>O endpoint acima \u00e9 um endpoint de solicita\u00e7\u00e3o POST que espera um corpo. Se nenhuma URL longa for encontrada no corpo, ser\u00e1 retornado um erro. Caso contr\u00e1rio, ser\u00e1 feita uma pesquisa otomana com base no URL longo fornecido. Se forem encontrados dados na pesquisa, esses dados ser\u00e3o retornados ao usu\u00e1rio; caso contr\u00e1rio, ser\u00e1 iniciado um processo para criar uma nova entrada.<\/p>\n<p>Durante a cria\u00e7\u00e3o da nova entrada, um hash exclusivo \u00e9 criado com base no registro de data e hora. Esse hash \u00e9 anexado a um nome de host curto e salvo no banco de dados junto com o pr\u00f3prio hash e a URL longa. O objeto \u00e9 retornado ap\u00f3s um salvamento bem-sucedido.<\/p>\n<p>Quando se trata de <strong>\/expandir<\/strong> temos o seguinte:<\/p>\n<pre><code>app.get(\"\/expand\", function(req, res) {\r\n    if(!req.query.shortUrl) {\r\n        return res.status(400).send({\"status\": \"error\", \"message\": \"A short URL is required\"});\r\n    }\r\n    UrlModel.find({\"shortUrl\": req.query.shortUrl}, function(error, url) {\r\n        if(error) {\r\n            return res.status(400).send(error);\r\n        }\r\n        res.send(url.length &gt; 0 ? url[0] : {});\r\n    });\r\n});<\/code><\/pre>\n<p>O m\u00e9todo \u00e9 semelhante ao que vimos no <strong>\/criar<\/strong> mas n\u00e3o \u00e9 exatamente o mesmo. Em vez disso, fazemos uma pesquisa com base no URL curto fornecido. Se for encontrado, retornamos o documento que cont\u00e9m o URL longo; caso contr\u00e1rio, retornamos um objeto vazio.<\/p>\n<p>Por fim, temos o <strong>raiz<\/strong> endpoint. Esse endpoint \u00e9 respons\u00e1vel pelo redirecionamento para o URL longo e requer um ID que, na realidade, \u00e9 o nosso hash. Lembre-se de que estamos hospedando a API e os URLs curtos no mesmo servidor.<\/p>\n<pre><code>app.get(\"\/:id\", function(req, res) {\r\n    if(!req.params.id) {\r\n        return res.status(400).send({\"status\": \"error\", \"message\": \"An id is required\"});\r\n    }\r\n    UrlModel.getById(req.params.id, function(error, url) {\r\n        if(error) {\r\n            return res.status(400).send(error);\r\n        }\r\n        res.redirect(url.longUrl);\r\n    });\r\n});<\/code><\/pre>\n<p>Ent\u00e3o, digamos que navegamos para <strong>https:\/\/localhost:3000\/2xmx9qpyj<\/strong> no navegador. Os <strong>2xmx9qpyj<\/strong> \u00e9 o nosso ID, que tamb\u00e9m \u00e9 o nosso valor de hash. Podemos fazer uma pesquisa de documento com base nesse ID e navegar se ele existir.<\/p>\n<p>N\u00e3o \u00e9 t\u00e3o ruim, certo?<\/p>\n<h3 id=\"the-full-application-source-code\">O c\u00f3digo-fonte completo do aplicativo<\/h3>\n<p>Caso queira ver o aplicativo completo reunido, voc\u00ea pode encontr\u00e1-lo abaixo.<\/p>\n<pre><code>var Couchbase = require(\"couchbase\");\r\nvar Ottoman = require(\"ottoman\");\r\nvar Express = require(\"express\");\r\nvar BodyParser = require(\"body-parser\");\r\nvar Hashids = require(\"hashids\");\r\n\r\nvar app = Express();\r\n\r\napp.use(BodyParser.json());\r\napp.use(BodyParser.urlencoded({ extended: true }));\r\n\r\nOttoman.bucket = (new Couchbase.Cluster(\"couchbase:\/\/localhost\")).openBucket(\"example\");\r\n\r\nvar UrlModel = Ottoman.model(\"Url\", {\r\n    hash: {type: \"string\", readonly: true},\r\n    longUrl: \"string\",\r\n    shortUrl: \"string\"\r\n}, {\r\n    id: \"hash\"\r\n});\r\n\r\napp.get(\"\/expand\", function(req, res) {\r\n    if(!req.query.shortUrl) {\r\n        return res.status(400).send({\"status\": \"error\", \"message\": \"A short URL is required\"});\r\n    }\r\n    UrlModel.find({\"shortUrl\": req.query.shortUrl}, function(error, url) {\r\n        if(error) {\r\n            return res.status(400).send(error);\r\n        }\r\n        res.send(url.length &gt; 0 ? url[0] : {});\r\n    });\r\n});\r\n\r\napp.post(\"\/create\", function(req, res) {\r\n    if(!req.body.longUrl) {\r\n        return res.status(400).send({\"status\": \"error\", \"message\": \"A long URL is required\"});\r\n    }\r\n    UrlModel.find({\"longUrl\": req.body.longUrl}, function(error, url) {\r\n        if(error) {\r\n            return res.status(400).send(error);\r\n        }\r\n        if(url.length == 0) {\r\n            var hashids = new Hashids();\r\n            var urlObj = new UrlModel({\r\n                hash: hashids.encode((new Date).getTime()),\r\n                longUrl: req.body.longUrl\r\n            });\r\n            urlObj.shortUrl = \"https:\/\/localhost:3000\/\" + urlObj.hash;\r\n            urlObj.save(function(error, result) {\r\n                if(error) {\r\n                    return res.status(400).send(error);\r\n                }\r\n                res.send(urlObj);\r\n            });\r\n        } else {\r\n            res.send(url[0]);\r\n        }\r\n    });\r\n});\r\n\r\napp.get(\"\/:id\", function(req, res) {\r\n    if(!req.params.id) {\r\n        return res.status(400).send({\"status\": \"error\", \"message\": \"An id is required\"});\r\n    }\r\n    UrlModel.getById(req.params.id, function(error, url) {\r\n        if(error) {\r\n            return res.status(400).send(error);\r\n        }\r\n        res.redirect(url.longUrl);\r\n    });\r\n});\r\n\r\nOttoman.ensureIndices(function(error) {\r\n    if(error) {\r\n        console.log(error);\r\n    }\r\n    var server = app.listen(3000, function() {\r\n        console.log(\"Listening on port %s...\", server.address().port);\r\n    });\r\n});<\/code><\/pre>\n<p>Se voc\u00ea executar o c\u00f3digo acima com <code>npm index.js<\/code> voc\u00ea pode come\u00e7ar a usar cada um dos pontos de extremidade da API encontrados em <strong>https:\/\/localhost:3000<\/strong>.<\/p>\n<h2 id=\"conclusion\">Conclus\u00e3o<\/h2>\n<p>Voc\u00ea acabou de ver como criar um aplicativo encurtador de URL usando um modelo de documento de objeto (ODM) chamado Ottoman, Couchbase Server e Node.js. Se n\u00e3o for f\u00e3 de ODMs ou se quiser ver como fazer isso com consultas SQL, voc\u00ea pode conferir um <a href=\"https:\/\/www.couchbase.com\/blog\/pt\/create-a-url-shortener-with-nodejs-and-couchbase-using-n1ql\/\">tutorial anterior<\/a> Escrevi sobre o assunto.<\/p>\n<p>Deseja levar este tutorial um passo adiante? Por que n\u00e3o tentar coletar informa\u00e7\u00f5es anal\u00edticas das pessoas que tentam usar os URLs curtos? Voc\u00ea pode manter um contador de ocorr\u00eancias dentro dos documentos antes da navega\u00e7\u00e3o ou at\u00e9 mesmo armazenar informa\u00e7\u00f5es como agentes de usu\u00e1rio do navegador.<\/p>","protected":false},"excerpt":{"rendered":"<p>Not too long ago I wrote about creating a URL shortener with Node.js and Couchbase N1QL. If you haven&#8217;t already seen it, the article is a great introduction to Couchbase and creating RESTful APIs using Node.js and Express Framework. The [&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":[1815,1822,10128],"tags":[1510,1768,1767],"ppma_author":[9032],"class_list":["post-2448","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-best-practices-and-tutorials","category-node-js","category-ottoman","tag-odm","tag-short-hash","tag-url-shortener"],"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>URL Shortener using Ottoman ODM with Node.js &amp; Couchbase<\/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\/create-a-url-shortener-using-ottoman-odm-with-nodejs-and-couchbase\/\" \/>\n<meta property=\"og:locale\" content=\"pt_BR\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Create a URL Shortener using Ottoman ODM with Node.js and Couchbase\" \/>\n<meta property=\"og:description\" content=\"Not too long ago I wrote about creating a URL shortener with Node.js and Couchbase N1QL. If you haven&#8217;t already seen it, the article is a great introduction to Couchbase and creating RESTful APIs using Node.js and Express Framework. The [&hellip;]\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.couchbase.com\/blog\/pt\/create-a-url-shortener-using-ottoman-odm-with-nodejs-and-couchbase\/\" \/>\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=\"2016-12-20T15:00:00+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2025-06-14T04:40:24+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=\"8 minutos\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/create-a-url-shortener-using-ottoman-odm-with-nodejs-and-couchbase\/#article\",\"isPartOf\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/create-a-url-shortener-using-ottoman-odm-with-nodejs-and-couchbase\/\"},\"author\":{\"name\":\"Nic Raboy, Developer Advocate, Couchbase\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/#\/schema\/person\/bb545ebe83bb2d12f91095811d0a72e1\"},\"headline\":\"Create a URL Shortener using Ottoman ODM with Node.js and Couchbase\",\"datePublished\":\"2016-12-20T15:00:00+00:00\",\"dateModified\":\"2025-06-14T04:40:24+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/create-a-url-shortener-using-ottoman-odm-with-nodejs-and-couchbase\/\"},\"wordCount\":1363,\"commentCount\":0,\"publisher\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/#organization\"},\"image\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/create-a-url-shortener-using-ottoman-odm-with-nodejs-and-couchbase\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2022\/11\/couchbase-nosql-dbaas.png\",\"keywords\":[\"odm\",\"short hash\",\"url shortener\"],\"articleSection\":[\"Best Practices and Tutorials\",\"Node.js\",\"Ottoman.js ODM\"],\"inLanguage\":\"pt-BR\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\/\/www.couchbase.com\/blog\/create-a-url-shortener-using-ottoman-odm-with-nodejs-and-couchbase\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/create-a-url-shortener-using-ottoman-odm-with-nodejs-and-couchbase\/\",\"url\":\"https:\/\/www.couchbase.com\/blog\/create-a-url-shortener-using-ottoman-odm-with-nodejs-and-couchbase\/\",\"name\":\"URL Shortener using Ottoman ODM with Node.js & Couchbase\",\"isPartOf\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/create-a-url-shortener-using-ottoman-odm-with-nodejs-and-couchbase\/#primaryimage\"},\"image\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/create-a-url-shortener-using-ottoman-odm-with-nodejs-and-couchbase\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2022\/11\/couchbase-nosql-dbaas.png\",\"datePublished\":\"2016-12-20T15:00:00+00:00\",\"dateModified\":\"2025-06-14T04:40:24+00:00\",\"breadcrumb\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/create-a-url-shortener-using-ottoman-odm-with-nodejs-and-couchbase\/#breadcrumb\"},\"inLanguage\":\"pt-BR\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/www.couchbase.com\/blog\/create-a-url-shortener-using-ottoman-odm-with-nodejs-and-couchbase\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"pt-BR\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/create-a-url-shortener-using-ottoman-odm-with-nodejs-and-couchbase\/#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\/create-a-url-shortener-using-ottoman-odm-with-nodejs-and-couchbase\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/www.couchbase.com\/blog\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Create a URL Shortener using Ottoman ODM with Node.js and Couchbase\"}]},{\"@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":"URL Shortener using Ottoman ODM with Node.js & Couchbase","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\/create-a-url-shortener-using-ottoman-odm-with-nodejs-and-couchbase\/","og_locale":"pt_BR","og_type":"article","og_title":"Create a URL Shortener using Ottoman ODM with Node.js and Couchbase","og_description":"Not too long ago I wrote about creating a URL shortener with Node.js and Couchbase N1QL. If you haven&#8217;t already seen it, the article is a great introduction to Couchbase and creating RESTful APIs using Node.js and Express Framework. The [&hellip;]","og_url":"https:\/\/www.couchbase.com\/blog\/pt\/create-a-url-shortener-using-ottoman-odm-with-nodejs-and-couchbase\/","og_site_name":"The Couchbase Blog","article_author":"https:\/\/www.facebook.com\/thepolyglotdeveloper","article_published_time":"2016-12-20T15:00:00+00:00","article_modified_time":"2025-06-14T04:40:24+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":"8 minutos"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/www.couchbase.com\/blog\/create-a-url-shortener-using-ottoman-odm-with-nodejs-and-couchbase\/#article","isPartOf":{"@id":"https:\/\/www.couchbase.com\/blog\/create-a-url-shortener-using-ottoman-odm-with-nodejs-and-couchbase\/"},"author":{"name":"Nic Raboy, Developer Advocate, Couchbase","@id":"https:\/\/www.couchbase.com\/blog\/#\/schema\/person\/bb545ebe83bb2d12f91095811d0a72e1"},"headline":"Create a URL Shortener using Ottoman ODM with Node.js and Couchbase","datePublished":"2016-12-20T15:00:00+00:00","dateModified":"2025-06-14T04:40:24+00:00","mainEntityOfPage":{"@id":"https:\/\/www.couchbase.com\/blog\/create-a-url-shortener-using-ottoman-odm-with-nodejs-and-couchbase\/"},"wordCount":1363,"commentCount":0,"publisher":{"@id":"https:\/\/www.couchbase.com\/blog\/#organization"},"image":{"@id":"https:\/\/www.couchbase.com\/blog\/create-a-url-shortener-using-ottoman-odm-with-nodejs-and-couchbase\/#primaryimage"},"thumbnailUrl":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2022\/11\/couchbase-nosql-dbaas.png","keywords":["odm","short hash","url shortener"],"articleSection":["Best Practices and Tutorials","Node.js","Ottoman.js ODM"],"inLanguage":"pt-BR","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/www.couchbase.com\/blog\/create-a-url-shortener-using-ottoman-odm-with-nodejs-and-couchbase\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/www.couchbase.com\/blog\/create-a-url-shortener-using-ottoman-odm-with-nodejs-and-couchbase\/","url":"https:\/\/www.couchbase.com\/blog\/create-a-url-shortener-using-ottoman-odm-with-nodejs-and-couchbase\/","name":"URL Shortener using Ottoman ODM with Node.js & Couchbase","isPartOf":{"@id":"https:\/\/www.couchbase.com\/blog\/#website"},"primaryImageOfPage":{"@id":"https:\/\/www.couchbase.com\/blog\/create-a-url-shortener-using-ottoman-odm-with-nodejs-and-couchbase\/#primaryimage"},"image":{"@id":"https:\/\/www.couchbase.com\/blog\/create-a-url-shortener-using-ottoman-odm-with-nodejs-and-couchbase\/#primaryimage"},"thumbnailUrl":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2022\/11\/couchbase-nosql-dbaas.png","datePublished":"2016-12-20T15:00:00+00:00","dateModified":"2025-06-14T04:40:24+00:00","breadcrumb":{"@id":"https:\/\/www.couchbase.com\/blog\/create-a-url-shortener-using-ottoman-odm-with-nodejs-and-couchbase\/#breadcrumb"},"inLanguage":"pt-BR","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.couchbase.com\/blog\/create-a-url-shortener-using-ottoman-odm-with-nodejs-and-couchbase\/"]}]},{"@type":"ImageObject","inLanguage":"pt-BR","@id":"https:\/\/www.couchbase.com\/blog\/create-a-url-shortener-using-ottoman-odm-with-nodejs-and-couchbase\/#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\/create-a-url-shortener-using-ottoman-odm-with-nodejs-and-couchbase\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/www.couchbase.com\/blog\/"},{"@type":"ListItem","position":2,"name":"Create a URL Shortener using Ottoman ODM with Node.js and Couchbase"}]},{"@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\/2448","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=2448"}],"version-history":[{"count":0,"href":"https:\/\/www.couchbase.com\/blog\/pt\/wp-json\/wp\/v2\/posts\/2448\/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=2448"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/pt\/wp-json\/wp\/v2\/categories?post=2448"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/pt\/wp-json\/wp\/v2\/tags?post=2448"},{"taxonomy":"author","embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/pt\/wp-json\/wp\/v2\/ppma_author?post=2448"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}