{"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\/es\/create-a-url-shortener-using-ottoman-odm-with-nodejs-and-couchbase\/","title":{"rendered":"Crear un acortador de URL usando Ottoman ODM con Node.js y Couchbase"},"content":{"rendered":"<p>No hace mucho escrib\u00ed sobre <a href=\"https:\/\/www.couchbase.com\/blog\/es\/create-a-url-shortener-with-nodejs-and-couchbase-using-n1ql\/\">crear un acortador de URL con Node.js y Couchbase N1QL<\/a>. Si a\u00fan no lo has visto, el art\u00edculo es una gran introducci\u00f3n a Couchbase y a la creaci\u00f3n de API RESTful. <a href=\"https:\/\/www.couchbase.com\/blog\/es\/build-a-rest-api-with-node-js-express-and-couchbase\/\">usando Node.js<\/a> y Express Framework. La trampa detr\u00e1s de ese art\u00edculo, y no es una mala trampa, es que usted tiene que preferir escribir consultas SQL para gestionar sus datos NoSQL.<\/p>\n<p>\u00bfY si prefiere utilizar un Modelo de Documento Objeto (MDO) en lugar de escribir consultas?<\/p>\n<p>Esta vez vamos a explorar el proceso de desarrollo detr\u00e1s de la creaci\u00f3n de un acortador de URL que utiliza Ottoman ODM, Couchbase Server y Node.js.<\/p>\n<h2 id=\"the-requirements\">Requisitos<\/h2>\n<p>No hay muchos requisitos cuando se trata del \u00e9xito de esta aplicaci\u00f3n. Por ejemplo, lo siguiente es lo que necesitar\u00e1s instalado y configurado:<\/p>\n<ul>\n<li>Servidor Couchbase 4.1+<\/li>\n<li>Node.js 4.0+<\/li>\n<\/ul>\n<p>Dado que se trata de una aplicaci\u00f3n Node.js, necesitaremos tenerlo instalado y usaremos Node Package Manager (NPM) para reunir todas las dependencias de nuestro proyecto. Para sacar el m\u00e1ximo provecho de Ottoman vamos a querer utilizar Couchbase 4.1 o superior.<\/p>\n<h2 id=\"understanding-the-data-model-and-preparing-the-couchbase-database\">Comprender el modelo de datos y preparar la base de datos Couchbase<\/h2>\n<p>Para este ejemplo vamos a crear un cubo llamado <strong>ejemplo<\/strong> en Couchbase Server. No es necesario llamarlo as\u00ed, pero a lo largo del art\u00edculo nos referiremos a \u00e9l como tal. No se requieren \u00edndices o configuraciones adicionales en nuestro cluster m\u00e1s all\u00e1 de la creaci\u00f3n del bucket.<\/p>\n<p>En cuanto a los datos, el plan es almacenar un documento por cada URL que queramos reducir. Cada documento podr\u00eda ser algo como esto:<\/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>En <code>Tipo<\/code> es algo definido por el modelo Ottoman, pero las otras tres son propiedades que vamos a definir. El hash va a representar un hash \u00fanico de un valor. Este hash va a actuar como el identificador en cada una de nuestras URLs cortas.<\/p>\n<h2 id=\"developing-the-node.js-url-shortener-application\">Desarrollo de la aplicaci\u00f3n Node.js URL Shortener<\/h2>\n<p>Con la base de datos lista y una comprensi\u00f3n b\u00e1sica de nuestro modelo de datos, podemos trabajar en la creaci\u00f3n de nuestra aplicaci\u00f3n de acortador de URL Node.js. La aplicaci\u00f3n depender\u00e1 en gran medida de Express Framework y una biblioteca llamada <a href=\"https:\/\/www.npmjs.com\/package\/hashids\">Hach\u00eds<\/a>. Vamos a utilizar Hashids para ahorrarnos la molestia de tener que escribir nuestro propio algoritmo de hash corto.<\/p>\n<h3 id=\"creating-the-project-with-the-dependencies\">Creaci\u00f3n del proyecto con las dependencias<\/h3>\n<p>Empecemos creando un nuevo proyecto Node.js e instalando todas las dependencias necesarias del proyecto. Desde el Terminal (Mac y Linux) o S\u00edmbolo del sistema (Windows), ejecute lo siguiente:<\/p>\n<pre><code>npm init --y<\/code><\/pre>\n<p>El comando anterior crear\u00e1 un nuevo <strong>paquete.json<\/strong> para nuestro proyecto. Este archivo contendr\u00e1 toda la informaci\u00f3n de dependencia, as\u00ed como otras cosas.<\/p>\n<p>Ahora tenemos que instalar cada una de las dependencias necesarias en nuestro proyecto:<\/p>\n<pre><code>npm install couchbase express ottoman body-parser hashids --save<\/code><\/pre>\n<p>El comando anterior instalar\u00e1 el SDK de Couchbase, Express Framework, Ottoman, Hashids, y la librer\u00eda Body Parser para aceptar datos del cuerpo en peticiones HTTP.<\/p>\n<p>En este punto podemos empezar a arrancar la aplicaci\u00f3n para prepararla para el trabajo pesado.<\/p>\n<h3 id=\"bootstrapping-the-application\">Puesta en marcha de la aplicaci\u00f3n<\/h3>\n<p>Para simplificar las cosas, todo el c\u00f3digo de nuestra aplicaci\u00f3n residir\u00e1 en un \u00fanico archivo dentro de nuestro proyecto llamado <strong>index.js<\/strong>. En un entorno de producci\u00f3n es probable que desee dividirlo para facilitar el mantenimiento, pero para este ejemplo muy simple que va a estar bien.<\/p>\n<p>Abra el <strong>index.js<\/strong> e incluir importaciones a cada una de las dependencias 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>Con las dependencias importadas, ahora podemos inicializarlas para su uso dentro de la aplicaci\u00f3n:<\/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>En lo anterior estamos diciendo esencialmente que queremos inicializar Express Framework y aceptar JSON y datos del cuerpo codificados en URL de las solicitudes.<\/p>\n<p>En este punto podemos establecer una conexi\u00f3n con nuestro cluster Couchbase y abrir el bucket de la aplicaci\u00f3n:<\/p>\n<pre><code>Ottoman.bucket = (new Couchbase.Cluster(\"couchbase:\/\/localhost\")).openBucket(\"example\");<\/code><\/pre>\n<p>Para utilizar Ottoman es necesario que existan ciertos \u00edndices. Por suerte podemos hacer que Ottoman cree estos \u00edndices por nosotros si a\u00fan no existen. Cuando estemos seguros de que existen, podemos empezar a servir la aplicaci\u00f3n.<\/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>En nuestro ejemplo la aplicaci\u00f3n servir\u00e1 localmente en el puerto 3000.<\/p>\n<p>Hasta ahora s\u00f3lo tenemos el framework base funcionando para nuestra aplicaci\u00f3n de acortador de URL. En realidad no tenemos ninguna l\u00f3gica de acortamiento o interacci\u00f3n con la base de datos en lo que respecta a operaciones CRUD o de consulta.<\/p>\n<h3 id=\"creating-the-data-model\">Creaci\u00f3n del modelo de datos<\/h3>\n<p>Sabemos c\u00f3mo se ver\u00e1n los datos en la base de datos, pero a\u00fan no sabemos c\u00f3mo crearlos. Dado que estamos utilizando un ODM en lugar de consultas N1QL tenemos que definir el modelo dentro de nuestro c\u00f3digo.<\/p>\n<p>En este proyecto concreto, el modelo es muy simplista. Se ver\u00eda as\u00ed:<\/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>En el modelo de datos anterior, que llamamos <code>Url<\/code>tenemos tres propiedades. El <code>hash<\/code> representar\u00e1 el id de nuestro documento. No es un requisito establecer manualmente el id del documento, pero para este proyecto tiene sentido. Establecer manualmente un id de documento requiere que la propiedad sea de s\u00f3lo lectura. Las otras dos propiedades son valores de cadena est\u00e1ndar.<\/p>\n<p>El modelo puede ser infinitamente m\u00e1s complejo en funci\u00f3n de sus necesidades.<\/p>\n<h3 id=\"applying-the-data-model-in-a-series-of-restful-endpoint-methods\">Aplicaci\u00f3n del modelo de datos en una serie de m\u00e9todos RESTful Endpoint<\/h3>\n<p>La aplicaci\u00f3n que estamos construyendo es un servicio web RESTful por lo que necesitamos crear algunas funciones endpoint. La aplicaci\u00f3n contendr\u00e1 los siguientes tres endpoints p\u00fablicos:<\/p>\n<pre><code>\/\r\n\/create\r\n\/expand<\/code><\/pre>\n<p>Cuando el <strong>ra\u00edz<\/strong> la aplicaci\u00f3n nos llevar\u00e1 a la URL larga almacenada en Couchbase. Cuando el <strong>\/crear<\/strong> intentaremos encontrar una URL corta previamente guardada o crear una si no existe. Hacemos esto porque no queremos guardar m\u00faltiples copias de una URL larga. Finalmente tenemos un <strong>\/ampliar<\/strong> para que podamos ver a d\u00f3nde va nuestra URL corta.<\/p>\n<p>Empezando por el <strong>\/crear<\/strong> tenemos el siguiente m\u00e9todo, que es probablemente la parte m\u00e1s compleja de nuestra aplicaci\u00f3n:<\/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>El punto final anterior es un punto final de solicitud POST que espera un cuerpo. Si no se encuentra una URL larga en el cuerpo, se devolver\u00e1 un error. En caso contrario, se realizar\u00e1 una b\u00fasqueda otomana basada en la URL larga proporcionada. Si se encuentran datos en la b\u00fasqueda, esos datos se devolver\u00e1n al usuario, de lo contrario se iniciar\u00e1 un proceso para crear una nueva entrada.<\/p>\n<p>Durante la creaci\u00f3n de una nueva entrada, se crea un hash \u00fanico basado en la marca de tiempo. Este hash se a\u00f1ade a un nombre de host corto y se guarda en la base de datos junto con el propio hash y la URL larga. El objeto se devuelve cuando se ha guardado correctamente.<\/p>\n<p>Cuando se trata de la <strong>\/ampliar<\/strong> tenemos lo siguiente:<\/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>El m\u00e9todo es similar al que vimos en el <strong>\/crear<\/strong> pero no es exactamente lo mismo. En su lugar, hacemos una b\u00fasqueda basada en la URL corta proporcionada. Si se encuentra, devuelve el documento que contiene la URL larga; en caso contrario, devuelve un objeto vac\u00edo.<\/p>\n<p>Por \u00faltimo, tenemos el <strong>ra\u00edz<\/strong> endpoint. Este endpoint es responsable de la redirecci\u00f3n a la URL larga y requiere un id que en realidad es nuestro hash. Recuerda, estamos alojando la API y las URLs cortas en el mismo 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>Digamos que navegamos a <strong>https:\/\/localhost:3000\/2xmx9qpyj<\/strong> en el navegador. El sitio <strong>2xmx9qpyj<\/strong> es nuestro id, que es tambi\u00e9n nuestro valor hash. Podemos hacer una b\u00fasqueda de documentos basada en este id y navegar si existe.<\/p>\n<p>No est\u00e1 mal, \u00bfverdad?<\/p>\n<h3 id=\"the-full-application-source-code\">El c\u00f3digo fuente completo de la aplicaci\u00f3n<\/h3>\n<p>En caso de que desee ver toda la aplicaci\u00f3n reunida, puede encontrarla a continuaci\u00f3n.<\/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>Si ejecuta el c\u00f3digo anterior con <code>npm index.js<\/code> puede empezar a utilizar cada uno de los puntos finales de la API que se encuentran en <strong>https:\/\/localhost:3000<\/strong>.<\/p>\n<h2 id=\"conclusion\">Conclusi\u00f3n<\/h2>\n<p>Acabas de ver c\u00f3mo crear una aplicaci\u00f3n acortadora de URLs usando un Modelo de Documento Objeto (ODM) llamado Ottoman, Couchbase Server y Node.js. Si no eres un fan de los ODMs o quieres ver c\u00f3mo hacer esto con consultas SQL, puedes echar un vistazo a un art\u00edculo de <a href=\"https:\/\/www.couchbase.com\/blog\/es\/create-a-url-shortener-with-nodejs-and-couchbase-using-n1ql\/\">tutorial anterior<\/a> Escrib\u00ed sobre el tema.<\/p>\n<p>\u00bfQuieres llevar este tutorial un paso m\u00e1s all\u00e1? \u00bfPor qu\u00e9 no intentar recopilar informaci\u00f3n anal\u00edtica de las personas que intentan utilizar las URL cortas? Podr\u00edas mantener un contador de visitas dentro de los documentos antes de la navegaci\u00f3n o incluso almacenar informaci\u00f3n como los agentes de usuario del 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 v25.9 (Yoast SEO v25.9) - 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\/es\/create-a-url-shortener-using-ottoman-odm-with-nodejs-and-couchbase\/\" \/>\n<meta property=\"og:locale\" content=\"es_MX\" \/>\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\/es\/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\":\"es\",\"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\":\"es\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/www.couchbase.com\/blog\/create-a-url-shortener-using-ottoman-odm-with-nodejs-and-couchbase\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"es\",\"@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\":\"es\"},{\"@type\":\"Organization\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/#organization\",\"name\":\"The Couchbase Blog\",\"url\":\"https:\/\/www.couchbase.com\/blog\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"es\",\"@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\":\"es\",\"@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\/es\/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\/es\/create-a-url-shortener-using-ottoman-odm-with-nodejs-and-couchbase\/","og_locale":"es_MX","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\/es\/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":"es","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":"es","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.couchbase.com\/blog\/create-a-url-shortener-using-ottoman-odm-with-nodejs-and-couchbase\/"]}]},{"@type":"ImageObject","inLanguage":"es","@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":"El blog de Couchbase","description":"Couchbase, la base de datos 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":"es"},{"@type":"Organization","@id":"https:\/\/www.couchbase.com\/blog\/#organization","name":"El blog de Couchbase","url":"https:\/\/www.couchbase.com\/blog\/","logo":{"@type":"ImageObject","inLanguage":"es","@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 del Desarrollador, Couchbase","image":{"@type":"ImageObject","inLanguage":"es","@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 es un defensor de las tecnolog\u00edas modernas de desarrollo web y m\u00f3vil. Tiene experiencia en Java, JavaScript, Golang y una variedad de frameworks como Angular, NativeScript y Apache Cordova. Nic escribe sobre sus experiencias de desarrollo relacionadas con hacer el desarrollo web y m\u00f3vil m\u00e1s f\u00e1cil de entender.","sameAs":["https:\/\/www.thepolyglotdeveloper.com","https:\/\/www.facebook.com\/thepolyglotdeveloper","https:\/\/x.com\/nraboy"],"url":"https:\/\/www.couchbase.com\/blog\/es\/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 es un defensor de las tecnolog\u00edas modernas de desarrollo web y m\u00f3vil. Tiene experiencia en Java, JavaScript, Golang y una variedad de frameworks como Angular, NativeScript y Apache Cordova. Nic escribe sobre sus experiencias de desarrollo relacionadas con hacer el desarrollo web y m\u00f3vil m\u00e1s f\u00e1cil de entender."}],"_links":{"self":[{"href":"https:\/\/www.couchbase.com\/blog\/es\/wp-json\/wp\/v2\/posts\/2448","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.couchbase.com\/blog\/es\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.couchbase.com\/blog\/es\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/es\/wp-json\/wp\/v2\/users\/63"}],"replies":[{"embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/es\/wp-json\/wp\/v2\/comments?post=2448"}],"version-history":[{"count":0,"href":"https:\/\/www.couchbase.com\/blog\/es\/wp-json\/wp\/v2\/posts\/2448\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/es\/wp-json\/wp\/v2\/media\/13873"}],"wp:attachment":[{"href":"https:\/\/www.couchbase.com\/blog\/es\/wp-json\/wp\/v2\/media?parent=2448"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/es\/wp-json\/wp\/v2\/categories?post=2448"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/es\/wp-json\/wp\/v2\/tags?post=2448"},{"taxonomy":"author","embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/es\/wp-json\/wp\/v2\/ppma_author?post=2448"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}