API REST

COMUNICACIÓN CLIENTE - SERVIDOR

Ordenador usuario

Hosting de FB

== DAME EL HTML =>

<= TOMA EL HTML ==

== DAME LOS POSTS =>

<= TOMA LOS POSTS ==

Le he dado like a este post =>

<= ok, lo tengo en cuenta ==

== He subido un nuevo post =>

<= ok, lo tengo en cuenta ==

API

Ordenador usuario

Servidor facebook

== DAME EL HTML =>

<= TOMA EL HTML ==

== GET /POSTS =>

<= TOMA LOS POSTS ==

POST /POST/ID/LIKES/ =>

<= ok, lo tengo en cuenta ==

== POST:  /ME/POSTS =>

<= ok, lo tengo en cuenta ==

Hosting de FB

API

users

posts

pages

users/id/messages

users/id/friends

GET ( URL )

var URL = 'https://jsonplaceholder.typicode.com/users'

GET ( URL + '/25' )

POST ( URL, DATA )

PUT ( URL + '/25', DATA )

DELETE ( URL + '/25' )

Resumen

GET ( URL )

var URL = 'https://jsonplaceholder.typicode.com/users'

GET ( URL + '/25' )

POST ( URL, DATA )

PUT ( URL + '/25', DATA )

DELETE ( URL + '/25' )

ESTA BIEN YA DE TEORÍA

MODULO HTTP

CREAR SERVIDOR

var http = require('http');

var server = http.createServer( ( req, res) => {
    console.log('Estoy atento a las llamadas');
});

server.listen(5000, (err) => {
    if (!err){
        console.log('Servidor escuchando en el puerto 5000');
    }
});

CREAR SERVIDOR

var http = require('http');

var server = http.createServer( ( req, res) => {
    console.log('Estoy atento a las llamadas');
});

server.listen(5000, (err) => {
    if (!err){
        console.log('Servidor escuchando en el puerto 5000');
    }
});

PARÁMETROS

REQ Y RES 

== REQUEST => 

Ordenador usuario

Servidor facebook

REQ

REQ

req.url

 

req.method

 

req.headers

/USERS

"GET" || "POST" || "PUT" || "DELETE"

{ } 

RES

<= RESPONSE == 

Ordenador usuario

Servidor facebook

RES.SETHEADER()

RES.WRITE()

RES.END()

EJEMPLO

var http = require('http');

var server = http.createServer(serverFunc)

function serverFunc ( req, res) {
    res.write('Hola mundo');
    res.end();
};

server.listen(5000);

EJEMPLO

var http = require('http');

var server = http.createServer(serverFunc)

function serverFunc ( req, res) {
    res.setHeader('Content-Type', 'application/json');
    res.write(JSON.stringify({ a: 1 }));
    res.end();
};

server.listen(5000);

JUGUETEAMOS POSTMAN 

Mini ejercicio

Crea un servidor que esté escuchando por el puerto 4200.


Cada vez que reciba una petición get a la url /number, nos devuelve un número aleatorio del 1 al 100.

Cada vez que reciba una petición get a la url /randomGroup, nos devuelve un número aleatorio del 1 y el 4.

MODULO EXPRESSJS

npm i express

Creando server

var express = require('express')
var app = express()
 
app.get('/', function (req, res) {
  res.send('Hello World')
})
 
app.listen(3000)

GET:  "http://localhost:3000/ " =>    'Hello world'

Creando server

var express = require('express')
var app = express()
 
app.get('/', function (req, res) {
  res.send('Hello World')
})
 
app.listen(3000)

POST:  "http://localhost:3000/ " =>   ¿?

Creando server

var express = require('express')
var app = express()
 
app.get('/', function (req, res) {
  res.send('Hello World')
})
 
app.listen(3000)

GET:  "http://localhost:3000/users " =>   ¿?

Respuesta json

var express = require('express')
var app = express()
 
var users = [{name : 'a'},{name : 'b'}]

app.get('/users', function (req, res) {
  res.json(users);
})
 
app.listen(3000)

GET:  "http://localhost:3000/users" =>   [ {} , {} ]

GET Y POST

GET

1 RECURSO   =  1 URL 

STANDARD => NOUNS

http://localhost:3000/users

http://localhost:3000/books

http://localhost:3000/books/3

También se suelen nombrar en singular

GET

EN LA PRÁCTICA

app.get('/users', function (req, res) {
  res.json(users);
})

app.get('/users/:id', function (req, res) {

  const userId = req.params.id;

  const user = users.find(u => u.id == userId);

  res.json(user);
});

POST

<form action="//localhost:3000/users" method="post">
    <div>
        <label for="email">Email: </label>
        <input type="text" name="email"></input>
    </div>
<input type="submit"></input>
</form>

EN EL LADO DEL CLIENTE

createUser( user : User) {
  return axios.post(url, user)
  	.then(res => res.data)
}

o

POST

