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 в Swagger

Полученная документация содержит описание всех типов данных, возвращаемых API, список доступных методов c подробным описанием:

Описание метода API в Swagger

Описание метода API содержит его url, описание всех параметров, а так же все варианты ответов. Т.к. мы ссылались на модель Post в описании ответа, мы можем видеть ссылку на эту модель и даже пример ответа API, сгенерированный на основании описания модели. Вверху имеется кнопка Try it out, позволяющая выполнить запрос API прямо со страницы документации.

Заключение

Мы рассмотрели, как создать документацию в Swagger на примере простого API на Laravel. На основе созданных аннотаций мы сгенерировали полноценную документацию. Она может быть использована как разработчиками для совместной работы над API, так и клиентами вашего API.

Более подробную информацию о Swagger вы можете найти на сайте проекта: https://swagger.io/

Вливайтесь в общение

3 комментария

  1. Зачем такой геморрой с изучением ещё одного синтаксиса нотаций и размазыванию всей документации, когда можно просто написать yaml конфиг для сваггера?
    Всё будет в одном месте и понятно всем, кто знаком с OpenAPI.
    Я думал, что этот способ упростит создание документации, но чот нет.

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

  2. Посмотрите в сторону генерации swagger нотации при функциональном тестировании. Вы описываете тесты на ручки и в нужной среде при запуске тестов эти запросы перехватываются и обрабатываются.

Оставьте комментарий

Добавить комментарий

Этот сайт использует Akismet для борьбы со спамом. Узнайте, как обрабатываются ваши данные комментариев.

%d такие блоггеры, как: