REST

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]