A lo largo de los años, existieron algunas interfaces de comunicación (API) populares entre cliente y servidor. Sin embargo, el más popular se llama REST definido en 2000 por Roy Fielding. Es una arquitectura que aprovecha el protocolo HTTP para permitir la comunicación entre un cliente y una aplicación de servidor. Una aplicación de servidor que ofrece una API REST también se denomina servidor RESTful. Los servidores que no siguen la arquitectura REST al 100% se llaman RESTish en lugar de RESTful. A continuación, implementaremos dicha API REST para nuestra aplicación de servidor Express, pero primero conozcamos las herramientas que nos permiten interactuar con una API REST.
De MySQL Community Downloads, descargue e instale:
Desde la línea de comandos, en la raíz de la carpeta del proyecto. Instale Dotenv, con:
npm install --save-dev dotenv
En el archivo app.js
, agregue el módulo dotenv
y cargue los datos de configuración.
/* CARGA DE DATOS DE CONFIGURACION EN MEMORIA */
require('dotenv').config();
var createError = require('http-errors');
var express = require('express');
...
Desde la línea de comandos, acceda a la interfaz de nodeJS, con:
node
Genere y copie la secuencia de datos aleatorios, con:
> let crypto = require('crypto');
> crypto.randomBytes(16).toString('base64');
En la raíz del proyecto, cree el archivo .env
. Agregue la variable SALT con la secuencia de datos aleatorios.
SALT=...8uUYwT...
Modifique el manejador de rutas rest/users.js, cargue:
Sequelize
y Op
del módulo sequelize, yUsers
var express = require('express');
var router = express.Router();
/* Módulo crypto */
let crypto = require('crypto');
const { Sequelize, Op } = require('sequelize');
const Users = require('../models').users;
...
Para obtener TODOS los registros de una entidad en una base de datos relacional, implemente el controlador para el verbo GET con y el requerimiento al método findAll del modelo.
Cree el controlador para el verbo GET de la ruta /findAll/json
que retorna un json con todos los usuarios.
/* GET users listing. */
router.get('/findAll/json', function(req, res, next) {
Users.findAll({
})
.then(users => {
res.json(users);
})
.catch(error => res.status(400).send(error))
});
...
http://localhost:3000/users/findAll/json
Para obtener UN registro de una entidad en una base de datos relacional, implemente el controlador para el verbo GET y el requerimiento al método findOne del modelo.
Cree el controlador para el verbo GET de la ruta /findById/:id/json
que retorna un json dado el id de un foto.
/* GET user by id. */
router.get('/findById/:id/json', function(req, res, next) {
let id = parseInt(req.params.id);
Users.findOne({
where: {
[Op.and]: [
{id: id}
]
}
})
.then(users => {
res.json(users);
})
.catch(error => res.status(400).send(error))
});
Reinicie el servidor para comprobar el funcionamiento del controlador.
http://localhost:3000/users/findById/1/json
Para guardar UN registro de una entidad en una base de datos relacional, implemente el controlador para el verbo POST y el requerimineto al método create del modelo.
Cree el controlador para el verbo POST de la ruta /save
que recibe los datos de un foto en el cuerpo del requerimiento y guarda los datos en la base de datos relacional.
/* POST user. */
router.post('/save', function(req, res, next) {
let {email, username, password} = req.body;
// Encripte la contraseña con SALT
let salt = process.env.SALT
let hash = crypto.createHmac('sha512',salt).update(password).digest("base64");
let passwordHash = salt + "$" + hash
Users.create({
email: email,
username: username,
password: passwordHash,
logins: 0,
last_login: 0
})
.then(users => {
res.json(users);
})
.catch(error => res.status(400).send(error))
});
Reinicie el servidor para comprobar el funcionamiento del controlador.
En postman, realice una petición POST al URL http://localhost:3000/users/save
y envíe los datos en el cuerpo de la petición
{
"email": "user01@gmail.com",
"username": "user01",
"password": "password"
}
Para actualizar UN registro de una entidad en una base de datos relacional, implemente el controlador para el verbo PUT y el requerimineto al método update del modelo.
Cree el controlador para el verbo PUT de la ruta /update
que recibe los datos de una foto en el cuerpo del requerimiento y guarda los datos en la base de datos relacional de acuerdo con el identificador original.
/* PUT user. */
router.put('/update', function(req, res, next) {
let {id, email, username, password} = req.body;
// Encripte la contraseña con SALT
let salt = process.env.SALT
let hash = crypto.createHmac('sha512',salt).update(password).digest("base64");
let passwordHash = salt + "$" + hash
Users.update({
email: email,
username: username,
password: passwordHash,
logins: 0,
last_login: 0
},
{
where: {
id: parseInt(id)
}
})
.then(users => {
res.json(users);
})
.catch(error => res.status(400).send(error))
});
Reinicie el servidor para comprobar el funcionamiento del controlador.
En postman, realice una petición PUT al URL http://localhost:3000/users/update
y envíe los datos en el cuerpo de la petición
{
"id": 2,
"email": "user01@gmail.com",
"username": "user3",
"password": "password"
}
Para eliminar UN registro de una entidad en una base de datos relacional, implemente el controlador para el verbo DELETE y el requerimineto al método destroy del modelo.
Cree el controlador para el verbo DELETE de la ruta /delete/:id
que recibe el id de una foto en el cuerpo del requerimiento y elimina el registro de la base de datos relacional.
/* DELETE user. */
router.delete('/delete/:id', function(req, res, next) {
let id = parseInt(req.params.id);
Users.destroy({
where: {
id: id
}
})
.then(users => {
res.json(users);
})
.catch(error => res.status(400).send(error))
});
Reinicie el servidor para comprobar el funcionamiento del controlador.
En postman, realice una petición DELETE al URL http://localhost:3000/users/delete/2