Crear una API simple con MEAN

Pequeña API con el stack MEAN

<Hola>, he creado una pequeña API para hacer en un futuro un contador de visitas obteniendo la ip del visitante, la hora que entro, el sistema operativo y la url. Para eso vamos a utilizar Nodejs para la aplicación, esta aplicación utiliza las siguientes tecnologías.

mean app
mean app
  • Mongo( Base de datos no SQL )
  • ExpressJs( Framework basado en Nodejs nos permite administrar las rutas para crear la API )
  • Angular2( Framework para el Frontend de nuestra aplicación  )
  • Nodejs ( Servidor orientado a eventos ).

A este conjunto de tecnología se le otorga el nombre de MEAN.

Inicio de la API

Iniciamos con el proyecto, comenzamos con la estructura de archivos de nuestra aplicación.

estructura de mean
estructura de mean

He creado esta estructura para seguir un orden en los archivos, primero creamos un archivo dentro de la carpeta models con el nombre visita.js, aquí irá el código para el manejo de las colecciones que están la base de datos mongodb.

 

[code language=”javascript”]
//importamos nuestras librerías
//para el manejo de los esquemas
var mongoose = require(‘mongoose’),
Schema = mongoose.Schema;

//Definimos nuestro esquema
var Visitas = new Schema({
ip: { type: String },
fecha: { type: Date, default: Date.now },
so: { type: String },
url: { type: String }
});

//construimos un modelo para crear las colecciones
module.exports = mongoose.model(‘Visitas’, Visitas);
[/code]

Este modelo es importante ya que nos servirá para crear, editar, eliminar y buscar de manera sencilla y práctica. Ahora crearemos en la carpeta controllers un archivo visita.js que realizará toda las operaciones para el manejo del modelo visita.

[code language=”javascript”]
//importamos nuestras librerías
var mongoose = require(‘mongoose’);
var VisitasModel = mongoose.model(‘Visitas’);
var parser = require(‘ua-parser-js’);

//libreria para obtener la ip publica
const publicIp = require(‘public-ip’);

var ip_publica = null;

// peticion GET
exports.findAllVisita = function(req, res) {

console.log(‘GET /visita’);

//busca todos nuestro registro que hay en vistas
VisitasModel.find(function(err, contador) {
if(err) res.send(500, err.message);

res.status(200).jsonp(contador);
});

};

// peticion POST
exports.addVisita = function(req, res) {
console.log(‘POST’);
console.log(req.body);

//obtenemos los datos del navegador
var navegador = parser(req.headers[‘user-agent’]);
var tiempo = new Date();

publicIp.v4().then(ip =&amp;gt; {

//var fullUrl = req.protocol + ‘://’ + req.get(‘host’) + req.originalUrl;

if ( typeof req.body.url == "undefined" ) {
fullUrl = "-";
}else{
fullUrl = req.body.url;
}

//creamos el objeto del modelo vista
var contador = new VisitasModel({
ip: ip,
fecha: tiempo,
so: navegador.os.name,
url: fullUrl
});

//guardamos los datos en la tabla
contador.save(function(err, contador) {
if(err) return res.status(500).send( err.message );
res.status(200).jsonp(contador);
});
});

};
[/code]

En las primeras líneas( línea del 1 al 4 ) declaramos las librerías que necesitamos, en la línea 3 está la llamada al modelo visitas que vamos a procesar, en la línea 7 hacemos una llamada a una librería que nos va a retornar la ip publica del cliente y así tener un contador de las visitas que tenga un sitio web, de las líneas 12 al 23 es donde tenemos la búsqueda de registros que hay en la base de datos, usted verá algo así.

api get
api get

De la línea 26 hasta la 59 es el código que nos ayuda a insertar un registro en la tabla visitas, como ven en el código obtenemos los datos del navegador para así obtener el sistema operativo del usuario, en la línea 34 obtenemos la ip de usuario que está realizando la petición POST, en la línea 45 creamos el objeto que vamos a utilizar para insertar un registro nuevo que es la línea 53 en donde se hace el proceso.

Ahora crearemos un archivo app.js donde administramos las rutas e implementaremos el socket.io para cuando el cliente se conecte a un sitio web se inserte un registro de visita. El archivo contará con el siguiente código.

[code language=”javascript”]
//declarando todas las librerias
var express = require("express"),
app = express(),
bodyParser = require("body-parser"),
methodOverride = require("method-override"),
querystring = require(‘querystring’)
mongoose = require(‘mongoose’),
server = app.listen(3000),
http = require(‘http’),
url = require(‘url’),
io = require(‘socket.io’).listen(server);

