Документуючи кінцеві точки свого API, ви можете уявити, що завдання розділяється на дві частини: документування запитів (аутентифікація, тіло запиту, параметри запиту) та документування відповідей. У цьому посібнику ми детально розглянемо документацію запитів.
Основна мета Scramble — генерувати максимально можливу документацію API без потреби вручну прописувати анотації. Створення PHPDoc з усіма параметрами та тілом запиту є трудомістким і схильним до помилок процесом. Якщо деталі запиту змінюються, вам потрібно оновити PHPDoc, і з часом одна з правок може бути пропущена, призводячи до застарілої документації API.
Як не дивно, у коді вже міститься багато інформації про запити API! Правила валідації, параметри шляху маршруту та виклики методів на $request
— усі ці дані описують запити кінцевих точок API.
Scramble використовує цю інформацію для автоматичного створення базової документації запитів, яка описує типи даних, які можна надіслати до API.
Коли застосовується зв'язування моделей, Scramble документує параметри шляху відповідно до типу ключа моделі. Як і слід було очікувати, цілі числові ключі документуються як цілі, а
uuid
ключі — як рядки формату uuid
:
Окрім структури запиту та параметрів, які створює Scramble, ви можете додавати описи, приклади та значення за замовчуванням. Ви також можете вказати інші параметри, якщо Scramble щось пропустив, або змінити тип параметра.
Найпростіший спосіб зробити це — використовувати атрибути:
#[BodyParameter('name', 'Назва компанії')]
public function store(Request $request)
{
$request->validate([
'name' => ['required', 'string'],
]);
...
}
Також можна додавати описи до параметрів, використовуючи коментарі PHPDoc до правил.
public function store(Request $request)
{
$request->validate([
// Назва компанії.
'name' => ['required', 'string'],
]);
...
}
Scramble охоплює більшість випадків, використовуючи вихідний код для документації API запитів. Проте він не автоматично документує заголовки запитів або куки.
Це можна зробити, використовуючи атрибути. Наприклад, якщо ви отримуєте значення заголовка у контролері так:
$request->header('X-Header-Name');
Це можна задокументувати за допомогою атрибута #[HeaderParameter]
:
#[HeaderParameter('X-Header-Name', 'Назва заголовка.', type: 'string')]
Якщо ви хочете задокументувати куки, використайте атрибут #[CookieParameter]
.
$value = $request->cookie('name');
Документуйте його так:
#[CookieParameter('name', 'Кука.', type: 'string')]
З використанням #[PathParameter]
, #[QueryParameter]
та #[BodyParameter]
ви також можете задокументувати відповідні параметри запиту.
Щоб документувати параметри запиту, надіслані до API у рядку запиту, наприклад, /api/books?page=1
, використовуйте атрибут #[QueryParameter]
:
#[QueryParameter('page', 'Номер сторінки.', type: 'int')]
За допомогою #[PathParameter]
ви можете задокументувати параметри шляху, які входять до маршруту. Наприклад, у маршруті GET /api/book/{book}
є параметр шляху book
.
#[PathParameter('book', 'Книга, яку потрібно відобразити')]
Щоб додати параметр тіла запиту, використовуйте атрибут #[BodyParameter]
.
#[BodyParameter('project_id', type: 'int')]
Ви навіть можете використовувати крапки, як це робите у валідаційних правилах, щоб створити складні структури:
#[BodyParameter('projects.*.id', 'ID проекту', type: 'int')]
#[BodyParameter('projects.*.name', 'Назва проекту', type: 'string')]
За замовчуванням атрибути "додають" інформацію до параметрів, які автоматично виводяться з кодової бази. Щоб проігнорувати автоматично виведену інформацію про параметри, передайте infer: false
до атрибута. Це зберігатиме лише вручну надану інформацію про параметри:
#[QueryParameter('page', 'Номер сторінки.', type: 'int', infer: false)]
Часто заголовки та куки отримуються в посередниках, завдяки чому вони можуть застосовуватися до всіх кінцевих точок. Scramble надає вам повний контроль над документом OpenAPI, використовуючи трансформери.
Трансформери операцій дозволяють додавати додаткову документацію до всіх кінцевих точок. Ви також можете перевірити посередник та застосувати документацію, якщо на маршруті існує конкретний посередник.
Розглянемо цей приклад. У нас є глобальний посередник, який реєструє ID запиту, взятий з заголовків. Цей посередник запускається при кожному запиті до API, тому ми хочемо задокументувати його для всіх маршрутів.
<?php
namespace App\Http\Middleware;
use Closure;
use Illuminate\Http\Request;
use Symfony\Component\HttpFoundation\Response;
class LogRequestId
{
public function handle(Request $request, Closure $next): Response
{
if ($id = $request->header('X-Request-ID')) {
info("ID запиту: $id (url: {$request->url()}");
}
return $next($request);
}
}
Тепер ми можемо додати цей заголовок до всіх маршрутів, використовуючи трансформер операцій у методі boot
сервісного провайдера:
public function boot(): void
{
Scramble::configure()
->withOperationTransformers(function (Operation $operation) {
$operation->parameters[] = (new Parameter('X-Request-ID', 'header'))
->description('ID запиту для кращої видимості запиту.')
->setSchema(Schema::fromType(new StringType));
});
}
Тепер заголовок X-Request-ID
додано до всіх API маршрутів.
Щоб надати більше контексту для кінцевої точки, ви можете додати заголовок та опис до її документації. Це можна зробити просто, додавши коментар PHPDoc. Перший рядок вважається заголовком кінцевої точки, а наступні рядки — описом. Ви можете використовувати форматування Markdown CommonMark для опису.
Якщо ваш API вимагає аутентифікації, ви можете задокументувати це, використовуючи трансформер документації та вказавши стандартний механізм аутентифікації вашого API.
Трансформери документації визначаються у методі boot
сервісного провайдера:
public function boot()
{
Scramble::configure()
->withDocumentTransformers(function (OpenApi $openApi) {
$openApi->secure(
SecurityScheme::http('bearer')
);
});
}
Якщо кінцева точка є публічною (наприклад, реєстрація користувача), ви можете позначити цю кінцеву точку як таку, що не вимагає аутентифікації:
/**
* @unauthenticated
*/
public function store(Request $request)
{
...
}
Використовуючи трансформери операцій, ви навіть можете перевірити посередник на маршруті та автоматично прибрати вимогу аутентифікації для кінцевих точок, які не мають посередника auth
:
public function boot()
{
Scramble::configure()
->withOperationTransformers(function (Operation $operation, RouteInfo $routeInfo) {
$routeMiddleware = $routeInfo->route->gatherMiddleware();
$hasAuthMiddleware = collect($routeMiddleware)->contains(
fn ($m) => Str::startsWith($m, 'auth:')
);
if (! $hasAuthMiddleware) {
$operation->security = [];
}
})
}
Щоб згрупувати кінцеві точки, ви можете використовувати атрибут #[Group]
на контролері (який згрупує всі кінцеві точки цього контролера) та на методі контролера.
#[Group('API компаній')]
class CompaniesController {...}
Ви можете сортувати групи, надавши аргумент weight
атрибуту #[Group]
:
#[Group('API доменів', weight: 2)]
class DomainsController {...}
Використовуючи Scramble, ви можете генерувати актуальну документацію API, ґрунтуючись на вашому вихідному коді. Це економить час і забезпечує точність вашої документації. Крім того, ви можете покращити документацію, додавши описи параметрів, заголовки, приклади та значення за замовчуванням, що дозволить вам задокументувати всі деталі вашого API.
Спробуйте Scramble, якщо ще не робили цього: https://scramble.dedoc.co
Також ознайомтеся з демонстраційною документацією, згенерованою Scramble: https://scramble.dedoc.co/demo/scramble. Ви знайдете посилання “Перейти до GitHub” у документації, що дозволяє швидко перейти до вихідного коду, з якого була створена кожна частина документації.