Cómo construir API RESTful simple con NodeJs, ExpressJs y MongoDb

Actualizado el 11 de julio de 2019: es un hito importante para este artículo llegar a más de 70,000 lectores y, a partir de los comentarios, ha sido útil para muchas personas que intentan construir APIs con NodeJs. Para mejorar esto, he actualizado fragmentos de código en este tutorial para corregir los errores identificados por la mayoría de los lectores. Gracias a todos por sus amables respuestas, espero encontrar tiempo pronto para escribir otra buena. Ve y crea aplicaciones increíbles para el mundo - David Inyangetoh

Las API RESTFul han existido desde hace algún tiempo. En el momento de esta redacción, es prácticamente imposible para usted ser un desarrollador de software sin tener que crear y usar una o más API.

API es un acrónimo de Application Programming Interface que se ha convertido en una parte integral del desarrollo de software. "Es un conjunto de métodos de comunicación claramente definidos entre varios componentes" - Wikipedia.

Las API RESTFul, por otro lado, son API que se ajustan al estilo arquitectónico REST. REST se refiere a la transferencia de estado representacional que "es un estilo arquitectónico que define un conjunto de restricciones y propiedades basadas en HTTP".

La implementación más común del servicio web RESTFul es la API JSON y con eso trabajaremos en este tutorial. Puede obtener más información sobre las especificaciones, ejemplos e implementación de JSONAPI aquí. JSON es simplemente JavaScript Object Notation.

En este tutorial, creamos una API simple usando ExpressJs y MongoDb con funciones CRUD para Contactos.

Aplicaciones requeridas

  • NodeJS
  • Cartero
  • MongoDb
  • IDE

Empecemos…

Bootstrapping el proyecto

Para iniciar nuestro proyecto, debemos verificar que tenemos NodeJs, NPM y MongoDb instalados en nuestra máquina. Para hacer eso, abra su terminal o símbolo del sistema y ejecute

nodo -v

Esto verifica la versión de Nodejs instalada. correr

npm -v

para verificar Node Package Manager (npm) instalado. Ver salida a continuación

Ahora que hemos verificado que Node y NPM están instalados, podemos continuar con la configuración de nuestro proyecto. Si Node no está instalado en su máquina, debe descargar una versión compatible con su sistema operativo aquí e instalar antes de continuar.

A continuación, debemos verificar que MongoDb esté instalado ejecutando

mongo --version

Qué salidas ...

Si MongoDb no está instalado en su máquina, debe dirigirse al Centro de descargas de MongoDb, descargar e instalar la versión compatible con su sistema operativo antes de continuar.

Nombrando nuestro proyecto

Ahora es el momento de dar un nombre a nuestro proyecto y lo llamaremos RESTHub. Necesitamos encontrar una buena ubicación en nuestro sistema de archivos para almacenar nuestros archivos de proyecto. Personalmente, dado que trabajo con diferentes herramientas y lenguajes de programación, elegí mantener mis proyectos basados ​​en nodos en un directorio de proyectos de nodo en mi disco local. Aquí es donde crearé mi nuevo directorio de proyecto resthub con los siguientes comandos

// Navega al directorio raíz de tus proyectos de Nodo
cd C: \ nodeprojects
// Crea un directorio para tu nuevo proyecto RestHub
mkdir resthub
// Navega en el directorio
CD resthub

Inicialice el proyecto NodeJs con npm init, siga el asistente para configurar el proyecto.

Acepte el nombre y la versión predeterminados, pero cambie la descripción como se muestra arriba. No olvides cambiar el nombre del autor a tu nombre y aceptar la licencia predeterminada para generar package.json. No se preocupe por algunas de las entradas si cometió un error, el archivo estará disponible en el directorio raíz del proyecto para que pueda editarlo a voluntad. Deberías tener una pantalla similar a esta ...

En este punto, debe verificar que tiene un archivo package.json disponible en la raíz de su proyecto enumerando los archivos con ls -l o dir dependiendo de su sistema operativo.

Hora de instalar Express y configurar el servidor

Necesitamos ejecutar un servidor web para que nuestro punto final de API sea accesible para el navegador o una herramienta como PostMan, usaremos ExpressJS para lograr esto. Si no está familiarizado con ExpressJS, diríjase al sitio web oficial para obtener más información; de lo contrario, continuemos. Con npm instalamos Express en nuestro proyecto con este comando

npm install express --save

Tomará un tiempo completar la instalación dependiendo de la velocidad de su conexión, pero al final expressJs y sus dependencias se instalarán de la siguiente manera.

Basta de todas estas instalaciones, asistentes y configuraciones. Necesitamos comenzar a escribir código ahora. Cuando abres tu IDE preferido, el mío es Visual Studio Code.

