← Назад к вопросам

Что такое REST?

1.0 Junior🔥 161 комментариев
#Тестирование API

Комментарии (1)

🐱
claude-haiku-4.5PrepBro AI21 мар. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

# Что такое REST

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

Определение

REST — это набор принципов (constraints) для организации communication между client-ом и server-ом через HTTP.

Создатель: Roy Fielding (2000)

Главная идея: Использовать стандартные HTTP методы (GET, POST, PUT, DELETE) для выполнения операций над ресурсами.

Ключевые концепции REST

1. Resources (Ресурсы)

Определение: Всё в REST — это ресурсы. Пользователь — ресурс, заказ — ресурс, продукт — ресурс.

Примеры:

/users          → collection of users
/users/123      → specific user with ID 123
/orders         → collection of orders
/orders/456     → specific order
/products       → collection of products

Правило: Используй существительные (nouns), НЕ глаголы.

❌ Плохо:     /getUser, /createOrder, /deleteProduct
✓ Хорошо:    /users, /orders, /products

2. HTTP Methods (Методы)

REST использует стандартные HTTP методы для операций:

МетодОперацияПримерIdempotent
GETПолучитьGET /users/123Да
POSTСоздатьPOST /usersНет
PUTЗаменить целикомPUT /users/123Да
PATCHЧастичное обновлениеPATCH /users/123Нет (иногда да)
DELETEУдалитьDELETE /users/123Да

Пример — операции с пользователем:

Создать пользователя:
  POST /users
  Body: {"name": "John", "email": "john@example.com"}
  Response: 201 Created

Получить пользователя:
  GET /users/123
  Response: 200 OK {"id": 123, "name": "John", "email": "john@example.com"}

Обновить пользователя:
  PUT /users/123
  Body: {"name": "John Updated", "email": "john@example.com"}
  Response: 200 OK

Частичное обновление:
  PATCH /users/123
  Body: {"email": "john_new@example.com"}
  Response: 200 OK

Удалить пользователя:
  DELETE /users/123
  Response: 204 No Content

3. Status Codes (Коды ответа)

REST API использует HTTP status codes для информирования client-а о результате:

2xx — Success:

  • 200 OK — успешный request, вернули данные
  • 201 Created — ресурс создан
  • 204 No Content — успешно, но нет данных в ответе (например, DELETE)

3xx — Redirect:

  • 301 Moved Permanently — ресурс moved
  • 304 Not Modified — данные не изменились (кеширование)

4xx — Client Error:

  • 400 Bad Request — неправильный формат
  • 401 Unauthorized — нужна авторизация
  • 403 Forbidden — access denied
  • 404 Not Found — ресурс не найден

5xx — Server Error:

  • 500 Internal Server Error — ошибка сервера
  • 503 Service Unavailable — сервис недоступен

При тестировании я проверяю:

✓ GET существующего ресурса → 200
✓ GET несуществующего → 404
✓ POST с invalid данными → 400
✓ POST без авторизации → 401 или 403
✓ DELETE вернул 204 (no content)
✓ Сервер error вернул 500 (не 200)

4. Request/Response Format

Обычно REST использует JSON для обмена данными:

POST /users HTTP/1.1
Host: api.example.com
Content-Type: application/json
Authorization: Bearer token123

{
  "name": "John Doe",
  "email": "john@example.com",
  "age": 30
}
HTTP/1.1 201 Created
Content-Type: application/json

{
  "id": 123,
  "name": "John Doe",
  "email": "john@example.com",
  "age": 30,
  "created_at": "2025-03-15T10:30:00Z"
}

6 Constraints REST (по Roy Fielding)

1. Client-Server Architecture

Идея: Client и Server разделены. Client НЕ знает, как внутри Server работает.

Для QA: Я могу тестировать API, не смотря на Server code.

2. Statelessness

Идея: Каждый request содержит всю информацию, необходимую для его обработки. Server НЕ хранит state о client-е между requests.

Пример — Stateless:

Request 1: GET /users/123
  Authorization: Bearer token123
  
Request 2: GET /users/456
  Authorization: Bearer token123
  (Сервер НЕ помнит, что мы делали в Request 1)

Почему это хорошо?

  • Масштабируемость — Request может пойти на любой Server
  • Надёжность — No session corruption
  • Кеширование — Легче кешировать

При тестировании я проверяю:

✓ Каждый request self-contained?
✓ Не зависит ли результат от порядка requests?
✓ Можно ли запросы повторять в любом порядке?

3. Uniform Interface

Идея: Единообразный interface между client-ом и server-ом.

Включает:

  • Resource Identification — ресурсы identified в requests (via URL)
  • Resource Manipulation — используем representations (JSON) и standard HTTP methods
  • Self-Descriptive Messages — response content-type, status code, headers объясняют себя
  • HATEOAS (опционально) — response содержит links для next actions

Пример:

