JS, Node.js, Frontend, Backend, Firebase, Express, Patrones, HTML5_APIs, Asincronía, Websockets, Testing
Hello World
const express = require('express');
const app = express();
app.get('/', (req, res) => {
res.send('Hello World!');
});
app.listen(8080, () => {
console.log('Example app listening on port 8080!');
});
Api sencilla
// @see: https://strongloop.com/strongblog/compare-express-restify-hapi-loopback/
const express = require('express');
const Item = require('models').Item;
const app = express();
const itemRoute = express.Router();
itemRoute.param('itemId', (req, res, next, id) => {
Item.findById(req.params.itemId, (err, item) => {
req.item = item;
next();
});
});
// Create new Items
itemRoute.post('/', ({body}, res, next) => {
const item = new Item(body);
item.save((err, item) => {
res.json(item);
});
});
itemRoute.route('/:itemId')
// Get Item by Id
.get(({item}, res, next) => {
res.json(item);
})
// Update an Item with a given Id
.put(({item, body}, res, next) => {
item.set(body);
item.save((err, item) => {
res.json(item);
});
})
// Delete and Item by Id
.delete(({item}, res, next) => {
item.remove(err => {
res.json({});
});
});
app.use('/api/items', itemRoute);
app.listen(8080);
Claves
- Es una capa de configuración por encima de Express
- Desarrollado por Paypal
- Soporta Internalización
- Seguridad Out-of-the-box
- Pensado para gran escala y proyectos tipo enterprise
- Propensión a la configuración
- Pensado para ser escalable
- Incluye dependencias con Dust, LESS, Grunt, Passportjs y Yeoman
Modulos
- Lusca Application security for express apps.
- Kappa A hierarchical npm-registry proxy
- Makara Internationalization support for Kraken with Dust Templating
- Adaro Templating using DustJS
Hello World
const express = require('express');
const kraken = require('kraken-js');
const app = express();
app.use(kraken());
app.listen(8080);
Recursos
- Web Oficial
- Github
- krakenjs | Getting started
- krakenjs | examples
- krakenjs | news
- La gran contribución de PayPal a Node.js: la suite Kraken
- Kraken js at paypal
- From Java to Node - the PayPal story
As Ted explains, “As a newcomer to LoopBack, one of your first challenges will be figuring out what to call the technology you’re using. LoopBack was a standalone entity owned by a company called StrongLoop (which was also the name of its paid service offering), until the company was acquired by IBM® in 2015. Since that time, the LoopBack team released a 3.0 version, and starting with this version it’s consolidating the terms and names under the IBM banner with IBM API Connect™.” StrongLoop
Claves
- StrongLoop empezó en 2013 ofreciendo una version enterprise de Nodejs (Open Source) llamada Loopback
- En 2015 IBM adquiere la compañia
- Tiene una curva de aprendizaje muy elevada
- Basado en Express
- Usa una filosofía de convención sobre configuración
- Permite desarrollar API Rest muy rapidamente
- Documentación muy extensa
- Soporta RPC
Arquitectura
Api sencilla
// @see: https://strongloop.com/strongblog/compare-express-restify-hapi-loopback/
var loopback = require('loopback');
var app = module.exports = loopback();
var Item = loopback.createModel(
'Item',
{
description: 'string',
completed: 'boolean'
}
);
app.model(Item);
app.use('/api', loopback.rest());
app.listen(8080);
// API EXPLORER!
app.start = function() {
// start the web server
return app.listen(function() {
app.emit('started');
var baseUrl = app.get('url').replace(/\/$/, '');
console.log('Web server listening at: %s', baseUrl);
if (app.get('loopback-component-explorer')) {
var explorerPath = app.get('loopback-component-explorer').mountPath;
console.log('Browse your REST API at %s%s', baseUrl, explorerPath);
}
});
};
POST /Items
GET /Items
PUT /Items
PUT /Items/{id}
HEAD /Items/{id}
GET /Items/{id}
DELETE /Items/{id}
GET /Items/{id}/exists
GET /Items/count
GET /Items/findOne
POST /Items/update
Recursos
- Web Oficial
- Loopback | Getting started
- Loopback | Examples
- Loopback | Docs
- Loopback | Resources
- Loopback | Contributing
- The busy JavaScript developer's guide to LoopBack
- Getting Started with Node.js and LoopBack
Claves
- El core de Hapi.js es mucho más completo que el de Express
- No se usa middelware, se utilizan plugins
- Creado por Walmart Labs
- Originalmente utilizaba Express internamente, pero ya no
Hello World
const Hapi = require('hapi');
// Create a server with a host and port
const server = Hapi.server({
host: 'localhost',
port: 8080
});
// Add the route
server.route({
method: 'GET',
path: '/hello',
handler: function (request, h) {
return 'Hello World!';
}
});
// Start the server
async function start () {
try {
await server.start();
}
catch (err) {
console.log(err);
process.exit(1);
}
console.log('Server running at:', server.info.uri);
};
start();
Api sencilla
// @see: https://strongloop.com/strongblog/compare-express-restify-hapi-loopback/
const Hapi = require('hapi');
const Item = require('models').Item;
const server = Hapi.createServer('0.0.0.0', 8080);
server.ext('onPreHandler', (req, next) => {
if (req.params.itemId) {
Item.findById(req.params.itemId, (err, item) => {
req.item = item;
next();
});
}
else {
next();
}
});
server.route([
{
path: '/api/items/{itemId}',
method: 'GET',
config: {
handler({item}, reply) {
reply(item);
}
}
},
{
path: '/api/items/{itemId}',
method: 'PUT',
config: {
handler({item, body}, reply) {
item.set(body);
item.save((err, item) => {
reply(item).code(204);
});
}
}
},
{
path: '/api/items',
method: 'POST',
config: {
handler({body}, reply) {
const item = new Item(body);
item.save((err, item) => {
reply(item).code(201);
});
}
}
},
{
path: '/api/items/{itemId}',
method: 'DELETE',
config: {
handler({item}, reply) {
item.remove(err => {
reply({}).code(204);
});
}
}
}
]);
server.start();
Recursos
- Web Oficial
- Github
- @hapijs en Twitter
- Hapi.js | Latest Updates
- Hapi.js | Getting started
- Hapi.js | API
- Hapi.js | Community
- Hapi.js | Plugins
- Hapi.js | Resources
- Cómo empezar una API RESTful con hapi.js
- Create a Server in Hapi JS
- Introduction to Hapi.js
- How to set-up a powerful API with Nodejs, GraphQL, MongoDB, Hapi, and Swagger
- Creating RESTful API with Node.js: Hapi vs. Express
Build practical, production-ready Node.js apps in a matter of weeks, not months. Sails is the most popular MVC framework for Node.js, designed to emulate the familiar MVC pattern of frameworks like Ruby on Rails, but with support for the requirements of modern apps: data-driven APIs with a scalable, service-oriented architecture. Sailsjs
Claves
- Basado y dependiente de Express
- Esta pensado para aplicaciones de gran tamaño
- Tiene una arquitectura MVC configurada de base
- Es necesario conocer Express en profundidad
- Es una abstracción muy grande sobre express
- Cuenta con una herramienta CLI para facilitar el desarrollo
- Cuenta con un ORM propio que simplifica el trabajo con Bases de datos
Recursos
Expressive HTTP middleware framework for node.js to make web applications and APIs more enjoyable to write. Koa's middleware stack flows in a stack-like manner, allowing you to perform actions downstream then filter and manipulate the response upstream.
Only methods that are common to nearly all HTTP servers are integrated directly into Koa's small ~570 SLOC codebase. This includes things like content negotiation, normalization of node inconsistencies, redirection, and a few others.
Koa is not bundled with any middleware. Koa
Claves
- No utiliza Express para funcionar
- Esta pensado para remplazar la libreria
http
yhttps
de Nodejs - Utiliza dos tipos de middleware
async function
ycommon function
Context
sustituye al clasicoRequest
yResponse
, pero se mantienenext
como en Express- Sin middleware ni routas
- Sin
callback hell
, usandotry/catch
- Sistema muy modular y extensible por librerías
Hello World
const Koa = require('koa');
const app = new Koa();
app.use(async function(ctx) {
ctx.body = 'Hello World';
});
app.listen(3000);
Recursos
- Web Oficial
- Koa | Koa for Express Users
- Koa | Usage Guide
- Koa | Error Handling
- Koa | API Docs
- Koa | FAQ
Claves
- No depende de Express
- Toma una gestión de rutas muy similar a Express
- Especializado para la gestión de API Rest
- No incluye la gestión de plantillas y renderizado de express
Hello World
const restify = require('restify');
const server = restify.createServer();
server.get('/hello', (req, res, cb) => {
res.send("Hello World!");
return cb();
});
server.listen(8080, () => {
console.log('%s listening at %s', server.name, server.url);
});
Api sencilla
// @see: https://strongloop.com/strongblog/compare-express-restify-hapi-loopback/
const restify = require('restify');
const Item = require('models').Item;
const app = restify.createServer();
app.use((req, res, next) => {
if (req.params.itemId) {
Item.findById(req.params.itemId, (err, item) => {
req.item = item;
next();
});
}
else {
next();
}
});
app.get('/api/items/:itemId', ({item}, res, next) => {
res.send(200, item);
});
app.put('/api/items/:itemId', ({item, body}, res, next) => {
item.set(body);
item.save((err, item) => {
res.send(204, item);
});
});
app.post('/api/items', ({body}, res, next) => {
const item = new Item(body);
item.save((err, item) => {
res.send(201, item);
});
});
app.delete('/api/items/:itemId', ({item}, res, next) => {
item.remove(err => {
res.send(204, {});
});
});
app.listen(8080);
Recursos
Documentación
Presentaciones
- Pillars.js framework de desarrollo web para Node.js (2015)
- Pillarjs & GoblinDB, Prototype like a Boss!
Vídeos
Proyectos
Recursos
- State of JS | Back-end Frameworks – Worldwide Usage
- Node.js performance vs Hapi, Express, Restify, Koa & More
- NPM Trends | express, koa, pillars,kraken, loopback, hapi, sails
- NPM Trends | koa, kraken, loopback, hapi, sails
Frameworks
- Feathers Microservice framework built in the spirit of Express.
- Meteor An ultra-simple, database-everywhere, data-on-the-wire, pure-Javascript web framework.
- ThinkJS Framework with ES2015+ support, WebSockets, REST API.
- ActionHero Framework for making reusable & scalable APIs for TCP sockets, WebSockets, and HTTP clients.
- MERN Easily build production-ready universal apps with MongoDB, Express, React, and webpack.
- Next.js Minimalistic framework for server-rendered universal JavaScript web apps.
- Nuxt.js Minimalistic framework for server-rendered Vue.js apps.
- seneca Toolkit for writing microservices.
- AdonisJs A true MVC framework for Node.js built on solid foundations of Dependency Injection and IoC container.
- Hemera Write reliable and fault-tolerant microservices with NATS.
- Micro Minimalistic microservice framework with an async approach.
- Moleculer Fast & powerful microservices framework.
- Fastify Fast and low overhead web framework.
- Nest Angular-inspired framework for building efficient and scalable server-side apps.
- Zeronode Minimal building block for reliable and fault-tolerant microservices.
- TypeGraphQL Modern framework for creating GraphQL APIs with TypeScript, using classes and decorators.
- Wintersmith Flexible, minimalistic, multi-platform static site generator.
- Assemble Static site generator for Node.js, Grunt.js, and Yeoman.
- DocPad Static site generator with dynamic abilities and huge plugin ecosystem.
- Phenomic Modern static website generator based on the React and Webpack ecosystem.
- docsify Markdown documentation site generator with no statically built HTML files.
- KeystoneJS CMS and web application platform built on Express and MongoDB.
- ApostropheCMS Content management system with an emphasis on intuitive front end content editing and administration built on Express and MongoDB.
- Strapi Content Management Framework (headless-CMS) to build powerful APIs.
- Tipe Developer-first content management system with GraphQL and REST API from a schema file.
- nodeBB Forum platform for the modern web.
1 - Migra la aplicación de MovieFire para hacer una APIRest con Nodejs
Claves:
- Puedes usar librerías como
request
,morgan
,helmet
,firebase
... - Puedes dejar un front listo en
/public
y habilitar la ruta/
para dar soporte - Manten una buena estructura separando rutas y modelos, puedes usar
async/await
para simplificar el trabajo - Recuerda normalizar la estructura de datos que nos devuelve la API de OMBD
⚠️ reutilizaremos este ejercicio en el futuro con otras bases de datos, asi que intentan aislar y abstraer la conexión a la base de datos ;-)
Rutas:
[GET] /api/movies
retorna un JSON con todas las películas, array de objetos[{id, name, title...},{}]
[GET] /api/movies/:id
retorna un JSON con los detalles de una película en concreto, objeto{}
[POST] /api/movies
Crea una pelicula y retorna un status200
. Payload{name: ""}
[PUT] /api/movies
Actualiza el nombre de una película y retorna un status200
. Payload{id: "", name: ""}
[DELETE] /api/movies
Borra una película y retorna un status200
. Payload{id: ""}