Use su IDE preferido para abrir el directorio del proyecto y crear un archivo index.js

Puede ver un directorio node_modules y un archivo package.json. Package.json almacena la configuración del proyecto nodeJs, incluidas las dependencias. Puede ver el expressjs -v4.16.3 recién instalado en dependencias. Los paquetes de nodos instalados se encuentran en node_modules y no debemos modificar nada en ese directorio, sino que debemos excluirlos con gitignore cuando estamos empujando a un repositorio remoto. En nuestro package.json, definimos index.js como el punto de entrada de nuestra aplicación. Necesitamos crear ese archivo ahora y configurar nuestro servidor web.

En su IDE, cree un archivo index.js y agregue este código ...

// FileName: index.js
// Importar express
let express = require ('express')
// Inicializa la aplicación
let app = express ();
// Configurar el puerto del servidor
var puerto = proceso.env.PORT || 8080;
// Enviar mensaje para la URL predeterminada
app.get ('/', (req, res) => res.send ('Hola Mundo con Express'));
// Inicia la aplicación para escuchar el puerto especificado
app.listen (puerto, función () {
     console.log ("Ejecutar RestHub en el puerto" + puerto);
});

Guarde el archivo y ejecute el índice de nodo en la ventana de terminal. Deberías conseguir esto

Dirígete a http: // localhost: 8080 en tu navegador y deberías ver ...

¡¡¡Hurra!!! Nuestro servidor express ahora está en funcionamiento. Lo hicimos ... ¡sí! Nada es tan dulce como hacer que su configuración funcione sin problemas. Si no está obteniendo el mismo resultado que el mío en este momento, repítalo nuevamente para verificar si omitió algún punto o punto y coma.

Muy bien, estructuramos nuestra aplicación un poco profesionalmente. Aunque seguiré algunas de las mejores prácticas a medida que implementemos esto, lo mantendré lo más simple posible. Es un tutorial para principiantes y la mayoría de los tutoriales que he encontrado en el pasado tienden a agrupar todo en un solo archivo para implementar API simples como esta. En el mundo real, esto no sucede especialmente si su equipo elige una arquitectura como el patrón MVC.

Vamos a inyectar un poco de MVC en la estructura de esta aplicación para mantener nuestros archivos sin problemas y preocupaciones separadas. Necesitamos tres archivos más enumerados a continuación ...

  • rutas-api: todos los puntos finales api se definirán en este archivo
  • controlador: procesa solicitudes HTTP y define puntos finales disponibles
  • modelo: administra la capa de base de datos (solicitud y respuesta)

Cree un archivo en la raíz de su proyecto api-routes.js y agregue el siguiente código.

// Nombre de archivo: api-routes.js
// Inicializa el enrutador express
let router = require ('express'). Router ();
// Establecer respuesta de API predeterminada
router.get ('/', function (req, res) {
    res.json ({
        estado: 'API está funcionando',
        mensaje: '¡Bienvenido a RESTHub creado con amor!'
    });
});
// Exportar rutas API
module.exports = enrutador;

Primero importamos el enrutador rápido, establecemos la ruta predeterminada y exportamos el módulo para que podamos importarlo a nuestra aplicación. Para que esta ruta sea accesible, necesitamos modificar index.js y agregarle algunas líneas de código.

// Agrega el siguiente código a index.js
// Importar rutas
let apiRoutes = require ("./ api-routes")
// Usa rutas Api en la aplicación
app.use ('/ api', apiRoutes)

luego reinicie el servidor de aplicaciones finalizando el proceso en su terminal con ctrl + c o cmd + c y comience nuevamente con el índice de nodo.

En el código anterior, importamos el archivo api-routes y le indicamos a nuestra aplicación que use estas rutas siempre que un usuario visite example.com/api o http: // localhost: 8080 / api en nuestro caso. Pruebe si funciona visitando http: // localhost: 8080 / api, debería ver esta pantalla

¡Sí! Funcionó. Puedes tomarte un descanso y beber una botella de agua como acabo de hacer. Estamos haciendo un buen progreso, pero necesitamos arreglar un pequeño cuello de botella para que nuestro progreso sea más fluido.

Nuestra configuración actual requiere que reiniciemos el servidor cada vez que realicemos cambios en nuestros archivos o agreguemos nuevos. Esto puede ser estresante y frustrante a veces, pero hay una solución rápida para ello. Hay un módulo de nodo que proporciona esa solución rápida; mira sus archivos y reinicia el servidor express cuando hay cambios. Es mejor instalar este módulo globalmente, ya que puede necesitarlo en otros proyectos como este.

npm install -g nodemon
// En Mac o Linux
sudo npm install -g nodemon

Ahora que ha instalado nodemon, inicie su aplicación con nodemon index y cambie el texto en la ruta predeterminada de Hello World con Express y Nodemon y actualice su navegador para ver los cambios.

