Пошук уроків, статей та іншого контенту
Розглянете взаємодію клієнтів і серверів, ролі компонентів та обмін запитами й відповідями.
Клієнт–серверна архітектура — це спосіб організації програм, за якого різні частини системи мають окремі ролі:
клієнт надсилає запити та взаємодіє з користувачем;
сервер приймає запити, виконує логіку й повертає результати.
Найпоширеніший приклад:
Користувач відкриває вебсторінку.
Браузер, тобто клієнт, надсилає запит на сервер.
Сервер обробляє запит.
Сервер надсилає відповідь.
Браузер показує результат користувачу.
Клієнтом може бути не лише браузер. Це також:
мобільний застосунок;
desktop-застосунок;
інший сервер;
консольна програма;
пристрій або мікроконтролер.
Сервером є програма, яка очікує на запити через мережу та відповідає на них.
Клієнт зазвичай відповідає за:
інтерфейс користувача;
введення та відображення даних;
надсилання запитів;
обробку отриманих відповідей;
локальний стан застосунку.
Наприклад, коли користувач натискає кнопку «Показати профіль», клієнт формує запит до сервера.
Клієнт не обов’язково має знати, як саме сервер отримує або зберігає дані. Йому достатньо знати, куди надіслати запит і в якому форматі очікувати відповідь.
Сервер зазвичай відповідає за:
приймання запитів;
перевірку даних;
виконання бізнес-логіки;
автентифікацію та авторизацію;
взаємодію з базою даних;
формування відповідей.
Наприклад, сервер може отримати запит на перегляд профілю, знайти потрібного користувача в базі даних і повернути його ім’я та електронну адресу.
Сервер не повинен покладатися на те, що клієнт завжди коректний. Дані потрібно перевіряти на сервері, оскільки клієнтський код можна змінити або обійти.
Типовий обмін складається із запиту та відповіді.
Клієнт Сервер
| |
| ---- HTTP-запит ------------>|
| |
| обробка запиту |
| |
| <--- HTTP-відповідь ---------|
| |Запит містить інформацію про те, що клієнт хоче зробити. Він може містити:
HTTP-метод;
адресу ресурсу;
заголовки;
тіло запиту.
Наприклад:
GET /users/42 HTTP/1.1
Host: example.com
Accept: application/jsonУ цьому запиті:
GET — метод отримання даних;
/users/42 — шлях до ресурсу;
Host — ім’я сервера;
Accept — формат, який клієнт бажає отримати.
Для надсилання даних часто використовують тіло запиту:
POST /users HTTP/1.1
Content-Type: application/json
{"name":"Oksana","email":"oksana@example.com"}Відповідь містить результат обробки запиту. Вона може містити:
статусний код;
заголовки;
тіло відповіді.
Приклад:
HTTP/1.1 200 OK
Content-Type: application/json
{"id":42,"name":"Oksana"}Статусний код 200 означає, що запит успішно оброблено.
Поширені статусні коди:
200 OK — запит виконано успішно;
201 Created — ресурс створено;
400 Bad Request — запит містить некоректні дані;
401 Unauthorized — потрібна автентифікація;
403 Forbidden — доступ заборонено;
404 Not Found — ресурс не знайдено;
500 Internal Server Error — помилка на сервері.
HTTP-метод описує намір клієнта.
GETОтримання даних:
GET /productsPOSTСтворення нового ресурсу або виконання операції з переданими даними:
POST /productsPUTПовна заміна наявного ресурсу:
PUT /products/10PATCHЧасткова зміна ресурсу:
PATCH /products/10DELETEВидалення ресурсу:
DELETE /products/10Вибір методу допомагає серверу зрозуміти, яку операцію потрібно виконати.
Нижче сервер обробляє два маршрути:
GET / повертає текстове повідомлення;
GET /api/products повертає список товарів у форматі JSON.
Після запуску сервер також виконує запит до самого себе. Це показує взаємодію клієнта і сервера в одному файлі.
const http = require("node:http");
const server = http.createServer((request, response) => {
if (request.method === "GET" && request.url === "/") {
response.writeHead(200, {
"Content-Type": "text/plain; charset=utf-8"
});
response.end("Вітаємо на сервері!");
return;
}
if (request.method === "GET" && request.url === "/api/products") {
const products = [
{ id: 1, name: "Ноутбук", price: 42000 },
{ id: 2, name: "Клавіатура", price: 2500 }
];
response.writeHead(200, {
"Content-Type": "application/json; charset=utf-8"
});
response.end(JSON.stringify(products));
return;
}
response.writeHead(404, {
"Content-Type": "text/plain; charset=utf-8"
});
response.end("Маршрут не знайдено");
});
server.listen(3000, "127.0.0.1", () => {
console.log("Сервер запущено на http://127.0.0.1:3000");
// Цей HTTP-запит імітує роботу клієнта
http.get("http://127.0.0.1:3000/api/products", (response) => {
let body = "";
response.setEncoding("utf8");
response.on("data", (chunk) => {
body += chunk;
});
response.on("end", () => {
console.log("Статус відповіді:", response.statusCode);
console.log("Дані від сервера:", body);
server.close();
});
});
});Щоб запустити приклад:
Збережіть код у файл server.js.
Переконайтеся, що встановлено Node.js.
Виконайте команду:
node server.jsОчікуваний результат:
Сервер запущено на http://127.0.0.1:3000
Статус відповіді: 200
Дані від сервера: [{"id":1,"name":"Ноутбук","price":42000},{"id":2,"name":"Клавіатура","price":2500}]У цьому прикладі:
http.createServer створює сервер;
request містить дані запиту клієнта;
response використовується для формування відповіді;
request.method містить HTTP-метод;
request.url містить шлях запиту;
response.writeHead встановлює статус і заголовки;
response.end завершує та надсилає відповідь;
http.get виконує запит як клієнт.
Клієнт і сервер можуть обмінюватися даними, але кожен із них має власну відповідальність.
Клієнт може перевірити дані для зручності користувача. Наприклад, показати повідомлення, якщо поле електронної пошти порожнє.
Однак сервер також повинен перевірити ці дані перед обробкою. Перевірка на клієнті не є захистом, адже запит можна надіслати без браузера або змінити вручну.
Сервер повинен самостійно перевіряти:
наявність обов’язкових полів;
типи та формат даних;
права доступу;
допустимість операції.
Основна логіка та дані можуть зберігатися на сервері. Кілька різних клієнтів використовують один і той самий сервер.
Наприклад, вебзастосунок і мобільний застосунок можуть працювати з одним API.
Сервер може обслуговувати різні типи клієнтів:
браузер;
мобільний застосунок;
інший програмний сервіс.
Клієнтам потрібно лише дотримуватися узгодженого формату запитів і відповідей.
Якщо бізнес-правила реалізовані на сервері, їх можна змінити в одному місці. Клієнтам не завжди потрібно перевипускати нову версію програми.
Клієнт залежить від доступності сервера та мережі. Якщо сервер недоступний, клієнт може не отримати потрібні дані.
Також сервер має обробляти багато запитів, тому важливі:
коректна обробка помилок;
перевірка вхідних даних;
контроль доступу;
передбачуваний формат відповідей.
На цьому рівні достатньо запам’ятати основний принцип: клієнт просить, сервер обробляє запит і повертає результат.
Клієнтські перевірки покращують взаємодію з користувачем, але не замінюють серверну перевірку.
200Якщо ресурс не знайдено або дані некоректні, потрібно використовувати відповідний статусний код, наприклад 404 або 400. Статус допомагає клієнту зрозуміти результат без аналізу тексту відповіді.
Якщо клієнт очікує JSON, а сервер повертає довільний текст, обмін даними може завершитися помилкою. Формат відповіді потрібно узгодити.
Критичні правила, перевірки доступу та операції з важливими даними повинні контролюватися сервером.
Запит може не завершитися через недоступність сервера або проблеми з мережею. Клієнт має бути готовим обробити таку ситуацію та показати зрозуміле повідомлення.
Клієнт–серверна архітектура розділяє систему на клієнта і сервер.
Клієнт надсилає запити та показує результати.
Сервер обробляє запити, виконує бізнес-логіку та повертає відповіді.
HTTP-запит складається з методу, шляху, заголовків і, за потреби, тіла.
HTTP-відповідь містить статус, заголовки та, за потреби, тіло.
Статусні коди повідомляють клієнту про результат операції.
Дані та права доступу потрібно перевіряти на сервері.
Один сервер може обслуговувати багато різних клієнтів.