Что такое REST

Ответ

REST (Representational State Transfer) — это архитектурный стиль для построения распределенных систем, в частности веб-сервисов (RESTful API). Он использует стандартные возможности протокола HTTP.

Основные принципы REST применительно к разработке на Node.js:

  1. Ресурсо-ориентированность: Все сущности (пользователи, заказы) представляются как ресурсы с уникальными идентификаторами (URI).

    • GET /api/users — получить список пользователей.
    • GET /api/users/123 — получить пользователя с ID 123.
  2. Единообразие интерфейса (Uniform Interface): Использование стандартных HTTP-методов для операций CRUD.

    • GET — получение ресурса.
    • POST — создание нового ресурса.
    • PUT — полное обновление ресурса.
    • PATCH — частичное обновление ресурса.
    • DELETE — удаление ресурса.
  3. Отсутствие состояния (Stateless): Каждый запрос от клиента должен содержать всю информацию, необходимую серверу для его обработки. Сервер не хранит состояние сессии клиента между запросами. Аутентификация, например, реализуется через токены (JWT в заголовке каждого запроса).

  4. Кэшируемость: Ответы сервера должны явно указывать, можно ли их кэшировать и как долго (через HTTP-заголовки Cache-Control, ETag).

  5. Слоистая система: Клиент не знает, подключен ли он напрямую к серверу или через промежуточные узлы (балансировщики, прокси, шлюзы).

Пример реализации простого RESTful API для ресурса articles на Express.js:

const express = require('express');
const app = express();
app.use(express.json());

let articles = [{ id: 1, title: 'First Article' }];
let nextId = 2;

// GET /articles — получить все статьи
app.get('/articles', (req, res) => {
  res.json(articles);
});

// POST /articles — создать новую статью
app.post('/articles', (req, res) => {
  const newArticle = { id: nextId++, ...req.body };
  articles.push(newArticle);
  res.status(201).json(newArticle); // 201 Created
});

// GET /articles/:id — получить статью по ID
app.get('/articles/:id', (req, res) => {
  const article = articles.find(a => a.id === parseInt(req.params.id));
  if (!article) return res.status(404).send('Article not found');
  res.json(article);
});

// PUT /articles/:id — полностью обновить статью
app.put('/articles/:id', (req, res) => {
  const index = articles.findIndex(a => a.id === parseInt(req.params.id));
  if (index === -1) return res.status(404).send('Article not found');
  articles[index] = { id: articles[index].id, ...req.body };
  res.json(articles[index]);
});

// DELETE /articles/:id — удалить статью
app.delete('/articles/:id', (req, res) => {
  const initialLength = articles.length;
  articles = articles.filter(a => a.id !== parseInt(req.params.id));
  if (articles.length === initialLength) return res.status(404).send('Article not found');
  res.status(204).send(); // 204 No Content
});

app.listen(3000);

Ответ 18+ 🔞

А, REST, ну это же классика, ёпта! Сидишь такой, пишешь очередной API, а тебе говорят: «Сделай по REST». И ты такой: «Да похуй, я и так сделаю». Но нет, блядь, есть правила, и их надо соблюдать, иначе получится пиздопроебибна, а не API.

Смотри, REST — это не какая-то херня с блэкджеком и шлюхами. Это, по сути, просто способ договориться с сервером на языке HTTP, чтобы он тебя понимал. Представь, что твой сервер — это туповатый, но очень принципиальный чиновник. Ему нужно всё по форме, по протоколу, иначе он тебя пошлёт нахуй с ошибкой 400.

