Probabil că niciun dezvoltator web nu este străin APOI REST și provocările pe care arhitectura o eficientă și eficientă API soluție aduce.

Aceste provocări includ:

  • Viteza (timpii de răspuns API)
  • Documentație (documente clare concise, care descriu API-ul)
  • Arhitectură și durabilitate (bază de cod menținută și extensibilă)

În acest tutorial vom aborda toate cele de mai sus folosind o combinație de Node.js, MongoDB, Fastify și Făli.

Codul sursă pentru proiect este disponibil pe GitHub.

Înainte de a începe …

Ar trebui să ai niște începători / intermediari Cunoștințe JavaScript, am auzit de Node.js și MongoDB, și știu ce APOI REST sunteți.

Mai jos sunt câteva linkuri pentru a vă actualiza:

Tehnologia pe care o vom folosi:

Este o idee bună să deschideți paginile de mai sus în file noi, pentru o referință ușoară.

Va trebui să aveți următoarele instalate:

Veți avea nevoie și de un IDE și a Terminal, eu folosesc iTerm2 pentru Mac și Hiper pentru Windows.

Să începem!

Cum sa construiti API uri REST rapide cu Nodejs MongoDB Fastify

Inițializați un nou proiect deschizând fișierul Terminal, executând fiecare dintre următoarele linii de cod:

mkdir fastify-api
cd fastify-api
mkdir src
cd src
touch index.js
npm init

În codul de mai sus, am creat două directoare noi, am navigat în ele, am creat un index.js fișier și a parafat proiectul nostru prin npm.

Vi se va solicita să introduceți mai multe valori la inițializarea unui nou proiect, pe care le puteți lăsa necompletate și actualizate într-o etapă ulterioară.

Odată finalizat, a pachet.json fișierul este generat în src director. În acest fișier puteți modifica valorile introduse la inițializarea proiectului.

Apoi instalăm toate dependențe că vom avea nevoie de:

npm i nodemon mongoose fastify fastify-swagger boom

Mai jos este o scurtă descriere a ceea ce face fiecare pachet, citat de pe site-urile web respective:

nodemon

nodemon este un instrument care ajută la dezvoltarea aplicațiilor bazate pe node.js prin repornirea automată a aplicației nod atunci când sunt detectate modificări de fișiere în director.

nodemon nu necesită orice modificări suplimentare la codul sau metoda de dezvoltare. nodemon este un învelitor de înlocuire pentru node, a folosi nodemon înlocuiți cuvântul node pe linia de comandă atunci când executați scriptul.

A înscena nodemon, trebuie să adăugăm următoarea linie de cod la package.json fișier, în obiectul scripturi:

“start”: “./node_modules/nodemon/bin/nodemon.js ./src/index.js”,

Al nostru package.json fișierul ar trebui să arate acum după cum urmează:

{
  "name": "fastify-api",
  "version": "1.0.0",
  "description": "A blazing fast REST APIs with Node.js, MongoDB, Fastify and Swagger.",
  "main": "index.js",
  "scripts": {
  "start": "./node_modules/nodemon/bin/nodemon.js ./src/index.js",
  "test": "echo "Error: no test specified" && exit 1"
},
  "author": "Siegfried Grimbeek <siegfried.grimbeek@gmail.com> (www.siegfriedgrimbeek.co.za)",
  "license": "ISC",
  "dependencies": {
  "boom": "^7.2.2",
  "fastify": "^1.13.0",
  "fastify-swagger": "^0.15.3",
  "mongoose": "^5.3.14",
  "nodemon": "^1.18.7"
  }
}

mangustă

Mongoose oferă o soluție simplă, bazată pe schemă, pentru a vă modela datele aplicației. Include turnarea tipului încorporat, validarea, crearea de interogări, cârlige logice de afaceri și multe altele, scoase din cutie.

fastify

Fastify este un cadru web extrem de concentrat pe furnizarea celei mai bune experiențe pentru dezvoltatori, cu cea mai redusă cheltuieli și o arhitectură de plugin puternică. Este inspirat de Hapi și Express și, din câte știm, este unul dintre cele mai rapide cadre web din oraș.