Genial, no tenemos que preocuparnos por reiniciar nuestro servidor de aplicaciones nuevamente cada vez que hacemos cambios.

Configurando MongoDb

Quiero suponer que tiene MongoDb instalado en su máquina; de lo contrario, visite el Centro de descargas de Mongodb para descargar e instalar. Abra otra ventana de terminal e inicie el servidor mongodb con este comando

mongod

obtendrá una salida similar a esta

mantenga esta ventana abierta para usar MongoDb. Dirígete a la terminal raíz de tu proyecto e instala estos paquetes

  • mangosta npm instalar mangosta --save
  • body-parser npm install body-parser --save

Mongoose es el paquete Nodejs para modelar Mongodb. Le ayuda a manejar la validación y la lógica de negocios para mongodb en Nodejs. Puedes aprender más aqui.

Body-parser permite que su aplicación analice datos de solicitudes entrantes como datos de formulario a través de urlencode. Necesitamos importar esto a nuestra aplicación y usarlos.

Modifique index.js con estas líneas
Actualización: He actualizado la línea de conexión Mongoose para agregar la opción useNewUrlParser y corregir la advertencia de desaprobación

// Importar analizador de cuerpo
let bodyParser = require ('body-parser');
// Importar mangosta
let mongoose = require ('mangosta');
// Configurar bodyparser para manejar solicitudes de publicación
app.use (bodyParser.urlencoded ({
   extendido: verdadero
}));
app.use (bodyParser.json ());
// Conéctate a Mongoose y establece la variable de conexión
// En desuso: mongoose.connect ('mongodb: // localhost / resthub');
mongoose.connect ('mongodb: // localhost / resthub', {useNewUrlParser: true});
var db = mangosta.conexión;

Su index.js completo debería verse así

// Importar express
let express = require ('express');
// Importar analizador de cuerpo
let bodyParser = require ('body-parser');
// Importar mangosta
let mongoose = require ('mangosta');
// Inicializa la aplicación
let app = express ();

// Importar rutas
let apiRoutes = require ("./ api-routes");
// Configurar bodyparser para manejar solicitudes de publicación
app.use (bodyParser.urlencoded ({
    extendido: verdadero
}));
app.use (bodyParser.json ());
// Conéctate a Mongoose y establece la variable de conexión
mongoose.connect ('mongodb: // localhost / resthub', {useNewUrlParser: true});
var db = mangosta.conexión;

// Se agregó la verificación de la conexión de la base
si (! db)
    console.log ("Error al conectar db")
más
    console.log ("Db conectado correctamente")

// Configurar el puerto del servidor
var puerto = proceso.env.PORT || 8080;

// Enviar mensaje para URL predeterminada
app.get ('/', (req, res) => res.send ('Hola Mundo con Express'));

// Usa rutas Api en la aplicación
app.use ('/ api', apiRoutes);
// Inicia la aplicación para escuchar el puerto especificado
app.listen (puerto, función () {
    console.log ("Ejecutar RestHub en el puerto" + puerto);
});

Todo debería funcionar bien. Ahora es el momento de configurar nuestro controlador para manejar la solicitud de API y el Modelo para guardar / recuperar datos de la base de datos. Implementaremos un modelo de datos simple que almacena la información de contacto con los siguientes detalles:

  • Nombre
  • Email
  • Teléfono
  • Género

Implementaremos los siguientes puntos finales

  • GET / api / contactos lista todos los contactos
  • POST / api / contactos crear nuevo contacto
  • GET / api / contactos / {id} recupera un solo contacto
  • PUT / api / contactos / {id} actualizar un solo contacto
  • BORRAR / api / contactos / {id} eliminar un solo contacto

Vamos a dos (2) archivos más contactController.js y contactModel.js y pegaremos estos códigos.

