Vytvoření REST API s Express.js a PostgreSQL

Tento tutoriál je částí 5 z 5 této série.

  • Část 1:Minimální Node.js s Babel Setup
  • Část 2:Jak nastavit Express.js v Node.js
  • Část 3:Jak vytvořit REST API s Express.js v Node.js
  • Část 4:Nastavení PostgreSQL pomocí Sequelize v Express

Node + Express + PostgreSQL je výkonný technologický zásobník pro backendové aplikace, který nabízí operace CRUD. Poskytuje vám vše pro odhalení API (Express routes), pro přidání obchodní logiky (Express middleware a logiku v rámci Express routes) a pro použití skutečných dat s databází (PostgreSQL). Je ideální pro vytvoření technologického zásobníku PERN (PostgreSQL, Express, React, Node), PEAN (PostgreSQL, Express, Angular, Node) nebo PEVN (PostgreSQL, Express, Vue, Node). Vše, co by chybělo, je frontendová aplikace s React, Angular, Vue nebo něčím jiným. Ale to je na jinou sekci.

Tato část se nejprve zaměřuje na připojení PostgreSQL k Express pro naše REST API. Dříve jsme nastavili PostgreSQL v naší aplikaci Express.js a nasadili databázi počátečními daty, ale zatím jsme ji v Express pro RESTful API nepoužili. Nyní se chceme ujistit, že každá operace CRUD procházející tímto REST API čte nebo zapisuje z/do databáze PostgreSQL, místo aby používala ukázková data, jak jsme to dělali dříve pro naše expresní trasy. Proto potřebujeme propojit naše Express trasy s PostgreSQL přes Sequelize, abychom spojili oba světy.

V našem src/index.js tam, kde nastavujeme a spouštíme aplikaci Express s databází PostgreSQL, již máme na místě expresní middleware, který předává modely jako kontext všem našim expresním trasám. Dříve byly tyto modely vzorovými daty. Nyní používáme modely Sequelize, které nás připojují k databázi PostgreSQL. Vzhledem k tomu, že struktura dat složek/souborů je stejná jako dříve, nic se nemění pro předávání modelů jako kontextu do expresních tras.

import express from 'express';...
import models, { sequelize } from './models';
const app = express();
...
app.use((req, res, next) => {  req.context = {    models,    me: models.users[1],  };  next();});
...

Uživatele me (autentizovaný uživatel) však lze získat z nasazených dat z databáze. Neexistuje žádný users pole již dostupné jako ukázková data na objektu modelů, protože modely jsou nyní naším rozhraním k databázi PostgreSQL.

import express from 'express';...
import models, { sequelize } from './models';
const app = express();
...
app.use(async (req, res, next) => {  req.context = {    models,    me: await models.User.findByLogin('rwieruch'),  };  next();});
...

I když ověřeného uživatele ještě neznáme, protože pro něj nepředáváme žádná data do REST API zvenčí, vezmeme pouze libovolného uživatele, o kterém víme, že v naší databázi existuje kvůli předchozímu nasazování databáze PostgreSQL. findByLogin metoda je na našem modelu dostupná, protože jsme ji dříve implementovali jako vlastní metodu pro získávání uživatelů podle uživatelského jména nebo e-mailu.

Pojďme se nyní ponořit do našich expresních tras. Máme trasy pro relaci, uživatele a entitu zprávy. Entita relace je na prvním místě. Opět, místo použití ukázkových dat, která byla u modelů k dispozici dříve, můžeme k interakci s databází nyní použít rozhraní modelů – poháněné Sequelize. V souboru src/routes/session.js změňte následující řádky kódu:

import { Router } from 'express';
const router = Router();
router.get('/', async (req, res) => {  const user = await req.context.models.User.findByPk(    req.context.me.id,  );  return res.send(user);});
export default router;

Z funkce route se stává asynchronní funkce, protože nyní řešíme asynchronní požadavek na databázi PostgreSQL. Asynchronní povahu funkce řešíme pomocí async/await.

Vzhledem k tomu, že dříve jsme modely pohodlně předávali přes objekt kontextu do každé expresní cesty s aplikačním Express middlewarem, můžeme toho využít zde. Autentizovaného uživatele, kterého jsme dříve libovolně převzali z databáze PostgreSQL, lze použít k získání aktuálního uživatele relace z databáze.

Pojďme se vypořádat s uživatelskými trasami v src/routes/user.js soubor, který nabízí koncové body RESTful API pro načítání uživatelů nebo jednoho uživatele podle id. Oba požadavky API by měly vést k operacím čtení pro databázi PostgreSQL:

import { Router } from 'express';
const router = Router();
router.get('/', async (req, res) => {  const users = await req.context.models.User.findAll();  return res.send(users);});
router.get('/:userId', async (req, res) => {  const user = await req.context.models.User.findByPk(    req.params.userId,  );  return res.send(user);});
export default router;

První koncový bod API, který načte seznam uživatelů, nezíská z požadavku žádné vstupní parametry. Ale druhý koncový bod API má přístup k identifikátoru uživatele, aby mohl číst správného uživatele z databáze PostgreSQL.

V neposlední řadě, směrování zpráv v src/routes/message.js soubor. Kromě čtení zpráv a jedné zprávy podle identifikátoru máme také koncové body API pro vytváření zprávy a mazání zprávy. Obě operace by měly vést k operacím zápisu pro PostgreSQL databázi:

import { Router } from 'express';
const router = Router();
router.get('/', async (req, res) => {  const messages = await req.context.models.Message.findAll();  return res.send(messages);});
router.get('/:messageId', async (req, res) => {  const message = await req.context.models.Message.findByPk(    req.params.messageId,  );  return res.send(message);});
router.post('/', async (req, res) => {  const message = await req.context.models.Message.create({    text: req.body.text,    userId: req.context.me.id,  });
  return res.send(message);});
router.delete('/:messageId', async (req, res) => {  const result = await req.context.models.Message.destroy({    where: { id: req.params.messageId },  });
  return res.send(true);});
export default router;

V podstatě to je vše pro připojení PostgreSQL k expresním trasám pomocí Sequelize. Všechny modely nastavené pomocí Sequelize lze použít jako rozhraní k vaší databázi PostgreSQL. Jakmile uživatel narazí na vaše REST API, můžete provádět operace čtení nebo zápisu v expresních trasách do vaší databáze PostgreSQL.

Cvičení

  • Potvrďte zdrojový kód pro poslední sekci. Uvědomte si, že projekt nemůže správně běžet v karanténě, protože neexistuje žádná databáze.
    • Potvrďte změny z poslední sekce.
  • Zkontrolujte zdrojový kód alternativní implementace MongoDB s Mongoose
  • Experimentujte s vaším REST API s operacemi cURL.

Tento tutoriál je částí 1 ze 2 této série.

  • Část 2:Jak zacházet s chybami v Express