11.01.25
REST
REST (Representational State Transfer) — это архитектурный стиль, который используется для разработки веб-сервисов. Он основывается на принципах работы HTTP и предоставляет набор ограничений и рекомендаций для создания масштабируемых и производительных API. Вот основные моменты, связанные с REST:
Основные принципы REST:
- Клиент-серверная архитектура:
- В REST-приложениях клиент и сервер разделены. Клиент отвечает за пользовательский интерфейс и взаимодействие с пользователем, а сервер — за обработку данных и бизнес-логику.
- Отсутствие состояния (Stateless):
- Каждый запрос от клиента к серверу должен содержать всю необходимую информацию для его обработки. Сервер не хранит состояние клиента между запросами, что упрощает масштабирование.
- Кэширование:
- Ответы сервера могут быть кэшированы клиентом или промежуточными серверами, что позволяет уменьшить нагрузку на сервер и ускорить время отклика.
- Единообразный интерфейс:
- REST использует стандартные HTTP-методы (GET, POST, PUT, DELETE) для выполнения операций над ресурсами. Это упрощает взаимодействие между клиентом и сервером.
- Иерархия ресурсов:
- Ресурсы (например, пользователи, товары) идентифицируются с помощью URI (Uniform Resource Identifier). Каждый ресурс может иметь свои представления (например, JSON, XML).
- Многоуровневая система:
- Архитектура может состоять из нескольких уровней, включая промежуточные серверы, которые могут выполнять функции, такие как кэширование, балансировка нагрузки и безопасность.
Рассмотрим пример простого RESTful API на PHP для управления списком задач (To-Do List).
/project
/api
/controllers
TaskController.php
/models
TaskModel.php
/config
database.php
index.php
.htaccess
1. Настройка базы данных
Создадим таблицу tasks
в базе данных.
CREATE TABLE tasks (
id INT AUTO_INCREMENT PRIMARY KEY,
title VARCHAR(255) NOT NULL,
description TEXT,
completed TINYINT(1) DEFAULT 0
);
2. Конфигурация базы данных
<?php
// api/config/database.php
$host = 'localhost';
$dbname = 'todo';
$user = 'root';
$pass = '';
try {
$db = new PDO("mysql:host=$host;dbname=$dbname", $user, $pass);
$db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
} catch (PDOException $e) {
die("Ошибка подключения к базе данных: " . $e->getMessage());
}
3. Модель (TaskModel)
Модель отвечает за взаимодействие с базой данных.
<?php
// api/models/TaskModel.php
class TaskModel {
private $db;
public function __construct($db) {
$this->db = $db;
}
// Получить все задачи
public function getAllTasks() {
$query = "SELECT * FROM tasks";
return $this->db->query($query)->fetchAll(PDO::FETCH_ASSOC);
}
// Получить задачу по ID
public function getTaskById($id) {
$query = "SELECT * FROM tasks WHERE id = :id";
$stmt = $this->db->prepare($query);
$stmt->execute(['id' => $id]);
return $stmt->fetch(PDO::FETCH_ASSOC);
}
// Создать задачу
public function createTask($data) {
$query = "INSERT INTO tasks (title, description) VALUES (:title, :description)";
$stmt = $this->db->prepare($query);
$stmt->execute($data);
return $this->db->lastInsertId();
}
// Обновить задачу
public function updateTask($id, $data) {
$query = "UPDATE tasks SET title = :title, description = :description, completed = :completed WHERE id = :id";
$stmt = $this->db->prepare($query);
$data['id'] = $id;
return $stmt->execute($data);
}
// Удалить задачу
public function deleteTask($id) {
$query = "DELETE FROM tasks WHERE id = :id";
$stmt = $this->db->prepare($query);
return $stmt->execute(['id' => $id]);
}
}
4. Контроллер (TaskController)
Контроллер обрабатывает HTTP-запросы и взаимодействует с моделью.
<?php
// api/controllers/TaskController.php
class TaskController {
private $model;
public function __construct($model) {
$this->model = $model;
}
// Получить все задачи
public function getAllTasks() {
$tasks = $this->model->getAllTasks();
echo json_encode($tasks);
}
// Получить задачу по ID
public function getTaskById($id) {
$task = $this->model->getTaskById($id);
if ($task) {
echo json_encode($task);
} else {
http_response_code(404);
echo json_encode(['message' => 'Задача не найдена']);
}
}
// Создать задачу
public function createTask() {
$data = json_decode(file_get_contents('php://input'), true);
$id = $this->model->createTask($data);
http_response_code(201);
echo json_encode(['id' => $id]);
}
// Обновить задачу
public function updateTask($id) {
$data = json_decode(file_get_contents('php://input'), true);
$result = $this->model->updateTask($id, $data);
if ($result) {
echo json_encode(['message' => 'Задача обновлена']);
} else {
http_response_code(404);
echo json_encode(['message' => 'Задача не найдена']);
}
}
// Удалить задачу
public function deleteTask($id) {
$result = $this->model->deleteTask($id);
if ($result) {
echo json_encode(['message' => 'Задача удалена']);
} else {
http_response_code(404);
echo json_encode(['message' => 'Задача не найдена']);
}
}
}
5. Точка входа (index.php)
Обрабатываем запросы и вызываем соответствующие методы контроллера.
<?php
// api/index.php
require 'config/database.php';
require 'models/TaskModel.php';
require 'controllers/TaskController.php';
header("Content-Type: application/json");
$db = new PDO("mysql:host=localhost;dbname=todo", 'root', '');
$model = new TaskModel($db);
$controller = new TaskController($model);
$requestMethod = $_SERVER['REQUEST_METHOD'];
$uri = parse_url($_SERVER['REQUEST_URI'], PHP_URL_PATH);
$uri = explode('/', $uri);
// Обработка запросов
if ($uri[1] === 'tasks') {
$id = $uri[2] ?? null;
switch ($requestMethod) {
case 'GET':
if ($id) {
$controller->getTaskById($id);
} else {
$controller->getAllTasks();
}
break;
case 'POST':
$controller->createTask();
break;
case 'PUT':
if ($id) {
$controller->updateTask($id);
}
break;
case 'DELETE':
if ($id) {
$controller->deleteTask($id);
}
break;
default:
http_response_code(405);
echo json_encode(['message' => 'Метод не поддерживается']);
break;
}
} else {
http_response_code(404);
echo json_encode(['message' => 'Ресурс не найден']);
}
6. Настройка .htaccess
Для обработки "чистых" URL (например, /tasks/1) используем .htaccess.
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ /api/index.php [QSA,L]