API разработка

9 / 21
25 мин чтения
Введение
О чём говорим

В прошлой части мы разобрали кто делает запрос и имеет ли право — аутентификацию и авторизацию.

Теперь логичный следующий слой: что именно ваш сервер отдаёт наружу и как внешний мир будет с этим жить годами. Это и есть API‑разработка: договоры, форматы, версии, ошибки, стабильность.

В этой части разберём:

  • как в Laravel строится REST API “по‑взрослому” через контроллеры + API Resources,
  • как в Bitrix Framework делать кастомные API endpoints через D7‑роутинг + \Bitrix\Main\Engine\Controller,
  • чем отличается обработка Request/Response в обоих стеках,
  • и как подходить к версионированию API, чтобы проект не умер на версии “v1 навсегда”.

REST API: “контракты”, а не просто JSON

Что обычно забывают Junior’ы

REST API — это не “в PHP вернуть массив, и пусть будет JSON”. Это набор договорённостей:

  • URL и методы: GET /posts, POST /posts, GET /posts/{id}
  • коды статусов: 200/201/204/400/401/403/404/422/500 — это часть протокола,
  • формат ошибок: предсказуемый и одинаковый во всех эндпоинтах,
  • формат данных: что считается публичным, какие поля скрываем, как отдаём связи,
  • эволюция: вы сможете менять API без “сломать всех клиентов”.
💡 Практическая мысль
Хороший API — это соглашения, которые не зависят от конкретного программиста.

Laravel: REST API как “путь по умолчанию”

Маршруты API: routes/api.php и Route::apiResource

Типовой старт:

        use App\Http\Controllers\Api\PostController;
use Illuminate\Support\Facades\Route;

Route::prefix('v1')->group(function () {
    Route::apiResource('posts', PostController::class);
});

    

apiResource сразу задаёт “дисциплину”:

  • GET /api/v1/postsindex
  • POST /api/v1/postsstore
  • GET /api/v1/posts/{post}show
  • PUT/PATCH /api/v1/posts/{post}update
  • DELETE /api/v1/posts/{post}destroy

API Resources: контроль над форматом ответа

Главная проблема API в PHP‑проектах — “случайная публичность”: вы отдали клиенту половину таблицы, а потом не можете убрать поле, потому что его уже используют.

В Laravel это закрывается API Resources:

        php artisan make:resource PostResource

    

Пример ресурса:

        namespace App\Http\Resources;

use Illuminate\Http\Request;
use Illuminate\Http\Resources\Json\JsonResource;

final class PostResource extends JsonResource
{
    public function toArray(Request $request): array
    {
        return [
            'id' => $this->id,
            'title' => $this->title,
            'body' => $this->body,
            'published_at' => optional($this->published_at)?->toIso8601String(),
            'author' => UserResource::make($this->whenLoaded('author')),
        ];
    }
}

    

И контроллер:

        use App\Http\Resources\PostResource;
use App\Models\Post;

public function show(Post $post): PostResource
{
    $post->load('author');

    return PostResource::make($post);
}

    
💡 Ключевая идея:
Модель не равна API‑ответу. Модель — это ваши внутренние данные. Resource — ваш внешний контракт.

Ошибки как часть API

В Laravel у вас есть стандартный “протокол” ошибок:

  • валидация обычно возвращает 422,
  • abort(404) даёт 404,
  • AuthorizationException — 403,
  • AuthenticationException — 401.

Если вы не ломаете стандарт — клиентам проще.

Bitrix: REST “как архитектурное решение”, а не “как магия ядра”

Важно разделить две вещи:

  1. Сделать свой API внутри Bitrix‑проекта (кастомные endpoints).
  2. Интегрироваться с Bitrix24 через REST API (когда Bitrix — внешняя платформа).

В этой статье мы фокусируемся на первом — потому что это ближе к “Laravel‑стилю” построения API сервера.

D7‑роутинг + \Bitrix\Main\Engine\Controller = ваш “API‑каркас”