fastify-swagger

Făli generator de documentație pentru Fastify. Acesta folosește schemele pe care le declarați în rutele dvs. pentru a genera un document conform cu fanfara.

boom

boom oferă un set de utilități pentru returnarea erorilor HTTP.

Configurați serverul și creați primul traseu!

1611099367 158 Cum sa construiti API uri REST rapide cu Nodejs MongoDB Fastify

Adăugați următorul cod la index.js fişier:

// Require the framework and instantiate it
const fastify = require('fastify')({
  logger: true
})

// Declare a route
fastify.get('/', async (request, reply) => {
  return { hello: 'world' }
})

// Run the server!
const start = async () => {
  try {
    await fastify.listen(3000)
    fastify.log.info(`server listening on ${fastify.server.address().port}`)
  } catch (err) {
    fastify.log.error(err)
    process.exit(1)
  }
}
start()

Avem nevoie de Fastify , declarați primul nostru traseu și inițializați serverul pe port 3000, codul este destul de explicativ, dar luați notă de obiectul opțiunilor trecute la inițializare Fastify:

// Require the fastify framework and instantiate it
const fastify = require('fastify')({
  logger: true
})

Codul de mai sus activează Fastify’s logger încorporat care este dezactivat în mod implicit.

Acum puteți rula următorul cod în src din directorul dvs. Terminal:

npm start

Acum, când navigați la http: // localhost: 3000 / ar trebui să vezi {hello:world} obiect returnat.

Vom reveni la index.js fișier, dar deocamdată să trecem la configurarea bazei noastre de date.

Porniți MongoDB și creați modelul!

1611099367 531 Cum sa construiti API uri REST rapide cu Nodejs MongoDB Fastify

O singura data MongoDB a fost instalat cu succes, puteți deschide o nouă fereastră de terminal și porni un MongoDB instanță executând următoarele:

mongod

Cu MongoDB, nu este nevoie să creăm o bază de date. Putem specifica doar un nume în configurare și imediat ce stocăm date, MongoDB va crea această bază de date pentru noi.

Adăugați următoarele la index.js fişier:

...

// Require external modules
const mongoose = require('mongoose')

