Урок 23 из 49 · Месяц 3. JavaScript, часть 2
REST API, HTTP и HTTPS, методы PUT и DELETE
Содержание урока
- HTTP — язык общения браузера и сервера
- Важные заголовки
- HTTPS — защищённый HTTP
- Что такое REST API
- Ресурсы и адреса
- Методы — что делаем с ресурсом
- Другие принципы REST
- Метод PUT — заменить запись
- PATCH — изменить только часть
- Метод DELETE — удалить запись
- Практика: список задач с полным CRUD
- Практика от менторов и установка Node.js
- Что такое Node.js
- Установка
- Первый скрипт на Node.js
- Если что-то пошло не так
- Практика
- Итоги
Мы уже умеем получать данные методом GET и создавать их методом POST. Пора разобраться, по каким правилам вообще устроены API, с которыми работает фронтенд. В этом уроке поговорим о протоколах HTTP и HTTPS, разберём подход REST API, научимся изменять и удалять данные методами PUT и DELETE, а в конце установим Node.js — он понадобится уже в следующем уроке и дальше на протяжении всего курса.
HTTP — язык общения браузера и сервера
HTTP (HyperText Transfer Protocol) — это набор правил, по которым клиент и сервер обмениваются сообщениями. Как правила оформления письма: адрес получателя, тема, текст. Если обе стороны соблюдают правила, они понимают друг друга.
Каждое общение — это пара запрос → ответ. Вот как выглядит HTTP-запрос «изнутри» (так его видит сервер):
PUT /posts/1 HTTP/1.1
Host: jsonplaceholder.typicode.com
Content-Type: application/json
{"id":1,"title":"Новый заголовок","body":"Новый текст","userId":1}
- Первая строка: метод (
PUT), путь (/posts/1) и версия протокола. - Дальше заголовки — служебная информация в виде
Имя: значение. - После пустой строки — тело запроса.
Ответ сервера устроен похоже:
HTTP/1.1 200 OK
Content-Type: application/json; charset=utf-8
{"id":1,"title":"Новый заголовок","body":"Новый текст","userId":1}
Первая строка ответа содержит статус-код. Напомним группы:
| Группа | Смысл | Примеры |
|---|---|---|
| 1xx | информационные | редко встречаются во фронтенде |
| 2xx | успех | 200 OK, 201 Created, 204 No Content |
| 3xx | перенаправление | 301 Moved Permanently, 304 Not Modified |
| 4xx | ошибка клиента | 400, 401, 403 Forbidden, 404, 422 |
| 5xx | ошибка сервера | 500, 502 Bad Gateway, 503 |
Важные заголовки
| Заголовок | Для чего |
|---|---|
Content-Type |
в каком формате тело: application/json, text/html |
Accept |
какой формат ответа клиент хочет получить |
Authorization |
токен доступа, например Bearer YOUR_TOKEN |
HTTPS — защищённый HTTP
Обычный HTTP передаёт данные открытым текстом. Любой, кто находится «между» вами и сервером (например, владелец публичного Wi-Fi), может прочитать пароль или подменить страницу.
HTTPS — это тот же HTTP, но внутри зашифрованного канала (протокол TLS). Аналогия: HTTP — открытка, которую по пути может прочитать любой почтальон; HTTPS — письмо в запечатанном конверте, который может открыть только получатель.
Что даёт HTTPS:
- шифрование — посторонние не прочитают данные;
- целостность — данные нельзя незаметно изменить по дороге;
- подлинность — сертификат подтверждает, что вы говорите именно с нужным сайтом.
Что такое REST API
API (Application Programming Interface) — это «меню» сервера: список адресов и действий, которые он умеет выполнять. REST — популярный стиль, по которому это меню удобно организовать.
Главная идея REST: всё на сервере — это ресурсы (пользователи, посты, товары), у каждого ресурса есть свой адрес (URL), а действие определяется HTTP-методом.
Аналогия — библиотека. Книги — ресурсы, у каждой есть номер на полке (URL). Вы можете взять книгу почитать (GET), сдать новую (POST), заменить испорченную (PUT), исправить опечатку (PATCH) или списать (DELETE).
Ресурсы и адреса
| Адрес | Что это |
|---|---|
/posts |
коллекция — все посты |
/posts/1 |
один конкретный пост с id = 1 |
/posts/1/comments |
комментарии к посту 1 |
/users/3/todos |
задачи пользователя 3 |
В адресе принято писать существительные во множественном числе, а не глаголы. Не /getPosts или /deletePost?id=1, а /posts и /posts/1 с нужным методом.
Методы — что делаем с ресурсом
| Метод | Действие | Пример | Тело запроса | Типичный ответ |
|---|---|---|---|---|
GET |
получить | GET /posts/1 |
нет | 200 + данные |
POST |
создать | POST /posts |
новый объект | 201 + созданный объект |
PUT |
заменить целиком | PUT /posts/1 |
весь объект | 200 + обновлённый объект |
PATCH |
изменить частично | PATCH /posts/1 |
только изменённые поля | 200 + обновлённый объект |
DELETE |
удалить | DELETE /posts/1 |
нет | 200 или 204 |
Эти четыре базовые операции часто называют CRUD: Create (создать), Read (прочитать), Update (обновить), Delete (удалить).
Другие принципы REST
- Без сохранения состояния (stateless). Сервер не помнит предыдущих запросов клиента. Каждый запрос должен содержать всё нужное, например токен авторизации.
- Единый формат. Обычно JSON и в запросах, и в ответах.
- Предсказуемость. Зная адрес
/posts, легко догадаться про/posts/5и/users.
Метод PUT — заменить запись
PUT отправляет полную новую версию ресурса. Всё, что вы не передали, может быть потеряно.
const API_URL = "https://jsonplaceholder.typicode.com";
async function updatePost(id, post) {
const response = await fetch(`${API_URL}/posts/${id}`, {
method: "PUT",
headers: { "Content-Type": "application/json" },
body: JSON.stringify(post),
});
if (!response.ok) throw new Error(`Ошибка ${response.status}`);
return response.json();
}
updatePost(1, {
id: 1,
title: "Обновлённый заголовок",
body: "Полностью новый текст поста",
userId: 1,
}).then((post) => console.log(post));
Разбор:
- Адрес указывает на конкретную запись —
/posts/1, а не на всю коллекцию. - В теле — все поля объекта, даже те, что не менялись (
userId). - Сервер возвращает обновлённую запись.
PATCH — изменить только часть
Если нужно поменять одно поле, удобнее PATCH: передаём только то, что меняется.
async function patchPost(id, changes) {
const response = await fetch(`${API_URL}/posts/${id}`, {
method: "PATCH",
headers: { "Content-Type": "application/json" },
body: JSON.stringify(changes),
});
if (!response.ok) throw new Error(`Ошибка ${response.status}`);
return response.json();
}
patchPost(1, { title: "Только новый заголовок" }).then((post) => {
console.log(post.title); // "Только новый заголовок"
console.log(post.body); // старый текст сохранился
});
Метод DELETE — удалить запись
У DELETE обычно нет тела: всё нужное есть в адресе.
async function deletePost(id) {
const response = await fetch(`${API_URL}/posts/${id}`, {
method: "DELETE",
});
if (!response.ok) throw new Error(`Не удалось удалить: ${response.status}`);
return true;
}
deletePost(1).then(() => console.log("Пост удалён"));
Сервер может ответить 200 с телом или 204 No Content без тела. Поэтому после DELETE не вызывайте response.json() бездумно: у пустого ответа это вызовет ошибку.
Практика: список задач с полным CRUD
Соберём маленькое приложение, которое использует все методы. Задачи загружаются с сервера, их можно отмечать выполненными и удалять.
<ul id="todos"></ul>
<script src="todos.js"></script>
// todos.js
const API_URL = "https://jsonplaceholder.typicode.com";
const list = document.querySelector("#todos");
async function request(path, options = {}) {
const response = await fetch(`${API_URL}${path}`, {
headers: { "Content-Type": "application/json" },
...options,
});
if (!response.ok) throw new Error(`Ошибка ${response.status}`);
return response.status === 204 ? null : response.json();
}
function renderTodo(todo) {
const li = document.createElement("li");
li.dataset.id = todo.id;
const checkbox = document.createElement("input");
checkbox.type = "checkbox";
checkbox.checked = todo.completed;
const title = document.createElement("span");
title.textContent = todo.title;
const removeBtn = document.createElement("button");
removeBtn.type = "button";
removeBtn.textContent = "Удалить";
checkbox.addEventListener("change", async () => {
try {
await request(`/todos/${todo.id}`, {
method: "PATCH",
body: JSON.stringify({ completed: checkbox.checked }),
});
} catch (error) {
checkbox.checked = !checkbox.checked; // откатываем галочку
alert("Не удалось сохранить");
}
});
removeBtn.addEventListener("click", async () => {
if (!confirm(`Удалить «${todo.title}»?`)) return;
try {
await request(`/todos/${todo.id}`, { method: "DELETE" });
li.remove();
} catch (error) {
alert("Не удалось удалить");
}
});
li.append(checkbox, title, removeBtn);
return li;
}
async function init() {
try {
const todos = await request("/todos?_limit=5");
list.append(...todos.map(renderTodo));
} catch (error) {
list.textContent = "Не удалось загрузить задачи";
}
}
init();
Что здесь нового:
- Функция
request— обёртка надfetch. Она подставляет базовый адрес и заголовок, проверяетokи разбирает JSON. Каждый новый запрос — одна строка. Такие обёртки есть почти в каждом проекте. ...options— spread: настройки, переданные при вызове (method,body), добавляются к стандартным.- Откат галочки. Если PATCH не удался, возвращаем чекбокс в прежнее состояние, чтобы интерфейс не врал пользователю.
list.append(...todos.map(renderTodo))— превращаем каждую задачу в<li>и добавляем все сразу.
Практика от менторов и установка Node.js
На практическом занятии ментор разберёт с группой свой пример API и покажет, как читать его документацию. Чтобы быть готовыми, установите Node.js заранее.
Что такое Node.js
Node.js — программа, которая запускает JavaScript вне браузера: прямо на компьютере, в терминале. Вместе с ним устанавливается npm — менеджер пакетов, с которым мы познакомимся в уроке про npm и package.json. Без Node.js не работают ни Vite, ни React-проекты, ни большинство инструментов фронтендера.
Установка
- Откройте официальный сайт nodejs.org и скачайте версию LTS (Long Term Support — версия с долгой поддержкой, самая стабильная). Чётные версии (например, 22 или 24) — это LTS-линейки.
- Запустите установщик и нажимайте «Далее», оставляя настройки по умолчанию.
- Перезапустите терминал (или VS Code), чтобы он «увидел» новую программу.
- Проверьте установку:
node -v
npm -v
Если в ответ появились номера версий, например v24.x.x и 11.x.x, — всё готово. Точные цифры у вас могут отличаться, главное — что команды работают.
Первый скрипт на Node.js
Создайте файл hello.js:
const name = "Атлас";
console.log(`Привет из Node.js, ${name}!`);
console.log("Версия Node:", process.version);
Запустите его в терминале из той же папки:
node hello.js
Вы увидите вывод прямо в терминале. В Node.js нет document и window — нет страницы, — зато есть доступ к файлам и сети. А ещё в нём тоже есть fetch:
// users.js
const response = await fetch("https://jsonplaceholder.typicode.com/users");
const users = await response.json();
console.log(users.map((u) => u.name));
Чтобы await работал на верхнем уровне, сохраните файл с расширением .mjs (users.mjs) — так Node.js поймёт, что это модуль — и запустите node users.mjs.
Если что-то пошло не так
node: command not foundили «не является внутренней командой» — терминал не перезапущен, либо при установке не была отмечена опция добавления в PATH. Перезапустите компьютер или переустановите Node.js.- В PowerShell ошибка про «выполнение сценариев отключено» при запуске
npm— используйте Git Bash или Командную строку, либо спросите ментора, как поменять политику выполнения.
Практика
- Разобрать адреса. Для интернет-магазина запишите REST-адреса и методы для действий: получить все товары, получить товар 7, создать товар, изменить цену товара 7, удалить товар 7, получить отзывы к товару 7.
- PUT. Через
fetchотправьте PUT на/posts/1с новым заголовком и текстом. Выведите ответ в консоль и убедитесь, что статус — 200. - PATCH и DELETE. Отправьте PATCH на
/todos/1с{ completed: true }, затем DELETE на/todos/1. Для каждого запроса выведите в консольresponse.status. - Редактирование поста. Загрузите пост
/posts/1и подставьте его в форму (inputдля заголовка,textareaдля текста). При отправке формы — PUT-запрос и сообщение «Сохранено». - Node.js. Установите Node.js, проверьте
node -vиnpm -v, затем напишите скриптtodos.mjs, который загружает задачи пользователя 1 и выводит в терминал количество выполненных и невыполненных.
Итоги
- HTTP — правила обмена «запрос → ответ»: метод, адрес, заголовки, тело и статус-код.
- HTTPS — тот же HTTP, но зашифрованный; для форм с личными данными — только он.
- REST: ресурсы с понятными адресами (
/posts/1), действие задаёт метод. - CRUD: POST — создать, GET — прочитать, PUT/PATCH — обновить, DELETE — удалить.
- PUT заменяет запись целиком, PATCH меняет только переданные поля.
- Node.js запускает JavaScript вне браузера; ставим версию LTS и проверяем
node -v.