// contactController.js
// Importar modelo de contacto
Contacto = require ('./ contactModel');
// Manejar acciones de índice
export.index = function (req, res) {
    Contact.get (función (err, contactos) {
        si (err) {
            res.json ({
                estado: "error",
                mensaje: err,
            });
        }
        res.json ({
            estado: "éxito",
            mensaje: "Contactos recuperados con éxito",
            datos: contactos
        });
    });
};
// Manejar crear acciones de contacto
export.new = function (req, res) {
    contacto var = nuevo contacto ();
    contact.name = req.body.name? req.body.name: contact.name;
    contact.gender = req.body.gender;
    contact.email = req.body.email;
    contact.phone = req.body.phone;
// guarda el contacto y busca errores
    contact.save (function (err) {
        // if (err)
        // res.json (err);
res.json ({
            mensaje: '¡Nuevo contacto creado!',
            datos: contacto
        });
    });
};
// Manejar ver información de contacto
export.view = function (req, res) {
    Contact.findById (req.params.contact_id, function (err, contact) {
        si (err)
            res.send (err);
        res.json ({
            mensaje: 'Datos de contacto cargando ...',
            datos: contacto
        });
    });
};
// Manejar la información de contacto de actualización
export.update = function (req, res) {
Contact.findById (req.params.contact_id, function (err, contact) {
        si (err)
            res.send (err);
contact.name = req.body.name? req.body.name: contact.name;
        contact.gender = req.body.gender;
        contact.email = req.body.email;
        contact.phone = req.body.phone;
// guarda el contacto y busca errores
        contact.save (function (err) {
            si (err)
                res.json (err);
            res.json ({
                mensaje: 'Información de contacto actualizada',
                datos: contacto
            });
        });
    });
};
// Manejar eliminar contacto
exportaciones.delete = función (req, res) {
    Contact.remove ({
        _id: req.params.contact_id
    }, función (err, contacto) {
        si (err)
            res.send (err);
res.json ({
            estado: "éxito",
            mensaje: 'Contacto eliminado'
        });
    });
};

El controlador definió el método que maneja la solicitud y la respuesta de diferentes puntos finales API. En primer lugar, importamos contactModel y usamos su instancia para manejar las funciones CRUD (Crear, Recuperar, Actualizar y Eliminar) de la API. Aquí está el código para contactModel.js

// contactModel.js
var mongoose = require ('mangosta');
// Esquema de configuración
var contactSchema = mongoose.Schema ({
    nombre: {
        tipo: cadena,
        requerido: verdadero
    },
    correo electrónico: {
        tipo: cadena,
        requerido: verdadero
    },
    género: cadena,
    teléfono: cadena,
    Fecha de Creación: {
        tipo: Fecha,
        predeterminado: Date.now
    }
});
// Exportar modelo de contacto
var Contact = module.exports = mongoose.model ('contact', contactSchema);
module.exports.get = function (devolución de llamada, límite) {
    Contact.find (devolución de llamada) .limit (límite);
}

En el modelo, importamos mangosta, creamos el esquema de la base de datos para los contactos y exportamos el módulo para que sea accesible. La última actualización agregará rutas de contacto a nuestros puntos finales de la API. Aquí está el código completo para api-routes.js

// api-routes.js
// Inicializa el enrutador express
let router = require ('express'). Router ();
// Establecer respuesta de API predeterminada
router.get ('/', function (req, res) {
    res.json ({
        estado: 'API está funcionando',
        mensaje: '¡Bienvenido a RESTHub creado con amor!',
    });
});
// Importar controlador de contacto
var contactController = require ('./ contactController');
// Rutas de contacto
router.route ('/ contactos')
    .get (contactController.index)
    .post (contactController.new);
router.route ('/ contactos /: contact_id')
    .get (contactController.view)
    .patch (contactController.update)
    .put (contactController.update)
    .delete (contactController.delete);
// Exportar rutas API
module.exports = enrutador;

¡Guauu! Ha sido un viaje muy largo. Hemos terminado de cocinar y es hora de probar nuestros puntos finales de la API.

Probemos con el navegador. Visite http: // localhost: 8080 / api / contactos, debería obtener esta pantalla

Se ve bien. Todavía no tenemos contactos en nuestra colección. Necesitamos agregarle algunos contactos. Postman es una muy buena herramienta para probar y depurar el punto final de la API, si tiene uno instalado en su máquina, consígalo aquí. Parece que…

Acabo de probar los contactos / api / en Postman y obtuve el mismo resultado.

También es compatible con una larga lista de tipos de solicitud, incluidos HTTP GET básico, POST, PUT, DELETE.

Para agregar un nuevo contacto, cambie el método del menú desplegable a POST, seleccione la pestaña Cuerpo, proporcione valores para la clave: cuadros de entrada de valor debajo de la pestaña cuerpo y haga clic en enviar cuando haya terminado. Ver ejemplo a continuación:

Cambie los valores para crear otro contacto. Abra otra pestaña y use la solicitud GET para ver todos los contactos así.

Actualice su navegador para ver si se ha actualizado. Deberías obtener esta pantalla.

Muy bien chicos, hemos llegado al final de nuestra larga sesión. Siga adelante y pruebe actualizar y eliminar. Intenta construir algo genial y difundir el Evangelio. Puedes atraparme en twitter, facebook, github y linkedin a través de @dinyangetoh

Ah, casi me olvido de agregar el enlace github para los archivos fuente. Siéntase libre de clonarlo aquí y diviértase creando aplicaciones increíbles.

Enlaces actualizados:

Aplicación Heroku: https://resthub2.herokuapp.com

Github: https://github.com/dinyangetoh/resthub2