Creare una fake api rest in pochi minuti con Json-Server

Alle volte come front-end developer ci si ritrova nella situazione di dover lavorare con un'api rest non ancora completamente funzionante o difficilmente raggiungibile dal nostro ambiente di sviluppo che può rallentare o addirittura bloccare lo sviluppo della nostra applicazione.

Una soluzione semplice potrebbe essere quella di creare dei files json statici contenenti i dati necessari, ma scriverli a mano diventa tedioso e difficilmente si riescono a creare tanti elementi differenziati, oltre al fatto che diventa poco simpatico mantenere il tutto nel caso di un cambio di struttura o anche semplicemente del nome di alcune chiavi. Inoltre in questo modo non possiamo inserire, modificare o editare i dati dinamicamente, in pratica mancano 3 azioni su 4 di una classica api rest CRUD (Create, Read, Update, Delete).

Tra le varie soluzioni disponibili per risolvere il problema una delle più semplici e intuitive da usare è sicuramente json-server, costruito sul popolare framework web Express per Nodejs.

Hello World

Per prima cosa dobbiamo installare json-server globalmente sul nostro sistema grazie ad npm:

$ npm install -g json-server

Ora posizioniamoci in una cartella qualsiasi e creiamo un nuovo file, db.json, e inseriamo i dati che vogliamo vederci ritornare dalla nostra api:

{
    "users": [
        {
            "id": 1,
            "name": "Rocket",
            "email": "rocket@guardiansofthegalaxy.com"
        },
        {
            "id": 2,
            "name": "Groot",
            "email": "iam@groot.com"
        }
    ],
    "posts": [
        {
            "id": 1,
            "title": "Hello World!",
            "text": "Hello World",
            "userId": 1
        },
        {
            "id": 2,
            "title": "I am Groot",
            "text": "I am Groot",
            "userId": 1
        }
    ]
}

Siamo pronti per lanciare il nostro server, dalla riga di comando digitiamo:

$ json-server db.json

Il terminale dovrebbe risponderci circa in questo modo:

{^_^} Hi!

Loading database from db.json  
  http://localhost:3000/users
  http://localhost:3000/posts

You can now go to http://localhost:3000/

Enter `s` at any time to create a snapshot of the db  

La nostra API sarà quindi accessibile dall'url http://localhost:3000, dove troveremo una breve descrizione e dei links a tutte le risorse disponibili.

Navigando all'url http://localhost:3000/users per esempio possiamo osservare il server risponderci con i dati inseriti nel file db.json per la chiave users, e fin qui niente di sconvolgente, ma abbiamo anche, di default, accesso a tutte le azioni di un'api CRUD che si rispetti:

GET    /users  
GET    /users/1  
POST   /users  
PUT    /users/1  
PATCH  /users/1  
DELETE /users/1  

Grazie ad un client REST, come per esempio Postman, possiamo eseguire tutte le azioni CRUD che desideriamo e vedremo il file db.json aggiornarsi automaticamente!

Effettuando per esempio una chiamata POST all'url /users con i seguenti parametri:

name: 'Gamora'  
email: 'gamora@guardiansofthegalaxy.com'  

otteremo dal server la risposta in formato JSON contente i dati del nuovo elemento inserito:

{
  "name": "Gamora",
  "email": "gamora@guardiansofthegalaxy.com",
  "id": 3
}

Oltre alle URL base di CRUD troviamo altre funzioni avanzate come:

  • filtri sugli attributi (es. GET /users?name=Groot per ottenere tutti gli utenti con il nome uguale a 'Groot'), o full-text search (es. GET /users?q=galaxy);

  • possibilità di ottenere dati in relazione tra loro (es. GET /users/2/posts per ottenere tutti i posts dello user con id 2);

  • sorting per attributi, slice del numero dei record per la paginazione e altro ancora!

In ogni momento possiamo inoltre salvare in un file a parte lo stato del db attuale premendo s dalla console.

Generazione di dati casuali

Già utilizzando json-server con dei dati statici abbiamo degli evidenti vantaggi ma è con la possibilità di generare dati casuali a partire da un file javascript che ci permette ancora di più di testare le nostre applicazioni con dati quanto più possibile reali.

Per far questo abbiamo bisogno di una libreria che ci aiuti a generare dei dati random, come ad esempio ChanceJS, che include al suo interno un bel numero di diversi tipi di dati generabili, a partire da numeri, stringhe, nomi, email, località, date, etc., nella documentazione li troverete tutti.

Un esempio di generatore di dati è il seguente:

// api-gen.js
var moment = require('moment'),  
Chance = require('chance'),  
chance = new Chance();

module.exports = function() {  
    var data = {
        users: [],
        posts: []
    };
    var i,
    currentUser;

    for (i = 1; i < 51; i++) {

        data.users.push({
            id: i,
            name: chance.name(),
            email: chance.email()
        });
    }

    for (i = 1; i < 101; i++) {

        var date = chance.date({ year: 2015});
        currentUser = chance.pick(data.users);

        data.posts.push({
            id: i,
            title: chance.name(),
            text: chance.email(),
            userId: currentUser.id,
            published: new moment(date).format('DD/MM/YYYY HH:mm:ss')
        });
    }

    return data;
};

Per lanciare il nostro server non dovrete far altro che passare il file come parametro a json-server:

$ json-server api-gen.js

Come vedete si tratta di una semplice funzione che ritorna un oggetto contenente i dati che andranno a popolare la nostra api. Per ogni risorsa poi utilizziamo un semplice ciclo for per generare il numero di records casuali desiderato. E' possibile utilizzare inoltre i dati precedentemente generati (in questo caso gli utenti) per creare relazioni con altre risorse, oppure elaborare ulteriormente quanto generato casualmente da ChanceJS (in questo caso abbiamo formattato le date con MomentJS).

Conclusioni

Abbiamo visto come con davvero pochissimo tempo a dispozione e zero configurazione json-server possa creare per noi un'api rest completamente funzionante.

Ovviamente esistono soluzioni alternative, che permettono un maggior grado di personalizzazione ma sono anche più complesse e richiedono spesso un tempo di configurazione superiore, come ad esempio Dyson o Interfake, che possono rivelarsi più appropriate nel caso di necessità particolari.

Emanuele Ingrosso

Read more posts by this author.

Subscribe to Ingruz's Blog

Get the latest posts delivered right to your inbox.

or subscribe via RSS with Feedly!
comments powered by Disqus