// Connect to DB
mongoose.connect(‘mongodb://localhost/mycargarage’)
 .then(() => console.log(‘MongoDB connected…’))
 .catch(err => console.log(err))
 
...

În codul de mai sus avem nevoie Mangustă și conectați-vă la MongoDB Bază de date. Baza de date se numește mycargarage și dacă totul a mers bine, acum veți vedea MongoDB connected... în terminalul tău.

Observați că nu a trebuit să reporniți aplicația, datorită Nodemon pachet pe care l-am adăugat mai devreme.

Acum că baza noastră de date este în funcțiune, putem crea primul nostru model. Creați un folder nou în src director numit models, și în cadrul acestuia creați un nou fișier numit Car.js și adăugați următorul cod:

// External Dependancies
const mongoose = require('mongoose')

const carSchema = new mongoose.Schema({
  title: String,
  brand: String,
  price: String,
  age: Number,
  services: {
    type: Map,
    of: String
  }
})

module.exports = mongoose.model('Car', carSchema)

Codul de mai sus ne declară carSchema care conține toate informațiile legate de mașinile noastre. În afară de cele două tipuri evidente de date: String și Number. De asemenea, folosim un Map ceea ce este relativ nou pentru Mangustă și poți citi mai multe despre asta aici. Apoi exportăm produsele noastre carSchema pentru a fi folosit în aplicația noastră.

Am putea continua cu configurarea rutelor, controlerelor și configurării noastre în index.js fișier, dar o parte din acest tutorial demonstrează o bază de cod durabilă. Prin urmare, fiecare componentă va avea propriul folder.

Creați controlerul mașinii

Pentru a începe cu crearea controlerelor, creăm un folder în src director numit controllers, iar în dosar, creăm un carController.js fişier:

// External Dependancies
const boom = require('boom')

// Get Data Models
const Car = require('../models/Car')

// Get all cars
exports.getCars = async (req, reply) => {
  try {
    const cars = await Car.find()
    return cars
  } catch (err) {
    throw boom.boomify(err)
  }
}

// Get single car by ID
exports.getSingleCar = async (req, reply) => {
  try {
    const id = req.params.id
    const car = await Car.findById(id)
    return car
  } catch (err) {
    throw boom.boomify(err)
  }
}

// Add a new car
exports.addCar = async (req, reply) => {
  try {
    const car = new Car(req.body)
    return car.save()
  } catch (err) {
    throw boom.boomify(err)
  }
}

// Update an existing car
exports.updateCar = async (req, reply) => {
  try {
    const id = req.params.id
    const car = req.body
    const { ...updateData } = car
    const update = await Car.findByIdAndUpdate(id, updateData, { new: true })
    return update
  } catch (err) {
    throw boom.boomify(err)
  }
}

// Delete a car
exports.deleteCar = async (req, reply) => {
  try {
    const id = req.params.id
    const car = await Car.findByIdAndRemove(id)
    return car
  } catch (err) {
    throw boom.boomify(err)
  }
}

Cele de mai sus pot părea puțin de luat în considerare, dar sunt de fapt foarte simple.

  • Cerem boom pentru a rezolva erorile noastre: boom.boomify(err).
  • Exportăm fiecare dintre funcțiile noastre pe care le vom folosi în ruta noastră.
  • Fiecare funcție este un asincron funcție care poate conține un asteapta expresie care întrerupe executarea funcția asincronă și așteaptă rezoluția promisiunii adoptate și apoi reia funcția asincronă execută și returnează valoarea rezolvată. Aflați mai multe aici.
  • Fiecare funcție este împachetată într-o declarație try / catch. Aflați mai multe aici.
  • Fiecare funcție are doi parametri: req (cererea) și reply (raspunsul). În tutorialul nostru folosim doar parametrul de solicitare. Îl vom folosi pentru a accesa corpul cererii și parametrii cererii, permițându-ne să procesăm datele. Aflați mai multe aici.
  • Luați notă de codul de pe linia 31:
    const car = new Car({ …req.body })
    Aceasta face uz de JavaScript operator de răspândire. Aflați mai multe aici.
  • Luați notă de codul de pe linia 42:
    const { …updateData } = car
    Aceasta face uz de JavaScript destructurarea împreună cu operatorul de împrăștiere. Aflați mai multe aici.

În afară de asta, facem uz de unele standarde Mangustă caracteristici utilizate pentru manipularea bazei noastre de date.

Probabil că ardeți pentru a vă lansa API-ul și pentru a face o verificare a sănătății, dar înainte de a face acest lucru, trebuie doar să conectăm controlor la rute și apoi conectați în cele din urmă rute la aplicație.

Creați și importați rutele

Încă o dată, putem începe prin crearea unui folder în directorul rădăcină al proiectului nostru, dar de această dată, acesta este numit routes. În dosar, creăm un index.js fișier cu următorul cod:

// Import our Controllers
const carController = require('../controllers/carController')

const routes = [
  {
    method: 'GET',
    url: '/api/cars',
    handler: carController.getCars
  },
  {
    method: 'GET',
    url: '/api/cars/:id',
    handler: carController.getSingleCar
  },
  {
    method: 'POST',
    url: '/api/cars',
    handler: carController.addCar,
    schema: documentation.addCarSchema
  },
  {
    method: 'PUT',
    url: '/api/cars/:id',
    handler: carController.updateCar
  },
  {
    method: 'DELETE',
    url: '/api/cars/:id',
    handler: carController.deleteCar
  }
]

module.exports = routes

Aici avem nevoie de a noastră controlor și atribuirea fiecărei funcții pe care le-am creat în controlerul nostru rutelor noastre.

După cum puteți vedea, fiecare traseu constă dintr-o metodă, o adresă URL și un handler, care instruiește aplicația cu privire la funcția de utilizat atunci când este accesată una dintre rute.

:id urmărirea unora dintre rute este o modalitate obișnuită de a transmite parametrii către rute, iar acest lucru ne va permite să accesăm id după cum urmează:

http://127.0.0.1:3000/api/cars/5bfe30b46fe410e1cfff2323

Punând totul împreună și testând API-ul nostru

Acum că avem cele mai multe componente construite, trebuie doar să le conectăm pe toate pentru a începe să difuzăm date prin intermediul nostru API. În primul rând, trebuie să importăm rute pe care le-am creat prin adăugarea următoarei linii de cod la principalul nostru index.js fişier:

const routes = require(‘./routes’)

Apoi, trebuie să facem o buclă peste matricea noastră de rute pentru a le inițializa Fastify. Putem face acest lucru cu următorul cod, care trebuie, de asemenea, să fie adăugat la main index.js fişier:

routes.forEach((route, index) => {
 fastify.route(route)
})

Acum suntem gata să începem testarea!

Cel mai bun instrument pentru job este Poştaş, pe care îl vom folosi pentru a testa toate traseele noastre. Vom trimite datele noastre ca obiecte brute în corpul cererii și ca parametri.

Găsirea tuturor mașinilor:

1611099367 111 Cum sa construiti API uri REST rapide cu Nodejs MongoDB Fastify

Găsirea unei singure mașini:

1611099367 331 Cum sa construiti API uri REST rapide cu Nodejs MongoDB Fastify

Adăugarea unei mașini noi **:

1611099368 534 Cum sa construiti API uri REST rapide cu Nodejs MongoDB Fastify

** Serviciile par a fi goale, dar informațiile persistă de fapt în baza de date.

Actualizarea unei mașini:

1611099368 758 Cum sa construiti API uri REST rapide cu Nodejs MongoDB Fastify

Ștergerea unei mașini:

1611099368 446 Cum sa construiti API uri REST rapide cu Nodejs MongoDB Fastify

Acum avem un API complet funcțional – dar ce zici de documentație? Aici e locul Făli este cu adevărat la îndemână.

1611099368 892 Cum sa construiti API uri REST rapide cu Nodejs MongoDB Fastify

Adăugarea Swagger și încheierea.

Acum vom crea folderul final numit config. În interior vom crea un fișier numit swagger.js cu următorul cod:

exports.options = {
  routePrefix: '/documentation',
  exposeRoute: true,
  swagger: {
    info: {
      title: 'Fastify API',
      description: 'Building a blazing fast REST API with Node.js, MongoDB, Fastify and Swagger',
      version: '1.0.0'
    },
    externalDocs: {
      url: 'https://swagger.io',
      description: 'Find more info here'
    },
    host: 'localhost',
    schemes: ['http'],
    consumes: ['application/json'],
    produces: ['application/json']
  }
}

Codul de mai sus este un obiect cu opțiunile pe care le vom transmite în al nostru fastify-swagger conecteaza. Pentru a face acest lucru, trebuie să adăugăm următoarele la index.js fişier:

// Import Swagger Options
const swagger = require(‘./config/swagger’)

// Register Swagger
fastify.register(require(‘fastify-swagger’), swagger.options)

Și atunci trebuie să adăugăm următoarea linie după ce ne-am inițializat Fastify Server:

...
await fastify.listen(3000)
fastify.swagger()
fastify.log.info(`listening on ${fastify.server.address().port}`)
...

Și asta este! Dacă navigați acum la http: // localhost: 3000 / documentare, ar trebui să vedeți următoarele:

1611099369 276 Cum sa construiti API uri REST rapide cu Nodejs MongoDB Fastify

Simplu ca buna ziua! Acum aveți documentația API de actualizare automată care va evolua odată cu API-ul dvs. Puteți adăuga cu ușurință informații suplimentare la rutele dvs., vedeți mai multe aici.

Ce urmeaza?

Acum că avem un API de bază, posibilitățile sunt nelimitate. Poate fi folosit ca bază pentru orice aplicație imaginabilă.

În următorul tutorial, ne vom integra GraphQL și în cele din urmă să integreze frontendul cu Vue.js de asemenea!