app.post('/users', function (req, res) {
  
    const newUser = req.body; // ¿UNDEFINED?
    
    newUser.id = ();
    
    users.push(newUser);
    
    res.json(newUser);
})

MIENTRAS TANTO EN EL REQ

¿ Y EL CONTENIDO DEL FORMULARIO ?

ANTES DE EXPRESS 4.16.0 - Release date: 2017-09-28

NPM I BODY-PARSER

var express = require('express')
var bodyParser = require('body-parser')

var app = express();

// Middlewares 
app.use(bodyParser.json());

CON EXPRESS 4.16+

NPM I BODY-PARSER

var express = require('express')
/* var bodyParser = require('body-parser') */

var app = express();

// Middlewares 
app.use(express.json());

IMPORTANTE

DELETE Y PUT

DELETE Y PUT

HTTP

CODE ERRORS

  • 418 I'm a teapot
app.post('/users', function (req, res) {
    if (bodyIsEmpty(req.body)){
        res.status(400).send('Contenido del body vacío');
    }
    console.log('Hola');
    const newUser = req.body;
    newUser.id = users.length;
    users.push(newUser);
    res.json(newUser);
})
app.post('/users', function (req, res) {
    if (bodyIsEmpty(req.body)){
        res.status(400).send('Contenido del body vacío');
    }
    console.log('Hola');
    const newUser = req.body;
    newUser.id = users.length;
    users.push(newUser);
    res.json(newUser);
})

ERROR

app.post('/users', function (req, res) {
    if (bodyIsEmpty(req.body)){
        return res.status(400).send('Contenido del body vacío');
    }
    console.log('Hola');
    const newUser = req.body;
    newUser.id = users.length;
    users.push(newUser);
    res.json(newUser);
})

npm i -g nodemon

Oye, Yunior pero ...

¿ Cómo conecto yo mi "api" con un front ? 

Pues como ya hemos hecho con otras apis, mediante axios y si usas servicios mejor que mejor ;)

ejemplo

Cuando tu app arranque tendrás que hacerle un GET a tu server, ¿a dónde?

axios.get('http://localhost:5000/tasks')

ejemplo

Cuando se pulse ese botón, tendrás que mandar a hacer un delete a tu api y luego, si todo ha ido, bien borrarlo de la pantalla

ejemplo

Cuando se pulse ese botón, tendrás que avisar a la api que se ha completado una tarea.
Aquí ya hay varias opciones:

 - Si seguimos el estándar. PATCH /api/todos/20 y en el body el atributo isCompleted : true.

- Otras opciones. Por ejemplo, crear un endpoint concreto para esta "acción" GET/api/completarTODO/20, o podemos mandar la tarea con su completed a true por un PUT

ejemplo

Al introducir una tarea por el front :

 

- Hacer un post con axios a la api

- O bien si estuviese envuelto en un formulario especificar en el form que se hace un POST y que el action es a tu url.

EJERCICIOS

Hemos visto que ..

Oye, hemos visto una app muy sencilla por ahí que se llama todolist y queremos presentar un MVP de un producto parecido para dentro de un par de horas a un inversor que viene a reunirse con nosotros.
Me han dicho que eres fullstack así que seguro que lo haces rápido :)

Haz primero la API, e incluso prueba que funcionen todos los endpoints desde POSTMAN. Si puedes luego conectarlo con tu frontend de un todolist anterior pues guay. ! 

Hemos visto que ..

Coge este gif como referencia para hacer una app (web) que permita añadir, borrar y completar items de una lista y que esta lista no se pierda y se quede guardada en el backend. 

EJERCICIOS

Primera API

Queremos desarrollar una api restful con node para un proyecto copia de twitter. Aunque de momento, será solo una primera versión con usuarios y tweets como si fuese un blog personal.

USUARIO

username* : string<uniq>

name? : string

email* : string

tweets : Tweet []

 

TWEET

id* : string<uniq>

text* : string

owner* : string<ID>

createdAt : timestamp

Primera API

  • Deberán estar implementadas las funcionalidades de:
    • Crear un nuevo usuario. En la "variable de usuarios" De momento no hay nada de logins
    • Borrar un usuario 
    • Editar el email de un usuario o el nombre (PATCH)
    • Subir un tweet nuevo por parte de un usuario
    • Ir a buscar un tweet en concreto por su id
    • Borrar un tweet por su id

 

 

OJO ! CONTROLA QUE LA API NO SE PUEDA QUEDAR PILLADA EN NINGÚN MOMENTO, controla campos vacíos, request inválidas, etc etc y devuelve el error en la respuesta y el código correcto para dicho caso

EJERCICIOS

El producto evoluciona

Oye, resulta que anoche se fue la luz en la oficina, y al resetearlo parece que habíamos perdido toda la información !!


No queremos que esto vuelva a pasar, hemos perdido a muchos usuarios por el camino, dale persistencia a los datos mediante ficheros :)

Modulo fs   =>   const fs = require('fs')
Métodos fs.writeFileSync  y fs.readFileSync