In questo articolo vedremo come gestire un sito basato su un database di tipo flat file con ExpressJS.

Una soluzione di questo tipo prevede che i dati vengano raccolti in un unico file in formato JSON. In tal senso esistono due possibili scenari:

  1. Il file è un normale file JSON e le operazioni su di esso avvengono tramite i metodi di lettura e scrittura del modulo core fs.
  2. Il file è un normale file JavaScript in cui i dati vengono resi accessibili tramite la proprietà module.exports di Node.js.

Poiché il nostro database contiene più di 25000 record, la prima soluzione richiederebbe un accesso intensivo al file system. La seconda invece consentirebbe di effettuare le principali operazioni sfruttando solo la memoria dell'applicazione, risultando così molto più performante.

Il database consiste in un array di oggetti JSON. Di conseguenza tutte le operazioni si ridurranno di fatto alla gestione dei dati presenti in un array JavaScript.

Nella home page vogliamo restituire i primi nove record. Quindi useremo il metodo slice() degli array.

'use strict';

const express = require('express');
const db = require('../db');
const validator = require('validator');
const breadcrumb = require('express-url-breadcrumb');
const router = express.Router();

router.get('/', (req, res, next) => {
    res.render('home', {
        pageTitle: 'Restaurants App',
        restaurants: db.slice(0, 9)
    });
});

module.exports = router;

Quando vogliamo mostrare la pagina di dettaglio di un record, useremo il metodo find().

router.get('/restaurants/:id', breadcrumb(), (req, res, next) => {
    const { id } = req.params;
    if(validator.isNumeric(id)) {
        const restaurant = db.find(r => { return r.restaurant_id === id });
        if(restaurant) {
            res.render('single', {
                pageTitle: restaurant.name,
                restaurant: restaurant,
                isSingle: true
            });
        } else {
            res.sendStatus(404); 
        }
    } else {
        res.sendStatus(404);
    }
}); 

La ricerca di un record, al contrario, prevede l'uso di un loop sull'array di oggetti e delle espressioni regolari per trovare una corrispondenza tra la query inserita nel form di ricerca e il valore di una proprietà di un record.

router.post('/search', (req, res, next) => {
    const { q } = req.body;
    const regex = new RegExp(q, 'gi');
    let restaurants = [];

    for(let i = 0; i < db.length; i++) {
        let restaurant = db[i];
        if(regex.test(restaurant.name)) {
            restaurants.push(restaurant);
        }
    }

    if(restaurants.length > 0) {
        res.render('search-results', {
            pageTitle: 'Search results',
            restaurants: restaurants.slice(0, 9)
        });
    } else {
        res.render('search-results', {
            pageTitle: 'Search results',
            restaurants: false
        });
    }
});

Questo tipo di soluzione è utile quando non avete a disposizione un database sottostante e volete comunque replicare le funzionalità di un sito dinamico.

Demo

Heroku

Codice sorgente

GitHub