var url_cliente = "";

//configuracion de la aplicacion
app.use(bodyParser.urlencoded({ extended: false }));
app.use(bodyParser.json());
app.use(methodOverride());

//importar modelos y controladores
var models = require(‘./app/models/visita’)(app, mongoose);
var visitasController = require(‘./app/controllers/visita’);

//declarando rutas de express
var router = express.Router();

//peticion inicial de la aplicacion GET /
router.get(‘/’, function(req, res) {
res.send("¡Ok!");
});

app.use(router);

//es necesario declar esta ruta para que la aplicacion encuentre
//el archivo socket.io/socket.io.js
app.use(express.static("public"));

var rutasVisitas = express.Router();

// api request GET y POST
rutasVisitas.route(‘/visita’)
.get(visitasController.findAllVisita)
.post(visitasController.addVisita);

//agregar una ruta api a las peticiones de api/visita
app.use(‘/api’, rutasVisitas);

//conexion a la base de datos
mongoose.connect(‘mongodb://192.168.59.103:27017/test’, function(err, res) {
if (err) {
console.log(‘ERROR: connecting to Database. ‘ + err);
}
});

//comienza el servicio Node
server.listen(3000, function() {
console.log("Node server running on http://localhost:3000");
});

//empieza el socket io
io.on(‘connection’, function(socket) {

url_cliente = socket.handshake.query.name;

sendVisita(function(data) {
console.log(‘Send locations to client ‘ + socket.id);
});

socket.emit(‘conexion’, { bandera: ‘true’ });

});

//funciones adicionales
//envia un post a la api
function sendVisita(callback) {
var api_host = ‘localhost’;
var post_data = querystring.stringify({
‘url’: url_cliente
});
var options = {
hostname: api_host,
port: 3000,
path: ‘/api/visita’,
method: ‘POST’,
headers: {
‘Content-Type’: ‘application/x-www-form-urlencoded’,
‘Content-Length’: Buffer.byteLength(post_data)
}
};

var req = http.request(options, function(res) {
//console.log(‘—————————————–‘);
//console.log(‘STATUS: ‘ + res.statusCode);
//console.log(‘HEADERS: ‘ + JSON.stringify(res.headers));
var output = ”;

res.setEncoding(‘utf8’);
res.on(‘data’, function(chunk) {
output += chunk;
});

res.on(‘end’, function() {
var obj = JSON.parse(output);
if (callback != undefined) {
callback(obj);
}
});
});

req.write(post_data);

req.on(‘error’, function(e) {
callback({
url: "/"
});
console.log(‘problem with request: ‘ + e.message);
});

req.end();
}
[/code]

De la línea 1 a la 11 se llaman a las librerías para el funcionamiento de la aplicación, de la línea 21 a 22 es donde se manda a llamar el modelo y el controlador de visitas, esto nos permite administrar las rutas, en la línea 28 se empieza a declarar las rutas que utilizaremos para informar que la aplicación está funcionando creamos un mensaje al inicio de la aplicación que muestra un “Ok” si todo está funcionando.

La línea 36 es importante ya que nos permite el uso de la libreria estatica socket.io/socket.io.js que permite las conexiones en tiempo real del navegador del cliente con nuestro servicio. De la línea 38 a 46 se declaran las distintas rutas con los diferentes métodos http para distinguir cuando se inserta(POST) y cuando muestra los registros(GET).

Del código 50 al 53 realizamos la conexión al servidor Mongodb, la ejecución del socket se realiza en las líneas 62 a 72 el cual ejecuta la función sendVisita que hace una petición a nuestra API ( POST api/visita ) para insertar un registro nuevo del visitante que está en la página web.

Resultados de la API.

conexion de api
conexión de api

Cada vez que ingresamos a una página con el siguiente código.

codigo cliente web
código cliente web

[code language=”html”]
<script src="http://localhost:3000/socket.io/socket.io.js"></script>
<script>
var params = {query: ‘name=’ + document.URL};
var socket = io.connect(‘http://localhost:3000’, params );

socket.on(‘conexion’, function (data) {
console.log("this", data);
});
</script>
[/code]

Se inserta un registro nuevo.

registro nuevo en mongodb
registro nuevo en mongodb

Con esto finalizamos nuestra pequeña API, ustedes pueden clonar el proyecto que está en github https://github.com/BenjaminGuV/api-express-mongodb

Documentación.

</Saludos>

Deja un comentario