Swagger — это фрэймворк для описания, документирования и визуализации REST API. На основании спецификации Swagger можно генерировать исходный код для библиотек клиентских приложений, текстовую документацию для пользователей, варианты тестирования и др. Для этого имеется множество инструментов для различных языков программирования и платформ.
В данной статье мы рассмотрим, как использовать Swagger в Laravel для документирования REST API.
Установка необходимых пакетов
Мы будем использовать пакет DarkaOnLine/L5-Swagger. Он основан на 2 библиотеках: swagger-PHP, позволяющая создавать Swagger-спецификацию API с помощью аннотаций в php коде и swagger-UI, позволяющая создавать удобную документацию на основании спецификации Swagger. Для установки пакета для Laravel версии 5.7 и выше, нужно выполнить следующие команды:
composer require "darkaonline/l5-swagger:5.7.*" composer require "zircote/swagger-php:2.*"
Если вы используете другую версию Laravel, узнать подходящую вам версию пакета можно в его документации на Github.
Чтобы опубликовать файл конфигурации и шаблоны для отображения документации, нужно выполнить следующую команду:
php artisan vendor:publish --provider "L5Swagger\L5SwaggerServiceProvider"
Пример создания swagger документации
Рассмотрим возможности Swagger на примере простого API для блога. Мы создадим 2 метода, которые будут возвращать список всех постов, либо конкретный пост из блога по его id.
Для начала добавим в базовый контроллер аннотацию с описанием API. Этот элемент является обязательным:
/** * @SWG\Swagger( * schemes={"http"}, * host="localhost:8000", * basePath="/", * @SWG\Info( * title="Blog posts API", * version="1.0.0" * ) * ) */ class Controller extends BaseController {}
Здесь мы задаем название API, его версию, url и базовый путь.
Теперь создадим модель Post
и добавим аннотацию Swagger с описанием полей:
php artisan make:model Post
Аннотация модели описывает типы данных, которые может возвращать API. Здесь мы задаем название модели, список полей и их типы:
/** * @SWG\Definition( * definition="Post", * @SWG\Property( * property="id", * type="integer" * ), * @SWG\Property( * property="title", * type="string" * ), * @SWG\Property( * property="text", * type="string" * ) * ) */ class Post extends Model {}
Теперь создадим контроллер PostsController
:
php artisan make:controller PostsController --api
Ниже приведен код контроллера с аннотациями методов API:
class PostsController extends Controller { /** * @SWG\Get( * path="/posts", * summary="Get list of blog posts", * tags={"Posts"}, * @SWG\Response( * response=200, * description="successful operation", * @SWG\Schema( * type="array", * @SWG\Items(ref="#/definitions/Post") * ), * ), * @SWG\Response( * response="401", * description="Unauthorized user", * ), * ) */ public function index() {} /** * @SWG\Get( * path="/posts/{post_id}", * summary="Get blog post by id", * tags={"Posts"}, * description="Get blog post by id", * @SWG\Parameter( * name="post_id", * in="path", * description="Post id", * required=true, * type="integer", * ), * @SWG\Response( * response=200, * description="successful operation", * @SWG\Schema(ref="#/definitions/Post"), * ), * @SWG\Response( * response="401", * description="Unauthorized user", * ), * @SWG\Response( * response="404", * description="Post is not found", * ) * ) */ public function show($id) {} }
Рассмотрим типы аннотаций, использованные для описания методов и для чего они нужны:
@SWG\Get
— означает, что для доступа к методу должен использоваться http-метод GET. Существуют аналогичные аннотации для всех http-методов: @SWG\Post, @SWG\Put и другие. Здесь мы так же задаем url данного метода (атрибут path), описание, тэги, используемые для группировки методов и т.д.-
@SWG\Parameter
— используется для описания параметров метода. В нашем примере метод получения поста по id использует эту аннотацию для описания параметраpost_id
в url.in="path"
означает, что параметр используется в url. Так же можно задать тип параметра, обязателен он, или нет. @SWG\Response
— используется для описания ответа API. Атрибутresponse=200
означает http-статус ответа.@SWG\Schema
— используется для описания формата выходных данных. В коде выше видно, что для задания форматы используется ссылка на уже описанную нами ранее модель Post:@SWG\Items(ref="#/definitions/Post")
.
Т. к. в разных ситуациях ответы API могут отличаться, возможные ответы могут быть описаны с помощью нескольких таких аннотаций, перечисленных через запятую. В аннотациях выше описаны форматы ответа API для неавторизованного пользователя (response="401"
), а также когда запрашиваемый пост не найден в базе данных (response="404"
).
Генерация документации для API
Сгенерируем Swagger документацию с помощью следующей команды:
php artisan l5-swagger:generate
На момент написания статьи последняя версия библиотеки по умолчанию использует новый стандарт аннотаций OpenAPI. Если вы получили ошибку Symfony\Component\Debug\Exception\FatalThrowableError : Call to undefined function OpenApi\scan()
,
то добавьте строку SWAGGER_VERSION=2.0
в файл .env
. Полученная документация, доступна по ссылке /api/documentation. Если вы используете встроенный сервер PHP и php artisan serve, то документация откроется по ссылке: http://localhost:8000/api/documentation..
Полученная документация содержит описание всех типов данных, возвращаемых API, список доступных методов c подробным описанием:
Описание метода API содержит его url, описание всех параметров, а так же все варианты ответов. Т.к. мы ссылались на модель Post в описании ответа, мы можем видеть ссылку на эту модель и даже пример ответа API, сгенерированный на основании описания модели. Вверху имеется кнопка Try it out, позволяющая выполнить запрос API прямо со страницы документации.
Заключение
Мы рассмотрели, как создать документацию в Swagger на примере простого API на Laravel. На основе созданных аннотаций мы сгенерировали полноценную документацию. Она может быть использована как разработчиками для совместной работы над API, так и клиентами вашего API.
Более подробную информацию о Swagger вы можете найти на сайте проекта: https://swagger.io/
Зачем такой геморрой с изучением ещё одного синтаксиса нотаций и размазыванию всей документации, когда можно просто написать yaml конфиг для сваггера?
Всё будет в одном месте и понятно всем, кто знаком с OpenAPI.
Я думал, что этот способ упростит создание документации, но чот нет.
такой вариант сложен в поддержке, если что то отредактировали в аги но не залезли в общий конфигуратор который лежит не в коде который редактируешь, для долгосрочной работы .. такой метод описания аги мне кажется классным, где код там и описание
Посмотрите в сторону генерации swagger нотации при функциональном тестировании. Вы описываете тесты на ручки и в нужной среде при запуске тестов эти запросы перехватываются и обрабатываются.