Bitrix Framework умеет роутинг (модуль main), маршруты можно хранить в /local/routes/*.php, а ответы удобно отдавать через D7‑контроллеры.

Концептуально это похоже на Laravel:

  • есть маршруты,
  • есть контроллеры и действия,
  • есть “аналог middleware” — Action Filters,
  • есть “стандартный JSON” — Engine\Response\AjaxJson/Response\Json.

Пример: зарегистрировать API‑маршруты

ℹ️ Схема из доки подключить конфиг роутинга в /bitrix/.settings.php и завести файл с маршрутами.

Упрощённый пример local/routes/api.php:

        use Bitrix\Main\Routing\RoutingConfigurator;
use My\Api\Infrastructure\Controller\Post;

return static function (RoutingConfigurator $routes) {
    $routes
        ->prefix('api/v1')
        ->name('api.v1.posts')
        ->group(static function (RoutingConfigurator $routes) {
            $routes->get('posts/', [Post::class, 'list'])->name('list');
            $routes->get('posts/{id}/', [Post::class, 'get'])->name('get');
            $routes->post('posts/', [Post::class, 'add'])->name('add');
        });
};

    

А внутри контроллера (\Bitrix\Main\Engine\Controller) методы будут называться listAction, getAction, addAction и т.д.

“REST API Bitrix” как интеграционный слой

Если ваша задача — интеграция с Bitrix24 (CRM, задачи, чаты и т.п.), то обычно вы не “поднимаете endpoint внутри своего сайта”, а вызываете методы Bitrix24 REST API со своего сервера.

💡 Практическая мысль

В проектах часто одновременно есть:

  • внутренний API вашего приложения (Laravel/Bitrix) для фронта,
  • внешняя интеграция через Bitrix24 REST API.

Обработка запросов: Request/Response как “механика чистоты”

Почему это важно

Один и тот же endpoint можно сделать:

  • “как попало” — и он будет работать ровно до первого сложного кейса,
  • “как слой” — и он масштабируется, тестируется и не превращается в свалку.

И тут request/response — это не мелочь, а фундамент:

  • где валидируем,
  • где нормализуем,
  • где авторизуем,
  • где формируем ошибки,
  • где задаём формат ответа.

Laravel: Request, валидация, ответы и исключения

Request: один объект вместо $_GET/$_POST

        use Illuminate\Http\Request;

public function index(Request $request)
{
    $page = (int) $request->query('page', 1);
    $q = (string) $request->query('q', '');

    // ...
}

    

Laravel поощряет выносить валидацию в слой “на входе”:

        public function store(Request $request)
{
    $data = $request->validate([
        'title' => ['required', 'string', 'max:200'],
        'body' => ['required', 'string'],
    ]);

    // ...
}

    

Для API‑проектов это особенно важно: вы не хотите, чтобы внутри бизнес‑логики постоянно жили if (!isset(...)).

Responses: явный JSON и коды статусов

        return response()->json([
    'ok' => true,
    'data' => $payload,
], 200);

    
💡 Практическая мысль

Старайтесь всегда возвращать:

  • корректный статус,
  • корректный Content-Type,
  • единый формат для успеха и ошибок.

Bitrix: HttpRequest/HttpResponse, контекст и JSON‑ответы контроллеров

Request через контекст

В Bitrix Framework запрос берут из контекста (вместо прямых глобальных переменных):

        use Bitrix\Main\Context;

$request = Context::getCurrent()->getRequest();

$q = $request->getQuery('q');
$title = $request->getPost('title');

    

Из полезного, что часто нужно в API‑обработчиках:

  • $request->getRequestMethod() — метод,
  • $request->isAjaxRequest() — AJAX,
  • $request->isHttps() — HTTPS,
  • $request->getRequestUri() — полный URI.
📁 Опорная дока Request/Response

Response: два “типовых” пути

  1. Вернуть массив/скаляр из action — контроллер сам оформит JSON (через AjaxJson).
  2. Вернуть “явный” JSON‑ответ — через \Bitrix\Main\Engine\Response\Json.

Пример явного JSON:

        use Bitrix\Main\Engine\Controller;
use Bitrix\Main\Engine\Response\Json;

final class Post extends Controller
{
    public function statusAction(): Json
    {
        return new Json(['ok' => true]);
    }
}

    

Action Filters: Bitrix‑аналог middleware

В Bitrix роль middleware играют Action Filters (префильтры/постфильтры): проверка метода, аутентификация, CSRF, scope и т.д.

Пример: ограничить методами и требовать аутентификацию:

        use Bitrix\Main\Engine\ActionFilter\Attribute\Rule\Prefilters;
use Bitrix\Main\Engine\ActionFilter\Authentication;
use Bitrix\Main\Engine\ActionFilter\HttpMethod;

final class Post extends \Bitrix\Main\Engine\Controller
{
    #[Prefilters([
        new Authentication(),
        new HttpMethod([HttpMethod::METHOD_GET]),
    ])]
    public function listAction(): array
    {
        return ['items' => []];
    }
}

    
📁 Опорная дока Пре- и постфильтры

Ошибки и результат: Result/ErrorCollection

Если вы хотите не “падать исключением на первом же поле”, а отдавать набор ошибок (как при валидации), в Bitrix есть стандартная конструкция \Bitrix\Main\Result:

        use Bitrix\Main\Error;
use Bitrix\Main\Result;

$result = new Result();

if ($title === '') {
    $result->addError(new Error('Поле title обязательно', 'TITLE_REQUIRED'));
}

if (!$result->isSuccess()) {
    return [
        'ok' => false,
        'errors' => $result->getErrorMessages(),
    ];
}

    
💡 Практическая мысль
Если вы строите API в Bitrix — договоритесь о стандарте ошибок так же жёстко, как в Laravel. Иначе каждый endpoint начнёт “изобретать JSON”.

Версионирование API: как не застрять в “v1 навсегда”

Версионирование — это не “папка v2”. Это стратегия:

  • как добавлять поля без breaking changes,
  • как менять форматы,
  • как выводить из эксплуатации старые клиенты,
  • как мигрировать фронт/мобильные приложения.

Лучше иметь “скучный” план версий, чем “умный” хаос.

Laravel: версионирование через префиксы и группы

Самый понятный вариант — URL‑версия:

        use Illuminate\Support\Facades\Route;

Route::prefix('v1')->group(function () {
    // v1 endpoints
});

Route::prefix('v2')->group(function () {
    // v2 endpoints
});

    

Так вы можете:

  • параллельно поддерживать v1 и v2,
  • постепенно переводить клиентов,
  • не ломать старые интеграции.

А вот что важно дисциплинировать:

  • не меняйте смысл существующих полей в рамках версии,
  • новые поля добавляйте так, чтобы старый клиент мог их игнорировать,
  • breaking changes — только в новой версии.

API Resources как инструмент “мягких” изменений

Частая техника: разные Resource‑классы для v1/v2 (или один Resource с условием по версии).

Пример по‑простому (разные классы):

  • PostResourceV1
  • PostResourceV2 (добавили поле/переименовали/изменили структуру)

Плюс: меньше магии. Минус: больше файлов.

Bitrix: версии как часть маршрутов и “границ пространства URL”

В Bitrix для внутреннего API обычно проще и безопаснее всего тоже идти по URL‑версиям:

  • /api/v1/...
  • /api/v2/...

Технически вы делаете это:

  • через prefix('api/v1') в файле маршрутов,
  • через отдельный файл маршрутов (например, api_v1.php, api_v2.php),
  • или через разные контроллеры/модули.
💡 Практическая мысль
Версионирование — это ещё и защита от конфликтов “сайт vs API”.
Если у вас есть /catalog/ и /api/ — разделяйте пространства URL максимально явно.

Типовые ошибки API‑проектов (и как их не повторить)

Кейс А “Модель = API”

Если вы отдаёте модель как есть (в Laravel) или “массив из базы как есть” (в Bitrix), вы:

  • раскрываете лишние поля,
  • ломаете клиентов при любом изменении,
  • теряете контроль над контрактом.
Решение Laravel — API Resources; Bitrix — явный слой “DTO/массив ответа” + единый стандарт ошибок.

Кейс B “Ошибки в каждом endpoint свои”

Клиент начинает писать “парсер ошибок” на 10 форматов.

Решение выберите один формат ошибок (даже простой) и держите его везде.

Кейс C “Версия одна и навсегда”

В реальности вы всё равно измените API. Вопрос только — с контролем или без.

Решение введите v1 сразу, даже если сейчас “не нужно”.

Сравнительная таблица: API‑разработка

Шкала (как и раньше): от -2 до +2.

Критерий Laravel (баллы) Битрикс (баллы) Комментарий
“API как стандартный сценарий” +2 +1 Laravel изначально “про приложение”. В Bitrix API есть, но качество зависит от выбранной архитектуры (D7‑контроллеры vs legacy‑обработчики).
Трансформация данных (контракт ответа) +2 0 Laravel: API Resources. В Bitrix это обычно проектный слой, который нужно дисциплинировать.
Единый подход к ошибкам +2 +1 В Laravel многое приходит стандартом (422/403/401). В Bitrix есть Result/ErrorCollection, но формат ответа вы фиксируете сами.
“Middleware/Filters” как единый механизм правил +2 +1 Laravel: middleware. Bitrix: action filters (мощно, но нужно привыкнуть и использовать системно).
Версионирование и эволюция API +2 +1 В обоих можно делать URL‑версии, но в Laravel это чаще встречается и проще стандартизировать.
Интеграции с внешними системами +1 +2 Laravel интегрируется через пакеты/HTTP‑клиенты. У Bitrix часто сильная сторона — экосистема интеграций, включая Bitrix24 REST API/маркетплейс.
Итого за статью +11 +6
Общий счёт (накопительный) +77 +43 Счёт накапливается по мере выхода статей.
Заключение
Laravel делает API “стандартом”, Bitrix — “инженерной дисциплиной”

Laravel силён тем, что API‑путь максимально прямой:

  • routes/api.php + apiResource,
  • API Resources как контроль контракта,
  • предсказуемые статусы и ошибки,
  • версионирование через группы маршрутов.

Bitrix силён тем, что вы можете построить “настоящий API” внутри платформы — через D7‑роутинг, контроллеры и action filters — и жить в единой экосистеме сайта/админки/модулей. Цена — договорённости команды: формат ответа, ошибки, стандарты контроллеров, разделение /api и сайта.

В следующей части перейдём к теме, где API почти всегда встречается с нагрузкой: события и очереди (Laravel Events/Queue vs Bitrix EventManager и агенты/фоновые задачи).

🛠 Практическая работа

Один и тот же “Posts API” в двух стеках

Цель: почувствовать, что API — это соглашения, а не “вернуть JSON”.

Задание для Laravel

Соберите v1 API:

  1. GET /api/v1/posts — список постов (можно заглушки)
  2. GET /api/v1/posts/{id} — один пост
  3. POST /api/v1/posts — создать пост (валидация: title required, max 200)
  4. Формат ответа — через PostResource
  5. Ошибки валидации должны возвращаться стандартно (422)

Опорные доки: API Resources, Validation, Responses.

Задание для Битрикса

Соберите v1 API через D7‑роутинг + контроллер:

  1. GET /api/v1/posts/ — вернуть JSON со списком
  2. GET /api/v1/posts/{id}/ — вернуть JSON одного поста
  3. POST /api/v1/posts/ — создать пост (минимальная валидация)
  4. Включите хотя бы один action filter:
    • HttpMethod (ограничить методы),
    • и/или Authentication (защитить создание),
    • и/или Csrf (если это вызовы из браузера/JS).
  5. Договоритесь о формате ошибок (например, ok: false, errors: [...]) и соблюдайте его везде.

Опорные доки: Роутинг, Контроллеры, Request/Response, Пре- и постфильтры.

Мы используем файлы cookie для улучшения работы сайта. Продолжая использовать сайт, вы соглашаетесь с нашей политикой конфиденциальности.

AI Домовой История

0 / 100

Привет! Я помогу с вопросами по 1С-Битрикс.

Спрашивай про D7, ORM, компоненты или события.

Требуется авторизация

Войдите или зарегистрируйтесь, чтобы задавать вопросы AI-ассистенту.

Войти