{"id":713,"date":"2025-07-15T10:48:20","date_gmt":"2025-07-15T10:48:20","guid":{"rendered":"https:\/\/blogs.ua.es\/jpm33\/?p=713"},"modified":"2025-07-15T10:48:20","modified_gmt":"2025-07-15T10:48:20","slug":"mockear-un-api-con-json-server","status":"publish","type":"post","link":"https:\/\/blogs.ua.es\/jpm33\/2025\/07\/15\/mockear-un-api-con-json-server\/","title":{"rendered":"Mockear un API con json-server"},"content":{"rendered":"\n<figure class=\"wp-block-image size-full\"><a href=\"https:\/\/blogs.ua.es\/jpm33\/files\/2025\/07\/image-7.png\"><img loading=\"lazy\" decoding=\"async\" width=\"800\" height=\"320\" src=\"https:\/\/blogs.ua.es\/jpm33\/files\/2025\/07\/image-7.png\" alt=\"\" class=\"wp-image-719\" \/><\/a><\/figure>\n\n\n\n<p>json-server es una herramienta NodeJS que nos permite prototipar o mockear un API REST de forma muy r\u00e1pida. Ya sea para empezar un desarrollo Frontend si esperar al desarrollo del BackEnd o porqu\u00e9 necesitamos mockear el BackEnd por el motivo que sea.<\/p>\n\n\n\n<p>Una vez definido el API a usar es muy r\u00e1pido y sencillo usar cualquier petici\u00f3n HTTP con los m\u00e9todos GET, POST, PUT, PATCH, DELETE &#8230;<\/p>\n\n\n\n<!--more-->\n\n\n\n<h2 class=\"wp-block-heading\">Caracteristicas<\/h2>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Creaci\u00f3n r\u00e1pida de API REST<\/li>\n\n\n\n<li>Basado en un archivo JSON<\/li>\n\n\n\n<li>Funcionalidades RESTful b\u00e1sicas<\/li>\n\n\n\n<li>Paginaci\u00f3n, filtros, ordenaci\u00f3n<\/li>\n\n\n\n<li>Soporte para relaciones (anidamiento)<\/li>\n\n\n\n<li>Observaci\u00f3n de cambios en el archivo (hot reloading)<\/li>\n\n\n\n<li>Middleware personalizado<\/li>\n\n\n\n<li>Rutas personalizadas<\/li>\n\n\n\n<li>Generaci\u00f3n de datos aleatorios (Faker.js)<\/li>\n\n\n\n<li>No requiere base de datos<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\">Ventajas<\/h2>\n\n\n\n<ol class=\"wp-block-list\">\n<li>Permite prototipar APIs en minutos sin necesidad de una base de datos real ni l\u00f3gica de servidor compleja. Ideal para pruebas y desarrollo frontend.<\/li>\n\n\n\n<li>Facilita la edici\u00f3n y gesti\u00f3n de los datos directamente en un archivo JSON simple. No se requiere conocimiento de bases de datos.<\/li>\n\n\n\n<li>Soporta m\u00e9todos HTTP comunes (GET, POST, PUT, PATCH, DELETE) para manipular los recursos.<\/li>\n\n\n\n<li>Permite simular consultas de datos realistas con par\u00e1metros de URL para paginaci\u00f3n, filtrado y ordenaci\u00f3n.<\/li>\n\n\n\n<li>Permite simular relaciones entre recursos a trav\u00e9s de la anidaci\u00f3n en el archivo JSON o utilizando la convenci\u00f3n _embed.<\/li>\n\n\n\n<li>Detecta autom\u00e1ticamente los cambios en el archivo JSON y actualiza la API sin reiniciar el servidor.<\/li>\n\n\n\n<li>Permite extender la funcionalidad con middlewares de Express.js para a\u00f1adir l\u00f3gica personalizada (ej. validaci\u00f3n b\u00e1sica).<\/li>\n\n\n\n<li>Posibilidad de definir rutas personalizadas para casos de uso espec\u00edficos que no encajan en el modelo RESTful est\u00e1ndar.<\/li>\n\n\n\n<li>Puede integrarse con librer\u00edas como Faker.js para generar datos de prueba realistas r\u00e1pidamente.<\/li>\n\n\n\n<li>Simplifica el entorno de desarrollo al eliminar la necesidad de configurar y gestionar una base de datos.<\/li>\n<\/ol>\n\n\n\n<h2 class=\"wp-block-heading\">Incovenientes<\/h2>\n\n\n\n<ol class=\"wp-block-list\">\n<li>No apto para producci\u00f3n debido a la falta de seguridad, escalabilidad y funcionalidades empresariales.<\/li>\n\n\n\n<li>La complejidad del archivo JSON puede aumentar r\u00e1pidamente con grandes vol\u00famenes de datos, dificultando su mantenimiento.<\/li>\n\n\n\n<li>Carece de funcionalidades avanzadas como transacciones, autenticaci\u00f3n\/autorizaci\u00f3n robusta, validaci\u00f3n de esquemas complejas, etc.<\/li>\n\n\n\n<li>Las capacidades de consulta son limitadas en comparaci\u00f3n con una base de datos completa. No admite consultas complejas o joins.<\/li>\n\n\n\n<li>Las relaciones complejas pueden volverse dif\u00edciles de manejar y mantener en el archivo JSON.<\/li>\n\n\n\n<li>Puede haber un ligero retraso en la detecci\u00f3n de cambios en archivos muy grandes.<\/li>\n\n\n\n<li>Requiere conocimiento de Express.js. La creaci\u00f3n de middlewares complejos puede anular la simplicidad inicial de JSON-Server.<\/li>\n\n\n\n<li>La sobrecarga de rutas personalizadas puede complicar la configuraci\u00f3n y el mantenimiento.<\/li>\n\n\n\n<li>La configuraci\u00f3n inicial para la generaci\u00f3n de datos puede requerir un poco de c\u00f3digo.<\/li>\n\n\n\n<li>No permite persistencia de datos real entre sesiones o reinicios del servidor sin guardar el archivo JSON manualmente.<\/li>\n<\/ol>\n\n\n\n<h2 class=\"wp-block-heading\">Instalar y crear un proyecto<\/h2>\n\n\n\n<p>Crear un proyecto node des1de cero:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>mkdir projectName\ncd projectName\nnpm init\npackage name: (json-server-demo)\nversion: (1.0.0)\ndescription:\nentry point: (index.js)\ntest command:\ngit repository:\nkeywords:\nauthor:\nlicense: (ISC)\nAbout to write to C:\\devel\\source\\proofOfConcept\\json-server-demo\\package.json:\n\n{\n  \"name\": \"json-server-demo\",\n  \"version\": \"1.0.0\",\n  \"description\": \"\",\n  \"main\": \"index.js\",\n  \"scripts\": {\n    \"test\": \"echo \\\"Error: no test specified\\\" &amp;&amp; exit 1\"\n  },\n  \"author\": \"\",\n  \"license\": \"ISC\"\n}\n\n\nIs this OK? (yes) yes<\/code><\/pre>\n\n\n\n<p>Esto nos crea un ficheero <code style=\"background:gainsboro\">package.json<\/code> que describe la informaci\u00f3n del paquete npm (todo proyecto npm es en s\u00ed mismo un paquete npm).<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Instalar json-server<\/h2>\n\n\n\n<p>Ahora hace falta instalar<strong> json-server<\/strong> y usuarlo, podemos instalarlo de forma global como una herramienta nodejs m\u00e1s o como una librer\u00eda de nuestro proyecto (que quedar\u00eda en la subcarpeta <strong>node_modules<\/strong>):<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Global: <code>npm install -g json-server<\/code><\/li>\n\n\n\n<li>Local: <code>npm install json-server<\/code><\/li>\n<\/ul>\n\n\n\n<p>En el primer caso podremos ejecutar el comando escribien &#8220;json-server&#8221; en cualquier ruta del equipo donde node est\u00e9 en el PATH. Para el segundo caso necesitamos usar el comando npx de node y hay que ejecutarlo en la carpeta ra\u00edz del proyecto que hemos creado y donde lo hemos instalado. As\u00ed:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>npx json-server (pero aun no lo vamos a ejecutar!)<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">Configurar los datos y las rutas<\/h2>\n\n\n\n<p>Necesitamos un fichero donde est\u00e9n los documentos JSON que van a devolver los endpoint REST que queremos mockear. Para ello, creamos un fichero <code style=\"background:gainsboro\">db.json<\/code> con &#8220;base de datos&#8221; de los ficheros JSON de cada endpoint, como esta:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>{\n  \"posts\": &#091;\n    { \"id\": \"1\", \"title\": \"a title\", \"views\": 100 },\n    { \"id\": \"2\", \"title\": \"another title\", \"views\": 200 }\n  ],\n  \"comments\": &#091;\n    { \"id\": \"1\", \"text\": \"a comment about post 1\", \"postId\": \"1\" },\n    { \"id\": \"2\", \"text\": \"another comment about post 1\", \"postId\": \"1\" }\n  ],\n  \"profile\": {\n    \"name\": \"typicode\"\n  }\n}<\/code><\/pre>\n\n\n\n<p>Ahora ya podriamos arrancar la aplicaci\u00f3n con el comando:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>npx json-server -h 0.0.0.0 -p 8080 db.json\nJSON Server started on PORT :8080\nPress CTRL-C to stop\nWatching db.json...\n\n\u2661( \u25e1\u203f\u25e1 )\n\nIndex:\nhttp:&#047;&#047;localhost:8080\/\n\nStatic files:\nServing .\/public directory if it exists\n\nEndpoints:\nhttp:\/\/0.0.0.0:8080\/posts\nhttp:\/\/0.0.0.0:8080\/comments\nhttp:\/\/0.0.0.0:8080\/profile<\/code><\/pre>\n\n\n\n<p>Aqu\u00ed vemos que el programa detecta las 3 entradas que hemos creado con sus colecciones y nos indica los endpoints disponibles que ya se pueden usar con cURL, xHTTPRequest, etc. En Web tambien funciona:<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><a href=\"https:\/\/blogs.ua.es\/jpm33\/files\/2025\/07\/image-6.png\"><img loading=\"lazy\" decoding=\"async\" width=\"286\" height=\"290\" src=\"https:\/\/blogs.ua.es\/jpm33\/files\/2025\/07\/image-6.png\" alt=\"\" class=\"wp-image-717\" \/><\/a><\/figure>\n\n\n\n<p>Tendremos disponibles las operaciones habituales REST:<\/p>\n\n\n\n<p><code>GET \/posts<br>GET \/posts\/1<br>POST \/posts<br>PUT \/posts\/1<br>DELETE \/posts\/1<br>GET \/comments<br>GET \/comments\/1<\/code><\/p>\n\n\n\n<p>En versiones anteriores (la actual es la 1.0.0-beta.3) se podia crear un fichero routes.json donde se mapeaban endpoints externos con las rutas del fichero. Por ejemplo si en realidad un API es \/v1\/blog\/entradas y en el fichero es \/posts configurar esa relaci\u00f3n de forma que hacemos peticiones a \/v1\/blog\/entradas y resuelve con los objetos de \/posts.<\/p>\n\n\n\n<p>Un ejemplo m\u00e1s claro ser\u00eda algo as\u00ed:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>{\n  \"\/api\/posts\": \"\/posts\",\n  \"\/api\/comments\": \"\/comments\",\n  \"\/blog\/:resource\/:id\/show\": \"\/:resource\/:id\"\n}<\/code><\/pre>\n\n\n\n<p>En el \u00faltimo caso, tenemos unas URLS que dependiendo del :resource: accede a una secci\u00f3n u otra del fichero. <strong style=\"color: darkred\">Actualmente est\u00e1 en desuso<\/strong>. Para usarlo hay que instalar una versi\u00f3n anterior de json-server (en node con @version le indicamos a npm una version concreta):<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>npm install -g json-server@0.17.4<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">A\u00f1adir un middleware<\/h2>\n\n\n\n<p><strong style=\"color: darkred\">Actualmente tambi\u00e9n est\u00e1 en desuso<\/strong>. Debemos usar una versi\u00f3n anterior a la 1.x.<\/p>\n\n\n\n<p>Para ampliar todas estas funcionalidades podemos crear nuestro programa node (index.js) y que implemente un json-server (basado en Express) y detallar program\u00e1ticamente su comportamiento.<\/p>\n\n\n\n<p>En este caso se ejecutar\u00e1 como node index.js o npm start si actualizamos package.json (m\u00e1s abajo la versi\u00f3n modificada).<\/p>\n\n\n\n<p>Un fichero ejemplo:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>\/\/ server.js\nconst jsonServer = require('json-server')\nconst server = jsonServer.create()\nconst router = jsonServer.router('db.json')\nconst middlewares = jsonServer.defaults()\n\nserver.use(middlewares)\n\n\/\/ Add custom middleware before JSON Server router\nserver.use((req, res, next) =&gt; {\n  console.log('Time:', Date.now())\n  next()\n})\n\nserver.use(router)\nserver.listen(3000, () =&gt; {\n  console.log('JSON Server is running')\n})<\/code><\/pre>\n\n\n\n<p><\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Referencias<\/h2>\n\n\n\n<ol class=\"wp-block-list\">\n<li><a href=\"https:\/\/www.npmjs.com\/package\/json-server\">json-server<\/a><\/li>\n\n\n\n<li><a href=\"https:\/\/docs.npmjs.com\/cli\/v11\/configuring-npm\/package-json\">package-json<\/a><\/li>\n\n\n\n<li><a href=\"https:\/\/expressjs.com\/\">ExpressJS<\/a><\/li>\n<\/ol>\n\n\n\n<p><\/p>\n","protected":false},"excerpt":{"rendered":"<p>json-server es una herramienta NodeJS que nos permite prototipar o mockear un API REST de forma muy r\u00e1pida. Ya sea para empezar un desarrollo Frontend si esperar al desarrollo del BackEnd o porqu\u00e9 necesitamos mockear el BackEnd por el motivo &hellip; <a href=\"https:\/\/blogs.ua.es\/jpm33\/2025\/07\/15\/mockear-un-api-con-json-server\/\">Continue reading <span class=\"meta-nav\">&rarr;<\/span><\/a><\/p>\n","protected":false},"author":3080,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[135,374,236731],"tags":[236729,236718,23],"class_list":["post-713","post","type-post","status-publish","format-standard","hentry","category-linux","category-programacion","category-web","tag-linux","tag-programacion-2","tag-web"],"_links":{"self":[{"href":"https:\/\/blogs.ua.es\/jpm33\/wp-json\/wp\/v2\/posts\/713","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/blogs.ua.es\/jpm33\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blogs.ua.es\/jpm33\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blogs.ua.es\/jpm33\/wp-json\/wp\/v2\/users\/3080"}],"replies":[{"embeddable":true,"href":"https:\/\/blogs.ua.es\/jpm33\/wp-json\/wp\/v2\/comments?post=713"}],"version-history":[{"count":5,"href":"https:\/\/blogs.ua.es\/jpm33\/wp-json\/wp\/v2\/posts\/713\/revisions"}],"predecessor-version":[{"id":720,"href":"https:\/\/blogs.ua.es\/jpm33\/wp-json\/wp\/v2\/posts\/713\/revisions\/720"}],"wp:attachment":[{"href":"https:\/\/blogs.ua.es\/jpm33\/wp-json\/wp\/v2\/media?parent=713"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blogs.ua.es\/jpm33\/wp-json\/wp\/v2\/categories?post=713"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blogs.ua.es\/jpm33\/wp-json\/wp\/v2\/tags?post=713"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}