{"id":1614,"date":"2014-12-16T19:32:00","date_gmt":"2014-12-16T19:31:59","guid":{"rendered":"https:\/\/www.couchbase.com\/blog\/?p=1614"},"modified":"2023-06-28T00:24:10","modified_gmt":"2023-06-28T07:24:10","slug":"game-servers-and-couchbase-nodejs-part-1","status":"publish","type":"post","link":"https:\/\/www.couchbase.com\/blog\/es\/game-servers-and-couchbase-nodejs-part-1\/","title":{"rendered":"Servidores de juegos y Couchbase con Node.js - Parte 1"},"content":{"rendered":"<p>Parece que hoy en d\u00eda casi todos los estudios de videojuegos est\u00e1n trabajando en juegos en red en los que los jugadores pueden interactuar y cooperar con sus amigos y con otros jugadores de todo el mundo. Teniendo en cuenta mi experiencia previa en la construcci\u00f3n de este tipo de servidores y que Couchbase encaja como un almac\u00e9n de respaldo para un sistema como este, pens\u00e9 que tal vez este podr\u00eda ser un excelente tema para escribir. Estar\u00e9 escribiendo esto en m\u00faltiples partes con cada parte implementando un aspecto espec\u00edfico del servidor de juego, adicionalmente, estar\u00e9 haciendo el mismo tutorial usando nuestra librer\u00eda cliente PHP para mostrar eso tambi\u00e9n.<\/p>\n<h1>Dise\u00f1o del proyecto<\/h1>\n<p>Para empezar, necesitamos configurar algunas cosas b\u00e1sicas que nos permitan enviar y recibir peticiones HTTP as\u00ed como conectarnos a nuestro cluster de Couchbase. Si a\u00fan no est\u00e1s seguro de c\u00f3mo hacer esto, por favor echa un vistazo a mi <a href=\"https:\/\/www.couchbase.com\/blog\/es\/intro-and-couchnode-100\/\">entrada anterior<\/a> donde lo explico con un poco m\u00e1s de detalle de lo que lo har\u00e9 a continuaci\u00f3n. Vamos a empezar nuestro proyecto con una estructura de directorios t\u00edpica de Node.js con algunas carpetas adicionales para ayudar a organizar el c\u00f3digo del servidor del juego.<\/p>\n<div class=\"geshifilter\">\n<div class=\"text geshifilter-text\" style=\"font-family: monospace\">\/lib\/<br \/>\n\/lib\/models\/<br \/>\n\/lib\/app.js<br \/>\n\/lib\/database.js<br \/>\n\/paquete.json<\/div>\n<\/div>\n<p>Siguiendo la estructura normal de Node.js, empezamos con nuestra carpeta 'lib' para guardar todos nuestros archivos fuente, con lib\/server.js para actuar como archivo principal y finalmente nuestro package.json para describir las dependencias del proyecto y otros metadatos. Adem\u00e1s, a\u00f1adimos un database.js que gestionar\u00e1 de forma centralizada nuestra conexi\u00f3n a la base de datos para evitar que tengamos que instanciar una nueva conexi\u00f3n para cada solicitud, as\u00ed como la carpeta \/lib\/models\/ que utilizaremos para guardar el c\u00f3digo fuente de nuestros distintos modelos de base de datos.<\/p>\n<h1>Conceptos b\u00e1sicos<\/h1>\n<p>Here is some content for your package.json. We give our project a name, point to its main Javascript file and then define a couple of prerequisite modules we will need later on. Once you have saved this file, executing `npm install` in your project root directory should install the referenced dependancies.<\/p>\n<div class=\"geshifilter\">\n<div class=\"javascript geshifilter-javascript\" style=\"font-family: monospace\"><span style=\"color: #009900\">{<\/span><br \/>\n<span style=\"color: #3366cc\">\"principal\"<\/span><span style=\"color: #339933\">:<\/span> <span style=\"color: #3366cc\">\".\/lib\/app\"<\/span><span style=\"color: #339933\">,<\/span><br \/>\n<span style=\"color: #3366cc\">\"licencia\"<\/span> <span style=\"color: #339933\">:<\/span> <span style=\"color: #3366cc\">\"Apache2\"<\/span><span style=\"color: #339933\">,<\/span><br \/>\n<span style=\"color: #3366cc\">\"nombre\"<\/span><span style=\"color: #339933\">:<\/span> <span style=\"color: #3366cc\">\"gameapi-couchbase\"<\/span><span style=\"color: #339933\">,<\/span><br \/>\n<span style=\"color: #3366cc\">\"dependencias\"<\/span><span style=\"color: #339933\">:<\/span> <span style=\"color: #009900\">{<\/span><br \/>\n<span style=\"color: #3366cc\">\"couchbase\"<\/span><span style=\"color: #339933\">:<\/span> <span style=\"color: #3366cc\">\u201c~1.0.0\u201d<\/span><span style=\"color: #339933\">,<\/span><br \/>\n<span style=\"color: #3366cc\">\"express\"<\/span><span style=\"color: #339933\">:<\/span> <span style=\"color: #3366cc\">\u201c~3.4.0\u201d<\/span><span style=\"color: #339933\">,<\/span><br \/>\n<span style=\"color: #3366cc\">\"uuid\"<\/span><span style=\"color: #339933\">:<\/span> <span style=\"color: #3366cc\">\u201c~1.4.1\u201d<\/span><br \/>\n<span style=\"color: #009900\">}<\/span><span style=\"color: #339933\">,<\/span><br \/>\n<span style=\"color: #3366cc\">\"devDependencias\"<\/span><span style=\"color: #339933\">:<\/span> <span style=\"color: #009900\">{<\/span><br \/>\n<span style=\"color: #009900\">}<\/span><span style=\"color: #339933\">,<\/span><br \/>\n<span style=\"color: #3366cc\">\"version\"<\/span><span style=\"color: #339933\">:<\/span> <span style=\"color: #3366cc\">\u201c0.0.1\u201d<\/span><br \/>\n<span style=\"color: #009900\">}<\/span><\/div>\n<\/div>\n<p>Nuestro siguiente paso es configurar el n\u00facleo de nuestro servidor de juegos. Esto se coloca en nuestro \/lib\/app.js. Voy a ir a trav\u00e9s de las secciones de este archivo bloque por bloque, y proporcionar una explicaci\u00f3n de lo que est\u00e1 haciendo para cada uno.<\/p>\n<p>Primero tenemos que importar los m\u00f3dulos que vamos a necesitar en este archivo. En este momento s\u00f3lo necesitamos el m\u00f3dulo express para el enrutamiento HTTP y el an\u00e1lisis sint\u00e1ctico, pero m\u00e1s adelante en este tutorial vamos a a\u00f1adir m\u00e1s.<\/p>\n<div class=\"geshifilter\">\n<div class=\"javascript geshifilter-javascript\" style=\"font-family: monospace\"><\/div>\n<div class=\"javascript geshifilter-javascript\" style=\"font-family: monospace\"><span style=\"color: #003366;font-weight: bold\">var<\/span> express <span style=\"color: #339933\">=<\/span> requiere<span style=\"color: #009900\">(<\/span><span style=\"color: #3366cc\">expr\u00e9s<\/span><span style=\"color: #009900\">)<\/span><span style=\"color: #339933\">;<\/span><\/div>\n<\/div>\n<p>A continuaci\u00f3n, vamos a configurar express, adem\u00e1s adjuntamos el sub-m\u00f3dulo bodyParser de express para que podamos analizar los cuerpos JSON POST y PUT. Esto nos ayudar\u00e1 m\u00e1s adelante cuando nuestros clientes de juegos necesiten pasarnos bloques de datos JSON.<\/p>\n<div class=\"geshifilter\">\n<div class=\"javascript geshifilter-javascript\" style=\"font-family: monospace\"><\/div>\n<div class=\"javascript geshifilter-javascript\" style=\"font-family: monospace\"><span style=\"color: #003366;font-weight: bold\">var<\/span> aplicaci\u00f3n <span style=\"color: #339933\">=<\/span> express<span style=\"color: #009900\">(<\/span><span style=\"color: #009900\">)<\/span><span style=\"color: #339933\">;<\/span><br \/>\napp.<span style=\"color: #003366;font-weight: bold\">utilice<\/span><span style=\"color: #009900\">(<\/span>expr\u00e9s.<span style=\"color: #660066\">bodyParser<\/span><span style=\"color: #009900\">(<\/span><span style=\"color: #009900\">)<\/span><span style=\"color: #009900\">)<\/span><span style=\"color: #339933\">;<\/span><\/div>\n<\/div>\n<p>Para el \u00fanico prop\u00f3sito de demostraci\u00f3n, vamos a a\u00f1adir una ruta simple a nuestro servidor HTTP para manejar las peticiones a la ra\u00edz de nuestro servidor.<\/p>\n<div class=\"geshifilter\">\n<div class=\"javascript geshifilter-javascript\" style=\"font-family: monospace\"><\/div>\n<div class=\"javascript geshifilter-javascript\" style=\"font-family: monospace\">app.<span style=\"color: #660066\">consiga<\/span><span style=\"color: #009900\">(<\/span><span style=\"color: #3366cc\">\u2018\/\u2019<\/span><span style=\"color: #339933\">,<\/span> <span style=\"color: #003366;font-weight: bold\">funci\u00f3n<\/span><span style=\"color: #009900\">(<\/span>consulte<span style=\"color: #339933\">,<\/span> res<span style=\"color: #339933\">,<\/span> siguiente<span style=\"color: #009900\">)<\/span> <span style=\"color: #009900\">{<\/span><br \/>\nres.<span style=\"color: #660066\">enviar<\/span><span style=\"color: #009900\">(<\/span><span style=\"color: #009900\">{<\/span>esbirros<span style=\"color: #339933\">:<\/span> <span style=\"color: #3366cc\">\"\u00a1Incl\u00ednate ante m\u00ed porque soy la RA\u00cdZ!<\/span><span style=\"color: #009900\">}<\/span><span style=\"color: #009900\">)<\/span><span style=\"color: #339933\">;<\/span><br \/>\n<span style=\"color: #009900\">}<\/span><span style=\"color: #009900\">)<\/span><span style=\"color: #339933\">;<\/span><\/div>\n<\/div>\n<p>Por \u00faltimo, vamos a hacer que nuestro servidor HTTP escuche en el puerto 3000.<\/p>\n<div class=\"geshifilter\">\n<div class=\"javascript geshifilter-javascript\" style=\"font-family: monospace\"><\/div>\n<div class=\"javascript geshifilter-javascript\" style=\"font-family: monospace\">app.<span style=\"color: #660066\">escuche<\/span><span style=\"color: #009900\">(<\/span><span style=\"color: #cc0000\">3000<\/span><span style=\"color: #339933\">,<\/span> <span style=\"color: #003366;font-weight: bold\">funci\u00f3n<\/span> <span style=\"color: #009900\">(<\/span><span style=\"color: #009900\">)<\/span> <span style=\"color: #009900\">{<\/span><br \/>\nconsola.<span style=\"color: #660066\">registro<\/span><span style=\"color: #009900\">(<\/span><span style=\"color: #3366cc\">Escuchando en el puerto 3000<\/span><span style=\"color: #009900\">)<\/span><span style=\"color: #339933\">;<\/span><br \/>\n<span style=\"color: #009900\">}<\/span><span style=\"color: #009900\">)<\/span><span style=\"color: #339933\">;<\/span><\/div>\n<\/div>\n<p>Aqu\u00ed tienes una idea aproximada de c\u00f3mo deber\u00eda ser tu app.js hasta ahora:<\/p>\n<div class=\"geshifilter\">\n<div class=\"javascript geshifilter-javascript\" style=\"font-family: monospace\"><\/div>\n<div class=\"javascript geshifilter-javascript\" style=\"font-family: monospace\">\n<p><span style=\"color: #003366;font-weight: bold\">var<\/span> express <span style=\"color: #339933\">=<\/span> requiere<span style=\"color: #009900\">(<\/span><span style=\"color: #3366cc\">expr\u00e9s<\/span><span style=\"color: #009900\">)<\/span><span style=\"color: #339933\">;<\/span><\/p>\n<p><span style=\"color: #003366;font-weight: bold\">var<\/span> aplicaci\u00f3n <span style=\"color: #339933\">=<\/span> express<span style=\"color: #009900\">(<\/span><span style=\"color: #009900\">)<\/span><span style=\"color: #339933\">;<\/span><br \/>\napp.<span style=\"color: #003366;font-weight: bold\">utilice<\/span><span style=\"color: #009900\">(<\/span>expr\u00e9s.<span style=\"color: #660066\">bodyParser<\/span><span style=\"color: #009900\">(<\/span><span style=\"color: #009900\">)<\/span><span style=\"color: #009900\">)<\/span><span style=\"color: #339933\">;<\/span><\/p>\n<p>app.<span style=\"color: #660066\">consiga<\/span><span style=\"color: #009900\">(<\/span><span style=\"color: #3366cc\">\u2018\/\u2019<\/span><span style=\"color: #339933\">,<\/span> <span style=\"color: #003366;font-weight: bold\">funci\u00f3n<\/span><span style=\"color: #009900\">(<\/span>consulte<span style=\"color: #339933\">,<\/span> res<span style=\"color: #339933\">,<\/span> siguiente<span style=\"color: #009900\">)<\/span> <span style=\"color: #009900\">{<\/span><br \/>\nres.<span style=\"color: #660066\">enviar<\/span><span style=\"color: #009900\">(<\/span><span style=\"color: #009900\">{<\/span>esbirros<span style=\"color: #339933\">:<\/span> <span style=\"color: #3366cc\">\"\u00a1Incl\u00ednate ante m\u00ed porque soy la RA\u00cdZ!<\/span><span style=\"color: #009900\">}<\/span><span style=\"color: #009900\">)<\/span><span style=\"color: #339933\">;<\/span><br \/>\n<span style=\"color: #009900\">}<\/span><span style=\"color: #009900\">)<\/span><span style=\"color: #339933\">;<\/span><\/p>\n<p>app.<span style=\"color: #660066\">escuche<\/span><span style=\"color: #009900\">(<\/span><span style=\"color: #cc0000\">3000<\/span><span style=\"color: #339933\">,<\/span> <span style=\"color: #003366;font-weight: bold\">funci\u00f3n<\/span> <span style=\"color: #009900\">(<\/span><span style=\"color: #009900\">)<\/span> <span style=\"color: #009900\">{<\/span><br \/>\nconsola.<span style=\"color: #660066\">registro<\/span><span style=\"color: #009900\">(<\/span><span style=\"color: #3366cc\">Escuchando en el puerto 3000<\/span><span style=\"color: #009900\">)<\/span><span style=\"color: #339933\">;<\/span><br \/>\n<span style=\"color: #009900\">}<\/span><span style=\"color: #009900\">)<\/span><span style=\"color: #339933\">;<\/span><\/p>\n<\/div>\n<\/div>\n<p>For the last bit of our project basics, lets set up our database connection. The code is fairly straightforward, we import the couchbase module and subsequently export a new connection to our locally hosted server and the bucket &#8216;gameapi&#8217; through a property of the module named `mainBucket`.<\/p>\n<div class=\"geshifilter\">\n<div class=\"javascript geshifilter-javascript\" style=\"font-family: monospace\"><\/div>\n<div class=\"javascript geshifilter-javascript\" style=\"font-family: monospace\">\n<p><span style=\"color: #003366;font-weight: bold\">var<\/span> couchbase <span style=\"color: #339933\">=<\/span> requiere<span style=\"color: #009900\">(<\/span><span style=\"color: #3366cc\">couchbase<\/span><span style=\"color: #009900\">)<\/span><span style=\"color: #339933\">;<\/span><\/p>\n<p><span style=\"color: #006600;font-style: italic\">\/\/ Conectar con nuestro servidor Couchbase<\/span><\/p>\n<\/div>\n<div class=\"javascript geshifilter-javascript\" style=\"font-family: monospace\">m\u00f3dulo.<span style=\"color: #660066\">exportaciones<\/span>.<span style=\"color: #660066\">cubo principal<\/span> <span style=\"color: #339933\">=<\/span> <span style=\"color: #003366;font-weight: bold\">nuevo<\/span> couchbase.<span style=\"color: #660066\">Conexi\u00f3n<\/span><span style=\"color: #009900\">(<\/span><span style=\"color: #009900\">{<\/span>cubo<span style=\"color: #339933\">:<\/span><span style=\"color: #3366cc\">gameapi<\/span><span style=\"color: #009900\">}<\/span><span style=\"color: #339933\">,<\/span> <span style=\"color: #003366;font-weight: bold\">funci\u00f3n<\/span><span style=\"color: #009900\">(<\/span><span style=\"color: #009900\">)<\/span><span style=\"color: #009900\">{<\/span><span style=\"color: #009900\">}<\/span><span style=\"color: #009900\">)<\/span><span style=\"color: #339933\">;<\/span><\/div>\n<\/div>\n<p>At this point if you open a terminal in your project root and execute `node lib\/app.js`, you should see the message &#8220;Listening on port 3000&#8221;. You can also now point your browser to `https:\/\/localhost:3000` and see our work so far in action.<\/p>\n<p>Es en este punto donde te sugiero que instales una aplicaci\u00f3n que te permita elaborar peticiones HTTP espec\u00edficas, a m\u00ed personalmente me encanta la extensi\u00f3n POSTman para Google Chrome. Esto ser\u00e1 importante m\u00e1s adelante cuando quieras probar endpoints que no sean simples peticiones GET.<\/p>\n<h1>Creaci\u00f3n de cuentas - Modelo de cuenta<\/h1>\n<p>Now that we have our basic server running, lets starting working on the &#8216;game&#8217; portion of our game server. We are going to start by implementing the account creation endpoint which will be accessible by doing a POST request to the `\/users` URI. To start this process, we are going to first build a model for our endpoint handler to deal with to abstract some of the details of our database implementation. These models are where the bulk of our interactions with Couchbase Server will happen.<\/p>\n<p>Lets first start by creating a new file in our `\/lib\/models` folder called &#8216;accountmodel.js&#8217;. Once you&#8217;ve got your accountmodel.js file ready and opened, lets start by importing some of the modules we will need.<\/p>\n<div class=\"geshifilter\">\n<div class=\"javascript geshifilter-javascript\" style=\"font-family: monospace\"><span style=\"color: #003366;font-weight: bold\">var<\/span> uuid <span style=\"color: #339933\">=<\/span> requiere<span style=\"color: #009900\">(<\/span><span style=\"color: #3366cc\">uuid<\/span><span style=\"color: #009900\">)<\/span><span style=\"color: #339933\">;<\/span><br \/>\n<span style=\"color: #003366;font-weight: bold\">var<\/span> couchbase <span style=\"color: #339933\">=<\/span> requiere<span style=\"color: #009900\">(<\/span><span style=\"color: #3366cc\">couchbase<\/span><span style=\"color: #009900\">)<\/span><span style=\"color: #339933\">;<\/span><br \/>\n<span style=\"color: #003366;font-weight: bold\">var<\/span> db <span style=\"color: #339933\">=<\/span> requiere<span style=\"color: #009900\">(<\/span><span style=\"color: #3366cc\">'.\/..\/base de datos'<\/span><span style=\"color: #009900\">)<\/span>.<span style=\"color: #660066\">cubo principal<\/span><span style=\"color: #339933\">;<\/span><\/div>\n<\/div>\n<p>Como puedes ver, hay 4 m\u00f3dulos que vamos a necesitar en este momento. Usaremos el m\u00f3dulo uuid para generar UUID's para nuestros objetos de base de datos. He visto a mucha gente usando contadores de secuencia implementados usando el sistema incr\/decr de Couchbase, pero prefiero el m\u00e9todo UUID que usar\u00e9 aqu\u00ed ya que evita la necesidad de hacer una operaci\u00f3n adicional en la base de datos. A continuaci\u00f3n importamos el m\u00f3dulo couchbase que utilizaremos para acceder a varias constantes que necesitaremos (errores principalmente). Y por \u00faltimo importamos el m\u00f3dulo de base de datos y cogemos la conexi\u00f3n a nuestro bucket gameapi que creamos anteriormente.<\/p>\n<p>A continuaci\u00f3n definiremos una sencilla funci\u00f3n de ayuda que nos ayudar\u00e1 a eliminar cualquier propiedad a nivel de base de datos que nuestro modelo necesite y que no sea importante para el resto del servidor. En este momento la propiedad 'type' es la \u00fanica propiedad que vamos a eliminar. Esta propiedad ser\u00e1 utilizada por el gameapi para identificar qu\u00e9 tipo de objeto es un elemento en particular en nuestro cubo al hacer map-reduces m\u00e1s adelante.<\/p>\n<div class=\"geshifilter\">\n<div class=\"javascript geshifilter-javascript\" style=\"font-family: monospace\"><span style=\"color: #003366;font-weight: bold\">funci\u00f3n<\/span> cleanUserObj<span style=\"color: #009900\">(<\/span>obj<span style=\"color: #009900\">)<\/span> <span style=\"color: #009900\">{<\/span><br \/>\n<span style=\"color: #000066;font-weight: bold\">borrar<\/span> obj.<span style=\"color: #660066\">tipo<\/span><span style=\"color: #339933\">;<\/span><br \/>\n<span style=\"color: #000066;font-weight: bold\">devolver<\/span> obj<span style=\"color: #339933\">;<\/span><br \/>\n<span style=\"color: #009900\">}<\/span><\/div>\n<\/div>\n<p>Ahora definimos nuestra clase AccountModel.<\/p>\n<div class=\"geshifilter\">\n<div class=\"javascript geshifilter-javascript\" style=\"font-family: monospace\"><span style=\"color: #003366;font-weight: bold\">funci\u00f3n<\/span> AccountModel<span style=\"color: #009900\">(<\/span><span style=\"color: #009900\">)<\/span> <span style=\"color: #009900\">{<\/span><br \/>\n<span style=\"color: #009900\">}<\/span><\/div>\n<\/div>\n<p>Y exportar la clase a otros archivos que importan este. Le sugiero que mantenga esta declaraci\u00f3n siempre en la parte inferior de su archivo para que sea m\u00e1s f\u00e1cil de encontrar cuando usted est\u00e1 tratando de identificar lo que exporta un archivo en particular.<\/p>\n<div class=\"geshifilter\">\n<div class=\"javascript geshifilter-javascript\" style=\"font-family: monospace\"><\/div>\n<div class=\"javascript geshifilter-javascript\" style=\"font-family: monospace\">m\u00f3dulo.<span style=\"color: #660066\">exportaciones<\/span> <span style=\"color: #339933\">=<\/span> AccountModel<span style=\"color: #339933\">;<\/span><\/div>\n<div class=\"javascript geshifilter-javascript\" style=\"font-family: monospace\"><\/div>\n<\/div>\n<p>Ahora que nuestro Modelo est\u00e1 hecho, podemos construir nuestra funci\u00f3n de creaci\u00f3n que nos permitir\u00e1 crear objetos de usuario. Voy a dividir esta funci\u00f3n en trozos m\u00e1s peque\u00f1os para simplificar su explicaci\u00f3n.<\/p>\n<p>Empecemos por la definici\u00f3n de la propia funci\u00f3n.<\/p>\n<div class=\"geshifilter\">\n<div class=\"javascript geshifilter-javascript\" style=\"font-family: monospace\">Modelo de cuenta.<span style=\"color: #660066\">crear<\/span> <span style=\"color: #339933\">=<\/span> <span style=\"color: #003366;font-weight: bold\">funci\u00f3n<\/span><span style=\"color: #009900\">(<\/span>usuario<span style=\"color: #339933\">,<\/span> devoluci\u00f3n de llamada<span style=\"color: #009900\">)<\/span> <span style=\"color: #009900\">{<\/span><br \/>\n<span style=\"color: #009900\">}<\/span><span style=\"color: #339933\">;<\/span><\/div>\n<\/div>\n<p>A continuaci\u00f3n, vamos a crear un objeto que se insertar\u00e1 en nuestro cubo Couchbase. Especificamos un tipo para el objeto, que como se mencion\u00f3 anteriormente se utilizar\u00e1 m\u00e1s adelante. Generamos un UID para el usuario que nos ayudar\u00e1 a referirnos a \u00e9l en todo momento. Finalmente, copiamos los detalles del usuario que fueron pasados a la funci\u00f3n de creaci\u00f3n. Usted puede notar que no preform cualquier validaci\u00f3n de los datos que se pasan a nuestro modelo, esto se debe a que la mayor parte de nuestra solicitud de manejo de c\u00f3digo tendr\u00e1 una mejor idea de lo que aceptar o no aceptar, y nuestro modelo es s\u00f3lo responsable de obtener los datos almacenados. Por \u00faltimo, generamos una clave para referirnos a este documento, usamos el tipo de documento y el UID del usuario para este prop\u00f3sito.<\/p>\n<div class=\"geshifilter\">\n<div class=\"javascript geshifilter-javascript\" style=\"font-family: monospace\"><\/div>\n<div class=\"javascript geshifilter-javascript\" style=\"font-family: monospace\">\n<p><span style=\"color: #003366;font-weight: bold\">var<\/span> userDoc <span style=\"color: #339933\">=<\/span> <span style=\"color: #009900\">{<\/span><br \/>\ntipo<span style=\"color: #339933\">:<\/span> <span style=\"color: #3366cc\">usuario<\/span><span style=\"color: #339933\">,<\/span><br \/>\nuid<span style=\"color: #339933\">:<\/span> uuid.<span style=\"color: #660066\">v4<\/span><span style=\"color: #009900\">(<\/span><span style=\"color: #009900\">)<\/span><span style=\"color: #339933\">,<\/span><br \/>\n<span style=\"color: #000066\">nombre<\/span><span style=\"color: #339933\">:<\/span> usuario.<span style=\"color: #000066\">nombre<\/span><span style=\"color: #339933\">,<\/span><br \/>\nnombre de usuario<span style=\"color: #339933\">:<\/span> usuario.<span style=\"color: #660066\">nombre de usuario<\/span><span style=\"color: #339933\">,<\/span><br \/>\ncontrase\u00f1a<span style=\"color: #339933\">:<\/span> usuario.<span style=\"color: #660066\">contrase\u00f1a<\/span><br \/>\n<span style=\"color: #009900\">}<\/span><span style=\"color: #339933\">;<\/span><\/p>\n<p><span style=\"color: #003366;font-weight: bold\">var<\/span> nombreDocUsuario <span style=\"color: #339933\">=<\/span> <span style=\"color: #3366cc\">usuario<\/span> <span style=\"color: #339933\">+<\/span> usuarioDoc.<span style=\"color: #660066\">uid<\/span><span style=\"color: #339933\">;<\/span><\/p>\n<\/div>\n<\/div>\n<p>Para permitirnos encontrar a este usuario en el futuro por su nombre de usuario (\u00a1probablemente no sea una buena idea hacer que tus usuarios recuerden sus UIDs!), crearemos un 'documento referencial', es decir, un documento con una clave basada en el nombre de usuario que apunta al documento de nuestro usuario (usando su UID). Esto tambi\u00e9n tiene la ventaja a\u00f1adida de evitar que varios usuarios tengan el mismo nombre de usuario.<\/p>\n<div class=\"geshifilter\">\n<div class=\"javascript geshifilter-javascript\" style=\"font-family: monospace\"><span style=\"color: #003366;font-weight: bold\">var<\/span> refDoc <span style=\"color: #339933\">=<\/span> <span style=\"color: #009900\">{<\/span><br \/>\ntipo<span style=\"color: #339933\">:<\/span> <span style=\"color: #3366cc\">nombre de usuario<\/span><span style=\"color: #339933\">,<\/span><br \/>\nuid<span style=\"color: #339933\">:<\/span> usuarioDoc.<span style=\"color: #660066\">uid<\/span><br \/>\n<span style=\"color: #009900\">}<\/span><span style=\"color: #339933\">;<\/span><br \/>\n<span style=\"color: #003366;font-weight: bold\">var<\/span> refDocName <span style=\"color: #339933\">=<\/span> <span style=\"color: #3366cc\">nombre de usuario<\/span> <span style=\"color: #339933\">+<\/span> usuarioDoc.<span style=\"color: #660066\">nombre de usuario<\/span><span style=\"color: #339933\">;<\/span><\/div>\n<div class=\"javascript geshifilter-javascript\" style=\"font-family: monospace\"><\/div>\n<\/div>\n<p>Finalmente, necesitamos insertar estos documentos en nuestro bucket de Couchbase. Primero, insertamos el documento referencial y manejamos el error keyAlreadyExists espec\u00edficamente devolviendo un mensaje avisando al usuario de que el nombre de usuario est\u00e1 cogido y simplemente pasando cualquier otro error (probablemente deber\u00edamos envolver nuestros errores de Couchbase a nivel de Modelo, pero eso no es importante en este punto de la serie). El hecho de que insertemos los documentos referenciales primero aqu\u00ed es importante porque ++TODO++ \u00bfPor qu\u00e9 es importante otra vez? -TODO-. A continuaci\u00f3n insertamos el documento de usuario propiamente dicho y finalmente invocamos el callback que se nos pas\u00f3. Primero desinfectamos el objeto devuelto usando la funci\u00f3n que creamos antes para asegurarnos de que ninguna de nuestras propiedades a nivel de base de datos se filtre a otras capas de nuestra aplicaci\u00f3n. Tambi\u00e9n puedes notar que estamos pasando un valor 'cas' a trav\u00e9s de nuestro callback. Esto ser\u00e1 importante m\u00e1s adelante cuando necesitemos realizar <a href=\"https:\/\/www.couchbase.com\/blog\/es\/optimistic-or-pessimistic-locking-which-one-should-you-pick\/\">bloqueo optimista<\/a> en nuestro objeto Cuenta.<\/p>\n<div class=\"geshifilter\">\n<div class=\"javascript geshifilter-javascript\" style=\"font-family: monospace\"><\/div>\n<div class=\"javascript geshifilter-javascript\" style=\"font-family: monospace\">\n<p>db.<span style=\"color: #660066\">a\u00f1ada<\/span><span style=\"color: #009900\">(<\/span>refDocName<span style=\"color: #339933\">,<\/span> refDoc<span style=\"color: #339933\">,<\/span> <span style=\"color: #003366;font-weight: bold\">funci\u00f3n<\/span><span style=\"color: #009900\">(<\/span>err<span style=\"color: #009900\">)<\/span> <span style=\"color: #009900\">{<\/span><br \/>\n<span style=\"color: #000066;font-weight: bold\">si<\/span> <span style=\"color: #009900\">(<\/span>err <span style=\"color: #339933\">&amp;&amp;<\/span> err.<span style=\"color: #660066\">c\u00f3digo<\/span> <span style=\"color: #339933\">===<\/span> couchbase.<span style=\"color: #660066\">errores<\/span>.<span style=\"color: #660066\">claveYaExiste<\/span><span style=\"color: #009900\">)<\/span> <span style=\"color: #009900\">{<\/span><br \/>\n<span style=\"color: #000066;font-weight: bold\">devolver<\/span> devoluci\u00f3n de llamada<span style=\"color: #009900\">(<\/span><span style=\"color: #3366cc\">'El nombre de usuario especificado ya existe'<\/span><span style=\"color: #009900\">)<\/span><span style=\"color: #339933\">;<\/span><br \/>\n<span style=\"color: #009900\">}<\/span> <span style=\"color: #000066;font-weight: bold\">si no<\/span> <span style=\"color: #000066;font-weight: bold\">si<\/span> <span style=\"color: #009900\">(<\/span>err<span style=\"color: #009900\">)<\/span> <span style=\"color: #009900\">{<\/span><br \/>\n<span style=\"color: #000066;font-weight: bold\">devolver<\/span> devoluci\u00f3n de llamada<span style=\"color: #009900\">(<\/span>err<span style=\"color: #009900\">)<\/span><span style=\"color: #339933\">;<\/span><br \/>\n<span style=\"color: #009900\">}<\/span><\/p>\n<p>db.<span style=\"color: #660066\">a\u00f1ada<\/span><span style=\"color: #009900\">(<\/span>nombreDocUsuario<span style=\"color: #339933\">,<\/span> userDoc<span style=\"color: #339933\">,<\/span> <span style=\"color: #003366;font-weight: bold\">funci\u00f3n<\/span><span style=\"color: #009900\">(<\/span>err<span style=\"color: #339933\">,<\/span> resultado<span style=\"color: #009900\">)<\/span> <span style=\"color: #009900\">{<\/span><br \/>\n<span style=\"color: #000066;font-weight: bold\">si<\/span> <span style=\"color: #009900\">(<\/span>err<span style=\"color: #009900\">)<\/span> <span style=\"color: #009900\">{<\/span><br \/>\n<span style=\"color: #000066;font-weight: bold\">devolver<\/span> devoluci\u00f3n de llamada<span style=\"color: #009900\">(<\/span>err<span style=\"color: #009900\">)<\/span><span style=\"color: #339933\">;<\/span><br \/>\n<span style=\"color: #009900\">}<\/span><\/p>\n<p>devoluci\u00f3n de llamada<span style=\"color: #009900\">(<\/span><span style=\"color: #003366;font-weight: bold\">null<\/span><span style=\"color: #339933\">,<\/span> cleanUserObj<span style=\"color: #009900\">(<\/span>userDoc<span style=\"color: #009900\">)<\/span><span style=\"color: #339933\">,<\/span> resultado.<span style=\"color: #660066\">cas<\/span><span style=\"color: #009900\">)<\/span><span style=\"color: #339933\">;<\/span><br \/>\n<span style=\"color: #009900\">}<\/span><span style=\"color: #009900\">)<\/span><span style=\"color: #339933\">;<\/span><br \/>\n<span style=\"color: #009900\">}<\/span><span style=\"color: #009900\">)<\/span><span style=\"color: #339933\">;<\/span><\/p>\n<\/div>\n<\/div>\n<p>Este es el aspecto que deber\u00eda tener su archivo accountmodel.js hasta el momento:<\/p>\n<div class=\"geshifilter\">\n<div class=\"javascript geshifilter-javascript\" style=\"font-family: monospace\">\n<p><span style=\"color: #003366;font-weight: bold\">var<\/span> uuid <span style=\"color: #339933\">=<\/span> requiere<span style=\"color: #009900\">(<\/span><span style=\"color: #3366cc\">uuid<\/span><span style=\"color: #009900\">)<\/span><span style=\"color: #339933\">;<\/span><br \/>\n<span style=\"color: #003366;font-weight: bold\">var<\/span> couchbase <span style=\"color: #339933\">=<\/span> requiere<span style=\"color: #009900\">(<\/span><span style=\"color: #3366cc\">couchbase<\/span><span style=\"color: #009900\">)<\/span><span style=\"color: #339933\">;<\/span><br \/>\n<span style=\"color: #003366;font-weight: bold\">var<\/span> db <span style=\"color: #339933\">=<\/span> requiere<span style=\"color: #009900\">(<\/span><span style=\"color: #3366cc\">'.\/..\/base de datos'<\/span><span style=\"color: #009900\">)<\/span>.<span style=\"color: #660066\">cubo principal<\/span><span style=\"color: #339933\">;<\/span><\/p>\n<p><span style=\"color: #003366;font-weight: bold\">funci\u00f3n<\/span> cleanUserObj<span style=\"color: #009900\">(<\/span>obj<span style=\"color: #009900\">)<\/span> <span style=\"color: #009900\">{<\/span><br \/>\n<span style=\"color: #000066;font-weight: bold\">borrar<\/span> obj.<span style=\"color: #660066\">tipo<\/span><span style=\"color: #339933\">;<\/span><br \/>\n<span style=\"color: #000066;font-weight: bold\">devolver<\/span> obj<span style=\"color: #339933\">;<\/span><br \/>\n<span style=\"color: #009900\">}<\/span><\/p>\n<p><span style=\"color: #003366;font-weight: bold\">funci\u00f3n<\/span> AccountModel<span style=\"color: #009900\">(<\/span><span style=\"color: #009900\">)<\/span> <span style=\"color: #009900\">{<\/span><br \/>\n<span style=\"color: #009900\">}<\/span><\/p>\n<p>Modelo de cuenta.<span style=\"color: #660066\">crear<\/span> <span style=\"color: #339933\">=<\/span> <span style=\"color: #003366;font-weight: bold\">funci\u00f3n<\/span><span style=\"color: #009900\">(<\/span>usuario<span style=\"color: #339933\">,<\/span> devoluci\u00f3n de llamada<span style=\"color: #009900\">)<\/span> <span style=\"color: #009900\">{<\/span><br \/>\n<span style=\"color: #003366;font-weight: bold\">var<\/span> userDoc <span style=\"color: #339933\">=<\/span> <span style=\"color: #009900\">{<\/span><br \/>\ntipo<span style=\"color: #339933\">:<\/span> <span style=\"color: #3366cc\">usuario<\/span><span style=\"color: #339933\">,<\/span><br \/>\nuid<span style=\"color: #339933\">:<\/span> uuid.<span style=\"color: #660066\">v4<\/span><span style=\"color: #009900\">(<\/span><span style=\"color: #009900\">)<\/span><span style=\"color: #339933\">,<\/span><br \/>\n<span style=\"color: #000066\">nombre<\/span><span style=\"color: #339933\">:<\/span> usuario.<span style=\"color: #000066\">nombre<\/span><span style=\"color: #339933\">,<\/span><br \/>\nnombre de usuario<span style=\"color: #339933\">:<\/span> usuario.<span style=\"color: #660066\">nombre de usuario<\/span><span style=\"color: #339933\">,<\/span><br \/>\ncontrase\u00f1a<span style=\"color: #339933\">:<\/span> usuario.<span style=\"color: #660066\">contrase\u00f1a<\/span><br \/>\n<span style=\"color: #009900\">}<\/span><span style=\"color: #339933\">;<\/span><br \/>\n<span style=\"color: #003366;font-weight: bold\">var<\/span> nombreDocUsuario <span style=\"color: #339933\">=<\/span> <span style=\"color: #3366cc\">usuario<\/span> <span style=\"color: #339933\">+<\/span> usuarioDoc.<span style=\"color: #660066\">uid<\/span><span style=\"color: #339933\">;<\/span><\/p>\n<p><span style=\"color: #003366;font-weight: bold\">var<\/span> refDoc <span style=\"color: #339933\">=<\/span> <span style=\"color: #009900\">{<\/span><br \/>\ntipo<span style=\"color: #339933\">:<\/span> <span style=\"color: #3366cc\">nombre de usuario<\/span><span style=\"color: #339933\">,<\/span><br \/>\nuid<span style=\"color: #339933\">:<\/span> usuarioDoc.<span style=\"color: #660066\">uid<\/span><br \/>\n<span style=\"color: #009900\">}<\/span><span style=\"color: #339933\">;<\/span><br \/>\n<span style=\"color: #003366;font-weight: bold\">var<\/span> refDocName <span style=\"color: #339933\">=<\/span> <span style=\"color: #3366cc\">nombre de usuario<\/span> <span style=\"color: #339933\">+<\/span> usuarioDoc.<span style=\"color: #660066\">nombre de usuario<\/span><span style=\"color: #339933\">;<\/span><\/p>\n<p>db.<span style=\"color: #660066\">a\u00f1ada<\/span><span style=\"color: #009900\">(<\/span>refDocName<span style=\"color: #339933\">,<\/span> refDoc<span style=\"color: #339933\">,<\/span> <span style=\"color: #003366;font-weight: bold\">funci\u00f3n<\/span><span style=\"color: #009900\">(<\/span>err<span style=\"color: #009900\">)<\/span> <span style=\"color: #009900\">{<\/span><br \/>\n<span style=\"color: #000066;font-weight: bold\">si<\/span> <span style=\"color: #009900\">(<\/span>err <span style=\"color: #339933\">&amp;&amp;<\/span> err.<span style=\"color: #660066\">c\u00f3digo<\/span> <span style=\"color: #339933\">===<\/span> couchbase.<span style=\"color: #660066\">errores<\/span>.<span style=\"color: #660066\">claveYaExiste<\/span><span style=\"color: #009900\">)<\/span> <span style=\"color: #009900\">{<\/span><br \/>\n<span style=\"color: #000066;font-weight: bold\">devolver<\/span> devoluci\u00f3n de llamada<span style=\"color: #009900\">(<\/span><span style=\"color: #3366cc\">'El nombre de usuario especificado ya existe'<\/span><span style=\"color: #009900\">)<\/span><span style=\"color: #339933\">;<\/span><br \/>\n<span style=\"color: #009900\">}<\/span> <span style=\"color: #000066;font-weight: bold\">si no<\/span> <span style=\"color: #000066;font-weight: bold\">si<\/span> <span style=\"color: #009900\">(<\/span>err<span style=\"color: #009900\">)<\/span> <span style=\"color: #009900\">{<\/span><br \/>\n<span style=\"color: #000066;font-weight: bold\">devolver<\/span> devoluci\u00f3n de llamada<span style=\"color: #009900\">(<\/span>err<span style=\"color: #009900\">)<\/span><span style=\"color: #339933\">;<\/span><br \/>\n<span style=\"color: #009900\">}<\/span><\/p>\n<p>db.<span style=\"color: #660066\">a\u00f1ada<\/span><span style=\"color: #009900\">(<\/span>nombreDocUsuario<span style=\"color: #339933\">,<\/span> userDoc<span style=\"color: #339933\">,<\/span> <span style=\"color: #003366;font-weight: bold\">funci\u00f3n<\/span><span style=\"color: #009900\">(<\/span>err<span style=\"color: #339933\">,<\/span> resultado<span style=\"color: #009900\">)<\/span> <span style=\"color: #009900\">{<\/span><br \/>\n<span style=\"color: #000066;font-weight: bold\">si<\/span> <span style=\"color: #009900\">(<\/span>err<span style=\"color: #009900\">)<\/span> <span style=\"color: #009900\">{<\/span><br \/>\n<span style=\"color: #000066;font-weight: bold\">devolver<\/span> devoluci\u00f3n de llamada<span style=\"color: #009900\">(<\/span>err<span style=\"color: #009900\">)<\/span><span style=\"color: #339933\">;<\/span><br \/>\n<span style=\"color: #009900\">}<\/span><\/p>\n<p>devoluci\u00f3n de llamada<span style=\"color: #009900\">(<\/span><span style=\"color: #003366;font-weight: bold\">null<\/span><span style=\"color: #339933\">,<\/span> cleanUserObj<span style=\"color: #009900\">(<\/span>userDoc<span style=\"color: #009900\">)<\/span><span style=\"color: #339933\">,<\/span> resultado.<span style=\"color: #660066\">cas<\/span><span style=\"color: #009900\">)<\/span><span style=\"color: #339933\">;<\/span><br \/>\n<span style=\"color: #009900\">}<\/span><span style=\"color: #009900\">)<\/span><span style=\"color: #339933\">;<\/span><br \/>\n<span style=\"color: #009900\">}<\/span><span style=\"color: #009900\">)<\/span><span style=\"color: #339933\">;<\/span><br \/>\n<span style=\"color: #009900\">}<\/span><span style=\"color: #339933\">;<\/span><\/p>\n<p>m\u00f3dulo.<span style=\"color: #660066\">exportaciones<\/span> <span style=\"color: #339933\">=<\/span> AccountModel<span style=\"color: #339933\">;<\/span><\/p>\n<\/div>\n<\/div>\n<h1>Creaci\u00f3n de cuentas - Gesti\u00f3n de solicitudes<\/h1>\n<p>Ahora que hemos completado la funci\u00f3n de creaci\u00f3n en nuestro modelo de cuenta, podemos escribir una ruta express para manejar las solicitudes de creaci\u00f3n de cuentas y pasar estas solicitudes a trav\u00e9s de nuestra funci\u00f3n. Primero necesitamos definir una ruta.<\/p>\n<div class=\"geshifilter\">\n<div class=\"javascript geshifilter-javascript\" style=\"font-family: monospace\">app.<span style=\"color: #660066\">Correo electr\u00f3nico:<\/span><span style=\"color: #009900\">(<\/span><span style=\"color: #3366cc\">\/usuarios<\/span><span style=\"color: #339933\">,<\/span> <span style=\"color: #003366;font-weight: bold\">funci\u00f3n<\/span><span style=\"color: #009900\">(<\/span>consulte<span style=\"color: #339933\">,<\/span> res<span style=\"color: #339933\">,<\/span> siguiente<span style=\"color: #009900\">)<\/span> <span style=\"color: #009900\">{<\/span><br \/>\n<span style=\"color: #006600;font-style: italic\">\/\/ \u00a1Los siguientes trozos van aqu\u00ed!<\/span><br \/>\n<span style=\"color: #009900\">}<\/span><span style=\"color: #009900\">)<\/span><span style=\"color: #339933\">;<\/span><\/div>\n<\/div>\n<p>Y... realizar alguna validaci\u00f3n para asegurar que los datos necesarios fueron pasados al endpoint.<\/p>\n<div class=\"geshifilter\">\n<div class=\"javascript geshifilter-javascript\" style=\"font-family: monospace\"><span style=\"color: #000066;font-weight: bold\">si<\/span> <span style=\"color: #009900\">(<\/span><span style=\"color: #339933\">!<\/span>req.<span style=\"color: #660066\">cuerpo<\/span>.<span style=\"color: #000066\">nombre<\/span><span style=\"color: #009900\">)<\/span> <span style=\"color: #009900\">{<\/span><br \/>\n<span style=\"color: #000066;font-weight: bold\">devolver<\/span> res.<span style=\"color: #660066\">enviar<\/span><span style=\"color: #009900\">(<\/span><span style=\"color: #cc0000\">400<\/span><span style=\"color: #339933\">,<\/span> <span style=\"color: #3366cc\">Debe especificar un nombre<\/span><span style=\"color: #009900\">)<\/span><span style=\"color: #339933\">;<\/span><br \/>\n<span style=\"color: #009900\">}<\/span><br \/>\n<span style=\"color: #000066;font-weight: bold\">si<\/span> <span style=\"color: #009900\">(<\/span><span style=\"color: #339933\">!<\/span>req.<span style=\"color: #660066\">cuerpo<\/span>.<span style=\"color: #660066\">nombre de usuario<\/span><span style=\"color: #009900\">)<\/span> <span style=\"color: #009900\">{<\/span><br \/>\n<span style=\"color: #000066;font-weight: bold\">devolver<\/span> res.<span style=\"color: #660066\">enviar<\/span><span style=\"color: #009900\">(<\/span><span style=\"color: #cc0000\">400<\/span><span style=\"color: #339933\">,<\/span> <span style=\"color: #3366cc\">Debe especificar un nombre de usuario<\/span><span style=\"color: #009900\">)<\/span><span style=\"color: #339933\">;<\/span><br \/>\n<span style=\"color: #009900\">}<\/span><br \/>\n<span style=\"color: #000066;font-weight: bold\">si<\/span> <span style=\"color: #009900\">(<\/span><span style=\"color: #339933\">!<\/span>req.<span style=\"color: #660066\">cuerpo<\/span>.<span style=\"color: #660066\">contrase\u00f1a<\/span><span style=\"color: #009900\">)<\/span> <span style=\"color: #009900\">{<\/span><br \/>\n<span style=\"color: #000066;font-weight: bold\">devolver<\/span> res.<span style=\"color: #660066\">enviar<\/span><span style=\"color: #009900\">(<\/span><span style=\"color: #cc0000\">400<\/span><span style=\"color: #339933\">,<\/span> <span style=\"color: #3366cc\">Debe especificar una contrase\u00f1a<\/span><span style=\"color: #009900\">)<\/span><span style=\"color: #339933\">;<\/span><br \/>\n<span style=\"color: #009900\">}<\/span><\/div>\n<\/div>\n<p>Una vez que los datos han sido *cough* \"validados\" *\/cough*, podemos generar el hash SHA1 para la contrase\u00f1a del usuario (\u00a1nunca almacenes las contrase\u00f1as de un usuario en texto plano!) y luego ejecutar la funci\u00f3n create que construimos anteriormente en este post. Tambi\u00e9n puedes notar que elimino la contrase\u00f1a del usuario del objeto user antes de pasarlo de vuelta al cliente. Esto es de nuevo por seguridad, ya que queremos limitar la transmisi\u00f3n de la contrase\u00f1a del usuario (en cualquier formato) tanto como sea posible.<\/p>\n<div class=\"geshifilter\">\n<div class=\"javascript geshifilter-javascript\" style=\"font-family: monospace\"><\/div>\n<div class=\"javascript geshifilter-javascript\" style=\"font-family: monospace\">\n<p><span style=\"color: #003366;font-weight: bold\">var<\/span> nuevoUsuario <span style=\"color: #339933\">=<\/span> req.<span style=\"color: #660066\">cuerpo<\/span><span style=\"color: #339933\">;<\/span><br \/>\nnuevoUsuario.<span style=\"color: #660066\">contrase\u00f1a<\/span> <span style=\"color: #339933\">=<\/span> cripta.<span style=\"color: #660066\">sha1<\/span><span style=\"color: #009900\">(<\/span>nuevoUsuario.<span style=\"color: #660066\">contrase\u00f1a<\/span><span style=\"color: #009900\">)<\/span><span style=\"color: #339933\">;<\/span><\/p>\n<p>accountModel.<span style=\"color: #660066\">crear<\/span><span style=\"color: #009900\">(<\/span>req.<span style=\"color: #660066\">cuerpo<\/span><span style=\"color: #339933\">,<\/span> <span style=\"color: #003366;font-weight: bold\">funci\u00f3n<\/span><span style=\"color: #009900\">(<\/span>err<span style=\"color: #339933\">,<\/span> usuario<span style=\"color: #009900\">)<\/span> <span style=\"color: #009900\">{<\/span><br \/>\n<span style=\"color: #000066;font-weight: bold\">si<\/span> <span style=\"color: #009900\">(<\/span>err<span style=\"color: #009900\">)<\/span> <span style=\"color: #009900\">{<\/span><br \/>\n<span style=\"color: #000066;font-weight: bold\">devolver<\/span> siguiente<span style=\"color: #009900\">(<\/span>err<span style=\"color: #009900\">)<\/span><span style=\"color: #339933\">;<\/span><br \/>\n<span style=\"color: #009900\">}<\/span><\/p>\n<p><span style=\"color: #000066;font-weight: bold\">borrar<\/span> usuario.<span style=\"color: #660066\">contrase\u00f1a<\/span><span style=\"color: #339933\">;<\/span><br \/>\nres.<span style=\"color: #660066\">enviar<\/span><span style=\"color: #009900\">(<\/span>usuario<span style=\"color: #009900\">)<\/span><span style=\"color: #339933\">;<\/span><br \/>\n<span style=\"color: #009900\">}<\/span><span style=\"color: #009900\">)<\/span><span style=\"color: #339933\">;<\/span><\/p>\n<\/div>\n<\/div>\n<p>En resumen, toda la ruta de creaci\u00f3n de la cuenta deber\u00eda tener este aspecto:<\/p>\n<div class=\"geshifilter\">\n<div class=\"javascript geshifilter-javascript\" style=\"font-family: monospace\">\n<p>app.<span style=\"color: #660066\">Correo electr\u00f3nico:<\/span><span style=\"color: #009900\">(<\/span><span style=\"color: #3366cc\">\/usuarios<\/span><span style=\"color: #339933\">,<\/span> <span style=\"color: #003366;font-weight: bold\">funci\u00f3n<\/span><span style=\"color: #009900\">(<\/span>consulte<span style=\"color: #339933\">,<\/span> res<span style=\"color: #339933\">,<\/span> siguiente<span style=\"color: #009900\">)<\/span> <span style=\"color: #009900\">{<\/span><br \/>\n<span style=\"color: #000066;font-weight: bold\">si<\/span> <span style=\"color: #009900\">(<\/span><span style=\"color: #339933\">!<\/span>req.<span style=\"color: #660066\">cuerpo<\/span>.<span style=\"color: #000066\">nombre<\/span><span style=\"color: #009900\">)<\/span> <span style=\"color: #009900\">{<\/span><br \/>\n<span style=\"color: #000066;font-weight: bold\">devolver<\/span> res.<span style=\"color: #660066\">enviar<\/span><span style=\"color: #009900\">(<\/span><span style=\"color: #cc0000\">400<\/span><span style=\"color: #339933\">,<\/span> <span style=\"color: #3366cc\">Debe especificar un nombre<\/span><span style=\"color: #009900\">)<\/span><span style=\"color: #339933\">;<\/span><br \/>\n<span style=\"color: #009900\">}<\/span><br \/>\n<span style=\"color: #000066;font-weight: bold\">si<\/span> <span style=\"color: #009900\">(<\/span><span style=\"color: #339933\">!<\/span>req.<span style=\"color: #660066\">cuerpo<\/span>.<span style=\"color: #660066\">nombre de usuario<\/span><span style=\"color: #009900\">)<\/span> <span style=\"color: #009900\">{<\/span><br \/>\n<span style=\"color: #000066;font-weight: bold\">devolver<\/span> res.<span style=\"color: #660066\">enviar<\/span><span style=\"color: #009900\">(<\/span><span style=\"color: #cc0000\">400<\/span><span style=\"color: #339933\">,<\/span> <span style=\"color: #3366cc\">Debe especificar un nombre de usuario<\/span><span style=\"color: #009900\">)<\/span><span style=\"color: #339933\">;<\/span><br \/>\n<span style=\"color: #009900\">}<\/span><br \/>\n<span style=\"color: #000066;font-weight: bold\">si<\/span> <span style=\"color: #009900\">(<\/span><span style=\"color: #339933\">!<\/span>req.<span style=\"color: #660066\">cuerpo<\/span>.<span style=\"color: #660066\">contrase\u00f1a<\/span><span style=\"color: #009900\">)<\/span> <span style=\"color: #009900\">{<\/span><br \/>\n<span style=\"color: #000066;font-weight: bold\">devolver<\/span> res.<span style=\"color: #660066\">enviar<\/span><span style=\"color: #009900\">(<\/span><span style=\"color: #cc0000\">400<\/span><span style=\"color: #339933\">,<\/span> <span style=\"color: #3366cc\">Debe especificar una contrase\u00f1a<\/span><span style=\"color: #009900\">)<\/span><span style=\"color: #339933\">;<\/span><br \/>\n<span style=\"color: #009900\">}<\/span><\/p>\n<p><span style=\"color: #003366;font-weight: bold\">var<\/span> nuevoUsuario <span style=\"color: #339933\">=<\/span> req.<span style=\"color: #660066\">cuerpo<\/span><span style=\"color: #339933\">;<\/span><br \/>\nnuevoUsuario.<span style=\"color: #660066\">contrase\u00f1a<\/span> <span style=\"color: #339933\">=<\/span> cripta.<span style=\"color: #660066\">sha1<\/span><span style=\"color: #009900\">(<\/span>nuevoUsuario.<span style=\"color: #660066\">contrase\u00f1a<\/span><span style=\"color: #009900\">)<\/span><span style=\"color: #339933\">;<\/span><\/p>\n<p>accountModel.<span style=\"color: #660066\">crear<\/span><span style=\"color: #009900\">(<\/span>nuevoUsuario<span style=\"color: #339933\">,<\/span> <span style=\"color: #003366;font-weight: bold\">funci\u00f3n<\/span><span style=\"color: #009900\">(<\/span>err<span style=\"color: #339933\">,<\/span> usuario<span style=\"color: #009900\">)<\/span> <span style=\"color: #009900\">{<\/span><br \/>\n<span style=\"color: #000066;font-weight: bold\">si<\/span> <span style=\"color: #009900\">(<\/span>err<span style=\"color: #009900\">)<\/span> <span style=\"color: #009900\">{<\/span><br \/>\n<span style=\"color: #000066;font-weight: bold\">devolver<\/span> siguiente<span style=\"color: #009900\">(<\/span>err<span style=\"color: #009900\">)<\/span><span style=\"color: #339933\">;<\/span><br \/>\n<span style=\"color: #009900\">}<\/span><\/p>\n<p><span style=\"color: #000066;font-weight: bold\">borrar<\/span> usuario.<span style=\"color: #660066\">contrase\u00f1a<\/span><span style=\"color: #339933\">;<\/span><br \/>\nres.<span style=\"color: #660066\">enviar<\/span><span style=\"color: #009900\">(<\/span>usuario<span style=\"color: #009900\">)<\/span><span style=\"color: #339933\">;<\/span><br \/>\n<span style=\"color: #009900\">}<\/span><span style=\"color: #009900\">)<\/span><span style=\"color: #339933\">;<\/span><br \/>\n<span style=\"color: #009900\">}<\/span><span style=\"color: #009900\">)<\/span><span style=\"color: #339933\">;<\/span><\/p>\n<\/div>\n<\/div>\n<h1>Finale<\/h1>\n<p>Bueno, por fin hemos llegado al final de la parte 1 de nuestro tutorial. Hemos sacado muchas cosas b\u00e1sicas del camino, as\u00ed que las futuras partes de la serie deber\u00edan ser un poco m\u00e1s cortas (\u00a1aunque no prometo nada!). En este punto, deber\u00edas ser capaz de ejecutar una petici\u00f3n POST a tu endpoint \/users y crear un nuevo usuario como este:<\/p>\n<div class=\"geshifilter\">\n<div class=\"text geshifilter-text\" style=\"font-family: monospace\"><\/div>\n<div class=\"text geshifilter-text\" style=\"font-family: monospace\">&gt; POST \/usuarios<br \/>\n{<br \/>\n\"name\": \"Brett Lawson\",<br \/>\n\"nombre de usuario\": \"brett19\",<br \/>\n\"contrase\u00f1a\": \"\u00a1\u00e9xito!\"<br \/>\n}<br \/>\n&lt; 200 OK<br \/>\n{<br \/>\n\"uid\": \u201cb836d211-425c-47de-9faf-5d0adc078edc\u201d,<br \/>\n\"name\": \"Brett Lawson\",<br \/>\n\"nombre de usuario\": \"brett19\"<br \/>\n}<\/div>\n<\/div>\n<p>Desafortunadamente, en este punto no hay mucho que puedas hacer con tus nuevas cuentas, excepto quiz\u00e1s maravillarte de su existencia en nuestra base de datos. Espero que te quedes para la Parte 2, donde introducir\u00e9 las sesiones y la autenticaci\u00f3n de los usuarios que ahora pueden registrarse.<\/p>\n<p>La fuente completa de esta aplicaci\u00f3n est\u00e1 disponible aqu\u00ed: <a href=\"https:\/\/github.com\/brett19\/node-gameapi\">https:\/\/github.com\/brett19\/node-gameapi<\/a><\/p>\n<p>\u00a1Que aproveche! Brett<\/p>","protected":false},"excerpt":{"rendered":"<p>It seems these days that almost every game studio has been working on networked games where players can interact and co-operate with their friends and other players around the world. Considering my previous experience building such servers and that Couchbase [&hellip;]<\/p>\n","protected":false},"author":31,"featured_media":13873,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"inline_featured_image":false,"footnotes":""},"categories":[1],"tags":[],"ppma_author":[9004],"class_list":["post-1614","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-uncategorized"],"yoast_head":"<!-- This site is optimized with the Yoast SEO Premium plugin v27.3 (Yoast SEO v27.3) - https:\/\/yoast.com\/product\/yoast-seo-premium-wordpress\/ -->\n<title>Game Servers and Couchbase with Node.js - Part 1<\/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\/game-servers-and-couchbase-nodejs-part-1\/\" \/>\n<meta property=\"og:locale\" content=\"es_MX\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Game Servers and Couchbase with Node.js - Part 1\" \/>\n<meta property=\"og:description\" content=\"It seems these days that almost every game studio has been working on networked games where players can interact and co-operate with their friends and other players around the world. Considering my previous experience building such servers and that Couchbase [&hellip;]\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.couchbase.com\/blog\/es\/game-servers-and-couchbase-nodejs-part-1\/\" \/>\n<meta property=\"og:site_name\" content=\"The Couchbase Blog\" \/>\n<meta property=\"article:published_time\" content=\"2014-12-16T19:31:59+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2023-06-28T07:24:10+00:00\" \/>\n<meta name=\"author\" content=\"Brett Lawson, Principal Software Engineer, Couchbase\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Brett Lawson, Principal Software Engineer, Couchbase\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"11 minutos\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/game-servers-and-couchbase-nodejs-part-1\\\/#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/game-servers-and-couchbase-nodejs-part-1\\\/\"},\"author\":{\"name\":\"Brett Lawson, Principal Software Engineer, Couchbase\",\"@id\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/#\\\/schema\\\/person\\\/5cfc2fbf25776be2a027a474562be02f\"},\"headline\":\"Game Servers and Couchbase with Node.js &#8211; Part 1\",\"datePublished\":\"2014-12-16T19:31:59+00:00\",\"dateModified\":\"2023-06-28T07:24:10+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/game-servers-and-couchbase-nodejs-part-1\\\/\"},\"wordCount\":2214,\"commentCount\":16,\"publisher\":{\"@id\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/#organization\"},\"image\":{\"@id\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/game-servers-and-couchbase-nodejs-part-1\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/wp-content\\\/uploads\\\/sites\\\/1\\\/2022\\\/11\\\/couchbase-nosql-dbaas.png\",\"articleSection\":[\"Uncategorized\"],\"inLanguage\":\"es\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/game-servers-and-couchbase-nodejs-part-1\\\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/game-servers-and-couchbase-nodejs-part-1\\\/\",\"url\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/game-servers-and-couchbase-nodejs-part-1\\\/\",\"name\":\"Game Servers and Couchbase with Node.js - Part 1\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/game-servers-and-couchbase-nodejs-part-1\\\/#primaryimage\"},\"image\":{\"@id\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/game-servers-and-couchbase-nodejs-part-1\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/wp-content\\\/uploads\\\/sites\\\/1\\\/2022\\\/11\\\/couchbase-nosql-dbaas.png\",\"datePublished\":\"2014-12-16T19:31:59+00:00\",\"dateModified\":\"2023-06-28T07:24:10+00:00\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/game-servers-and-couchbase-nodejs-part-1\\\/#breadcrumb\"},\"inLanguage\":\"es\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/game-servers-and-couchbase-nodejs-part-1\\\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"es\",\"@id\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/game-servers-and-couchbase-nodejs-part-1\\\/#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\\\/game-servers-and-couchbase-nodejs-part-1\\\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Game Servers and Couchbase with Node.js &#8211; Part 1\"}]},{\"@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\\\/5cfc2fbf25776be2a027a474562be02f\",\"name\":\"Brett Lawson, Principal Software Engineer, Couchbase\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"es\",\"@id\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/6aec1ba24ef7558a248dcde7b7a18b15b06e2885b24b663906a448634066c1c4?s=96&d=mm&r=gee3586f0c112c20e863af447d44dec8f\",\"url\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/6aec1ba24ef7558a248dcde7b7a18b15b06e2885b24b663906a448634066c1c4?s=96&d=mm&r=g\",\"contentUrl\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/6aec1ba24ef7558a248dcde7b7a18b15b06e2885b24b663906a448634066c1c4?s=96&d=mm&r=g\",\"caption\":\"Brett Lawson, Principal Software Engineer, Couchbase\"},\"description\":\"Brett Lawson is a Principal Software Engineer at Couchbase. Brett is responsible for the design and development of the Couchbase Node.js and PHP clients as well as playing a role in the design and development of the C library, libcouchbase.\",\"url\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/es\\\/author\\\/brett-lawson\\\/\"}]}<\/script>\n<!-- \/ Yoast SEO Premium plugin. -->","yoast_head_json":{"title":"Game Servers and Couchbase with Node.js - Part 1","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\/game-servers-and-couchbase-nodejs-part-1\/","og_locale":"es_MX","og_type":"article","og_title":"Game Servers and Couchbase with Node.js - Part 1","og_description":"It seems these days that almost every game studio has been working on networked games where players can interact and co-operate with their friends and other players around the world. Considering my previous experience building such servers and that Couchbase [&hellip;]","og_url":"https:\/\/www.couchbase.com\/blog\/es\/game-servers-and-couchbase-nodejs-part-1\/","og_site_name":"The Couchbase Blog","article_published_time":"2014-12-16T19:31:59+00:00","article_modified_time":"2023-06-28T07:24:10+00:00","author":"Brett Lawson, Principal Software Engineer, Couchbase","twitter_card":"summary_large_image","twitter_misc":{"Written by":"Brett Lawson, Principal Software Engineer, Couchbase","Est. reading time":"11 minutos"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/www.couchbase.com\/blog\/game-servers-and-couchbase-nodejs-part-1\/#article","isPartOf":{"@id":"https:\/\/www.couchbase.com\/blog\/game-servers-and-couchbase-nodejs-part-1\/"},"author":{"name":"Brett Lawson, Principal Software Engineer, Couchbase","@id":"https:\/\/www.couchbase.com\/blog\/#\/schema\/person\/5cfc2fbf25776be2a027a474562be02f"},"headline":"Game Servers and Couchbase with Node.js &#8211; Part 1","datePublished":"2014-12-16T19:31:59+00:00","dateModified":"2023-06-28T07:24:10+00:00","mainEntityOfPage":{"@id":"https:\/\/www.couchbase.com\/blog\/game-servers-and-couchbase-nodejs-part-1\/"},"wordCount":2214,"commentCount":16,"publisher":{"@id":"https:\/\/www.couchbase.com\/blog\/#organization"},"image":{"@id":"https:\/\/www.couchbase.com\/blog\/game-servers-and-couchbase-nodejs-part-1\/#primaryimage"},"thumbnailUrl":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2022\/11\/couchbase-nosql-dbaas.png","articleSection":["Uncategorized"],"inLanguage":"es","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/www.couchbase.com\/blog\/game-servers-and-couchbase-nodejs-part-1\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/www.couchbase.com\/blog\/game-servers-and-couchbase-nodejs-part-1\/","url":"https:\/\/www.couchbase.com\/blog\/game-servers-and-couchbase-nodejs-part-1\/","name":"Game Servers and Couchbase with Node.js - Part 1","isPartOf":{"@id":"https:\/\/www.couchbase.com\/blog\/#website"},"primaryImageOfPage":{"@id":"https:\/\/www.couchbase.com\/blog\/game-servers-and-couchbase-nodejs-part-1\/#primaryimage"},"image":{"@id":"https:\/\/www.couchbase.com\/blog\/game-servers-and-couchbase-nodejs-part-1\/#primaryimage"},"thumbnailUrl":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2022\/11\/couchbase-nosql-dbaas.png","datePublished":"2014-12-16T19:31:59+00:00","dateModified":"2023-06-28T07:24:10+00:00","breadcrumb":{"@id":"https:\/\/www.couchbase.com\/blog\/game-servers-and-couchbase-nodejs-part-1\/#breadcrumb"},"inLanguage":"es","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.couchbase.com\/blog\/game-servers-and-couchbase-nodejs-part-1\/"]}]},{"@type":"ImageObject","inLanguage":"es","@id":"https:\/\/www.couchbase.com\/blog\/game-servers-and-couchbase-nodejs-part-1\/#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\/game-servers-and-couchbase-nodejs-part-1\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/www.couchbase.com\/blog\/"},{"@type":"ListItem","position":2,"name":"Game Servers and Couchbase with Node.js &#8211; Part 1"}]},{"@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\/5cfc2fbf25776be2a027a474562be02f","name":"Brett Lawson, Ingeniero de Software Principal, Couchbase","image":{"@type":"ImageObject","inLanguage":"es","@id":"https:\/\/secure.gravatar.com\/avatar\/6aec1ba24ef7558a248dcde7b7a18b15b06e2885b24b663906a448634066c1c4?s=96&d=mm&r=gee3586f0c112c20e863af447d44dec8f","url":"https:\/\/secure.gravatar.com\/avatar\/6aec1ba24ef7558a248dcde7b7a18b15b06e2885b24b663906a448634066c1c4?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/6aec1ba24ef7558a248dcde7b7a18b15b06e2885b24b663906a448634066c1c4?s=96&d=mm&r=g","caption":"Brett Lawson, Principal Software Engineer, Couchbase"},"description":"Brett Lawson es Ingeniero de Software Principal en Couchbase. Brett es responsable del dise\u00f1o y desarrollo de los clientes Node.js y PHP de Couchbase, adem\u00e1s de participar en el dise\u00f1o y desarrollo de la biblioteca C, libcouchbase.","url":"https:\/\/www.couchbase.com\/blog\/es\/author\/brett-lawson\/"}]}},"acf":[],"authors":[{"term_id":9004,"user_id":31,"is_guest":0,"slug":"brett-lawson","display_name":"Brett Lawson, Principal Software Engineer, Couchbase","avatar_url":"https:\/\/secure.gravatar.com\/avatar\/6aec1ba24ef7558a248dcde7b7a18b15b06e2885b24b663906a448634066c1c4?s=96&d=mm&r=g","0":null,"1":"","2":"","3":"","4":"","5":"","6":"","7":"","8":""}],"_links":{"self":[{"href":"https:\/\/www.couchbase.com\/blog\/es\/wp-json\/wp\/v2\/posts\/1614","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\/31"}],"replies":[{"embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/es\/wp-json\/wp\/v2\/comments?post=1614"}],"version-history":[{"count":0,"href":"https:\/\/www.couchbase.com\/blog\/es\/wp-json\/wp\/v2\/posts\/1614\/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=1614"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/es\/wp-json\/wp\/v2\/categories?post=1614"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/es\/wp-json\/wp\/v2\/tags?post=1614"},{"taxonomy":"author","embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/es\/wp-json\/wp\/v2\/ppma_author?post=1614"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}