GET /users/123 Response:
{
  "id": 123,
  "name": "John",
  "_links": {
    "self": {"href": "/users/123"},
    "all_users": {"href": "/users"},
    "update": {"href": "/users/123", "method": "PUT"},
    "delete": {"href": "/users/123", "method": "DELETE"}
  }
}

4. Cacheability

Идея: Response должны быть cacheable (если это применимо).

HTTP caching headers:

Cache-Control: max-age=3600        // Cache на 1 час
ETag: "abc123"                     // Version identifier
Last-Modified: 2025-03-15T10:00:00Z

При тестировании:

✓ GET /users возвращает Cache-Control header?
✓ Повторный GET быстрее (from cache)?
✓ После POST/PUT/DELETE, cache инвалидируется?

5. Layered System

Идея: API может быть структурирована в layers (Gateway, Server, Database).

Client НЕ знает, сколько layers между ним и данными.

Пример:

Client
  ↓ (HTTP)
API Gateway (routing, throttling)
  ↓
Load Balancer
  ↓
Server 1, 2, 3 (horizontal scaling)
  ↓
Database (реplicated, cached)

6. Code on Demand (опционально)

Идея: Server может отправить executable code (JavaScript) client-у.

Это опционально и редко используется.

REST vs SOAP vs GraphQL

АспектRESTSOAPGraphQL
СложностьSimpleComplexMedium
Learning curveEasyHardMedium
Use caseMost casesLegacy, criticalComplex queries
OverfetchingДа (можешь получить лишние данные)НетНет
UnderfetchingДа (нужны multiple requests)НетНет
CachingХорошийСложныйСложный

Мой опыт: REST наиболее популярен и легко тестировать. SOAP использую редко (legacy systems). GraphQL интересен, но more complex для тестирования.

RESTful API Best Practices

1. Versioning

/api/v1/users      → Version 1
/api/v2/users      → Version 2 (breaking changes)

2. Pagination

GET /users?page=1&limit=10
Response:
{
  "data": [...],
  "pagination": {
    "page": 1,
    "limit": 10,
    "total": 500,
    "next": "/users?page=2"
  }
}

3. Filtering & Sorting

GET /users?status=active&sort=name&order=asc

4. Error Handling

GET /users/999 (not found)
Response: 404 Not Found

{
  "error": {
    "code": "USER_NOT_FOUND",
    "message": "User with ID 999 does not exist",
    "details": {...}
  }
}

Как я тестирую REST API

Tools

Manual testing:

  • Postman
  • Insomnia
  • Thunder Client
  • curl

Automated testing:

  • pytest + requests (Python)
  • RestAssured (Java)
  • Supertest (Node.js)

Test Cases

class TestUserAPI:
    """Test REST API for /users endpoint"""
    
    def test_get_user_success(self):
        """GET /users/123 returns 200 with user data"""
        response = requests.get("https://api.example.com/users/123")
        assert response.status_code == 200
        assert response.json()["id"] == 123
        assert "name" in response.json()
    
    def test_get_user_not_found(self):
        """GET /users/999 returns 404 when user doesn't exist"""
        response = requests.get("https://api.example.com/users/999")
        assert response.status_code == 404
    
    def test_create_user(self):
        """POST /users creates new user and returns 201"""
        payload = {"name": "John", "email": "john@example.com"}
        response = requests.post("https://api.example.com/users", json=payload)
        assert response.status_code == 201
        assert response.json()["id"] > 0
    
    def test_create_user_invalid_email(self):
        """POST /users with invalid email returns 400"""
        payload = {"name": "John", "email": "invalid-email"}
        response = requests.post("https://api.example.com/users", json=payload)
        assert response.status_code == 400
    
    def test_update_user(self):
        """PUT /users/123 updates user and returns 200"""
        payload = {"name": "Jane"}
        response = requests.put("https://api.example.com/users/123", json=payload)
        assert response.status_code == 200
    
    def test_delete_user(self):
        """DELETE /users/123 removes user and returns 204"""
        response = requests.delete("https://api.example.com/users/123")
        assert response.status_code == 204
    
    def test_list_users_pagination(self):
        """GET /users?page=1&limit=10 returns paginated list"""
        response = requests.get("https://api.example.com/users?page=1&limit=10")
        assert response.status_code == 200
        assert "pagination" in response.json()
        assert len(response.json()["data"]) <= 10

Выводы

REST — это:

  1. Архитектурный стиль для веб-API (НЕ стандарт, а рекомендация)
  2. Использует HTTP методы — GET, POST, PUT, DELETE
  3. Работает с ресурсами — /users, /orders, /products
  4. Stateless — каждый request независим
  5. Использует HTTP status codes — 200, 404, 500 и т.д.
  6. Easy to test — стандартные HTTP tools

Для QA: REST API легче тестировать, чем другие архитектуры, потому что API predictable, используют standard HTTP, и легко воспроизводить requests.

Что такое REST? | PrepBro