Sestavte REST API historie konfliktů pomocí Express.js

Ahoj všichni! Vítejte u mého opravdu prvního příspěvku v DEV.
Před týdnem jsem našel zajímavý dataset, který obsahuje seznam konfliktů v Kaggle (History of Conflicts). Tato datová sada ukazuje konflikty, ke kterým došlo ve světě. Obsahuje více než 900 řádků. Ať už jsou data platná nebo ne, můžeme se pomocí této datové sady naučit.
Data jsem transformoval do JSON. Zde můžete pouze zkopírovat. Rozdělil jsem data každých 20 položek do nového pole. Takže forma JSON, kterou jsem poskytl, bude array of array of object .
Pokud chcete vidět konečný výsledek [který byl integrován s frontendovou aplikací], můžete navštívit tento odkaz. Samozřejmě naši aplikaci nasadíme poté, co bude aplikace kompletně sestavena.

Inicializujte projekt Node.js a poté nainstalujte závislosti:express, cors a dotenv. Také instaluji nodemon jako devDependencies.

mkdir history-of-conflicts-backend
cd history-of-conflicts-backend
npm init -y
npm i express cors dotenv --save
npm i nodemon --save-dev

V package.json upravte skripty.

"scripts": {
   "dev": "nodemon index.js",
   "start": "node index.js"
 },

Vytvořte index.js v kořenovém adresáři projektu, jak jsme definovali, že ./index.js je náš vstupní bod.
Vytvořte expresní server v ./index.js a ujistěte se, že náš webový server funguje správně.

const express = require('express');
const cors = require('cors');
const app = express();
const PORT = process.env.PORT || 4000;

app.use(cors());

app.get('/', (req, res) => {
  res.json({
    message: 'Hello',
  });
});

app.listen(PORT, () => console.log(`Server is running on port ${PORT}`));

Spusťte npm run dev a stiskněte http://localhost:4000 v Postman (nebo něco takového).
Našli jste odpověď json s "message": "Hello" ? Pokud ano, pojďme k dalšímu kroku!
Vytvořte soubor .json s názvem transformed-data.json a umístěte jej pod /data adresář.

data
  - transformed-data.json

Nyní potřebujeme ovladač, který bude obsluhovat části součásti. „část“, kterou mám na mysli, je skupina řádků. V kufru máme 47 dílů. Prvních 46 dílů má 20 řad, zatímco poslední díly mají 6 řad.
Musíme tedy vytvořit koncový bod podobný stránkování. Skupinu částí nazýváme sekce.

Vytvořte soubor ./controllers/index.js . V horní části řádku importujte transformed-data.json.

const transformedData = require('../data/transformed-data.json');

Protože jsem neposkytl transformovaná data (soubor, který byl rozdělen na části do sekcí), musíme to udělat ručně. Chcete-li to provést, vytvořte funkci nazvanou startEndIndexFinder pod řádkem, který je importován transformed-data.json.

function startEndIndexFinder({ currentSection, itemsPerSection }) {
  const section = +currentSection < 0 ? 1 : +currentSection;
  const startIndex = (section - 1) * itemsPerSection;
  const endIndex = section * itemsPerSection - 1;
  return { section, startIndex, endIndex };
}

Funkce obdrží objekt jako parametr, který obsahuje currentSection a itemsPerSection. Ujistěte se, že currentSection je větší než 0. Potom najděte první index a poslední index aktuální sekce. Nakonec vraťte objekt, který obsahuje sekci, počáteční index a koncový index.

Použijte startEndIndexFinder k našemu /parts řadiči.

const partsController = async (req, res) => {
  const currentSection = req.query.section || '1';
  const itemsPerSection =
    +req.query.itemsPerSection || transformedData.length + 1;
  const { endIndex, section, startIndex } = startEndIndexFinder({
    currentSection,
    itemsPerSection,
  });
  const maxSection = Math.ceil(transformedData.length / itemsPerSection);
  if (+currentSection > maxSection) {
    res.status(404).json({
      status: false,
      message: 'No more sections',
      data: {
        itemsPerSection,
        maxSection,
      },
    });
  }
  const data = transformedData
    .map((item, index) => {
      if (index >= startIndex && index <= endIndex) {
        return {
          id: index + 1,
          name: `Part ${index + 1}`,
          from: item[0].Date,
          to: item[item.length - 1].Date,
          link: `/api/parts/${index + 1}`,
        };
      }
    })
    .filter((item) => item);
  res.status(200).json({
    status: true,
    message: 'Sections of parts were successfully fetched',
    data: {
      itemsPerSection,
      section,
      startIndex,
      endIndex,
      maxSection,
      data,
    },
  });
};

module.exports = { partsController };

Z požadavku jsme obdrželi aktuální sekci a itemsPerSection. ItemsPerSection se ověřuje na tomto řadiči, protože existuje možnost, že klient odešle různé množství itemsPerSection v každém požadavku. Takže musíme provést tento const maxSection = Math.ceil(transformedData.length / itemsPerSection);

Samozřejmě můžete napsat čistší kód než ten můj :)

Po vytvoření našeho prvního ovladače jej můžeme použít.

const { partsController } = require('./controllers');
// ...
app.get('/api/parts', partsController);
app.listen(PORT, () => console.log(`Server is running on port ${PORT}`));

Test. Funguje to? Pokud ano, pojďme na další krok.

Druhý ovladač má sloužit detailu dílu. Je to jednodušší než předchozí.

// ...
const partController = async (req, res) => {
  const { params } = req;
  let part = params.part ? +params.part - 1 : 1;
  part = part < 0 ? 0 : part;
  part = part > transformedData.length - 1 ? transformedData.length - 1 : part;
  res.status(200).json({
    status: true,
    message: 'List of parts was successfully fetched',
    data: transformedData[part],
  });
};
module.exports = { partsController, partController };

Poté jej použijte v ./index.js.

const { partsController, partController } = require('./controllers');
// ...
app.get('/api/parts/:part', partController);

Otestujte to znovu. Pokud budete úspěšní, naše API je již hotové.

Zdaleka naše struktura složek vypadá takto.

/controllers
  - index.js
/data
  - transformed-data.json
/node_modules
  ........
index.js
package.json

V dalším kroku nasadíme tuto aplikaci do Vercelu.

Úložiště GitHub
Uvidíme se!