Основные закидоны этого чиновника (то есть принципы REST):

  1. Всё — ресурсы. Не «дай-ка мне данных», а «дай-ка мне ресурс «пользователи». Каждой сущности — свой уникальный адрес (URI), как квартира. Хочешь получить всех жильцов? GET /api/users. Нужен конкретный Вася с татухой? GET /api/users/123. Всё просто, как три копейки, блядь.

  2. Единый интерфейс, ёбана! Ты не можешь прийти к чиновнику и сказать: «Вася, обновись». Ты должен использовать правильные глаголы, которые все понимают. В HTTP это методы:

    • GET — посмотреть (не трогая).
    • POST — создать новую хуйню.
    • PUT — переписать всё с нуля, по-новой.
    • PATCH — подправить только одно поле, не трогая остальное.
    • DELETE — отправить нахуй, удалить к хуям.
  3. Без состояния (Stateless). Это самый важный пункт, на котором все обламываются. Чиновник тебя не помнит. Совсем. Ты пришёл — он тебя обслужил и забыл. Приходишь снова — представляешься заново. Никаких сессий, которые он хранит у себя в жопе. Вся информация для работы — в самом запросе. Обычно это токен (JWT), который ты суёшь в заголовок каждый раз. Доверия ебать ноль, только холодная логика.

  4. Кэширование. Чтобы чиновника не дергать по пустякам, он может тебе выдать бумажку (ответ) с пометкой «актуально до пятницы». И пока не наступила пятница, ты пользуешься этой бумажкой, а не бегаешь к нему. За это отвечают специальные заголовки в ответе.

  5. Слои. Ты вообще не знаешь, с кем общаешься на самом деле. Может, перед чиновником сидит его секретарша (балансировщик), а может, целая цепочка из десяти человек. Тебе да похуй, главное — интерфейс один и тот же.

Ну а теперь, чувак, смотри, как это выглядит в коде на Node.js с Express. Проще пареной репы, если не выёбываться.

const express = require('express');
const app = express();
app.use(express.json()); // Чтоб понимал JSON, который мы ему в тело запроса пихаем

// Наш «магазин» статей. Пока что тут одна статья, грустная и одинокая.
let articles = [{ id: 1, title: 'First Article' }];
let nextId = 2; // Счётчик для новых ID

// 1. GET /articles — получить все статьи (просто посмотреть на витрину)
app.get('/articles', (req, res) => {
  res.json(articles); // Отправляем весь массив обратно
});

// 2. POST /articles — создать новую статью (принести свою хуйню в магазин)
app.post('/articles', (req, res) => {
  // Берем данные из тела запроса (req.body), добавляем свой ID
  const newArticle = { id: nextId++, ...req.body };
  articles.push(newArticle); // Кидаем в наш массив
  res.status(201).json(newArticle); // Отвечаем кодом 201 (Создано) и шлём созданную статью назад
});

// 3. GET /articles/:id — получить одну статью по ID (найти конкретную хуйню на полке)
app.get('/articles/:id', (req, res) => {
  const article = articles.find(a => a.id === parseInt(req.params.id));
  if (!article) return res.status(404).send('Article not found'); // Если нет — 404, иди нахуй
  res.json(article); // Если нашли — отдаём
});

// 4. PUT /articles/:id — полностью обновить статью (заменить старую хуйню на новую)
app.put('/articles/:id', (req, res) => {
  const index = articles.findIndex(a => a.id === parseInt(req.params.id));
  if (index === -1) return res.status(404).send('Article not found'); // Опять нет? 404.
  // Заменяем объект целиком. Старые поля, которых нет в req.body, — нахуй пропадут.
  articles[index] = { id: articles[index].id, ...req.body };
  res.json(articles[index]); // Отдаём обновлённый вариант
});

// 5. DELETE /articles/:id — удалить статью (выкинуть хуйню в мусорку)
app.delete('/articles/:id', (req, res) => {
  const initialLength = articles.length;
  articles = articles.filter(a => a.id !== parseInt(req.params.id)); // Фильтруем, оставляем всех, кроме этого ID
  if (articles.length === initialLength) return res.status(404).send('Article not found'); // Если длина не изменилась — не нашли что удалять
  res.status(204).send(); // 204 No Content — всё ок, но в ответе нихуя нет, иди отсюда
});

app.listen(3000); // Слушаем порт, ждём, когда к нам придут

Вот и вся магия, я дарёна вошь. С одной стороны, правила как будто из армии, но с другой — когда все их соблюдают, получается овердохуища удобно. Клиенты знают, чего ждать, сервер предсказуем. Главное — не забывай про stateless, а то начнёшь сессии хранить, и потом сам от себя охуеешь, когда всё посыпется.

Видео-ответы