Swagger генерирует документацию по интерфейсу PHP restful API

PHP

потребности и контекст

необходимость:

Студенты, которые писали интерфейсные документы для коллег-клиентов, вспоминали кровь и слезы истории рукописных документов, прежде чем использовать автоматизированные инструменты для работы с документами в различных случаях.
Моя история другая, потому что, прежде всего, я глава команды Android в компании, и я принадлежу к клиентскому лагерю, убивающему людей в истории кровью и слезами.
Но история крови и слез та же: в дни без автоматизированной документации интерфейс — наименее эффективное звено в процессе разработки.
Поэтому я решил использовать swagger для построения процесса генерации документов из аннотаций php.

задний план:

Наш проект restful API использует фреймворк phalcon, общая структура очень проста, нам нужно только использовать swagger для сканирования каталога контроллера.
В дальнейшем наш проект php api называется php_api_project.
Сервер использует nginx.

строить

Позвольте мне рассказать об окончательном процессе создания документа, который хотел бы иметь полное представление до: настроить после завершения всего процесса, от документа до создания внешнего интерфейса, примерно следующим образом:

  1. Напишите / в формате swagger в файле php* Примечания/
  2. Используйте команду bin/swagger.phar в swagger-php для сканирования каталога, в котором находится контроллер php, для создания файла swagger.json.
  3. Скопируйте файл swagger.json в каталог, указанный index.html в swagger-ui.
  4. Откройте URL-адрес, по которому находится swagger-ui, и вы увидите документ. Каждый API в документе может напрямую обращаться к данным по этому URL-адресу.

Для выполнения этого требования требуются только следующие два элемента чванства:
swagger-php:Инструмент для сканирования комментариев php. Содержит хороший пример.
swagger-ui:Он используется для отображения содержимого файла swagger.json, сгенерированного инструментом сканирования, на веб-странице.

Сначала загрузите эти два проекта локально:

$ git clone https://github.com/swagger-api/swagger-ui.git
$ git clone https://github.com/zircote/swagger-php.git

Развертывание инструмента генерации документации

Говорят, что это развертывание, главное — сгенерировать bin/swagger, команду, используемую для создания файла swagger.json.
Основная задача — использовать composer для разрешения зависимостей.
Поскольку использование composer непосредственно в Китае более болезненно, лучше всего установить источник composer в Китае.
В этом случае развертывание всего инструмента генерации документов является следующие три строки команд:

$ cd swagger-php
$ composer config repo.packagist composer https://packagist.phpcomposer.com
$ composer update

Если в середине не сообщается об ошибках, развертывание завершено.После завершения вы можете создать документ, чтобы попробовать.
В каталоге Examples под проектом swagger-php есть пример проекта php, в котором написаны различные аннотации интерфейса в формате swagger, попробуем сгенерировать документ.
Выполните следующую команду:

$ cd swagger-php
$ mkdir json_docs
$ php ./bin/swagger ./Examples -o json_docs/

Приведенная выше команда просканирует комментарии к файлу php в каталоге Examples, а затем сгенерирует файл swagger.json в каталоге json_docs.Этот файл swagger.json является нашим файлом документации API, который внешний интерфейс swagger-ui использует для отображения.

NOTE:swagger-php — это всего лишь инструмент, его можно поставить куда угодно.

Развертывание интерфейса swagger-ui:

Метод развертывания очень прост, всего три шага:

1. Скопируйте папку Dist в проекте SWAGGER-UI в корневой каталог PHP_REST_API.

NOTE1:Просто скопируйте папку dist.Лучше всего переименовать.Для простоты я не буду ее здесь переименовывать.
NOTE2:Корневой каталог нашего проекта и корень конфигурации nginx — это один и тот же каталог, на самом деле нам не нужно размещать подкаталог, просто поместите его в каталог, доступный через домены без междоменного доступа. междоменная проблема? Я расскажу об этом позже.

2. Измените файл index.html в папке dist и укажите каталог, в котором находится swagger.json.

Просто измените одну строку.
Для простоты каталог swagger.json можно указать прямо в каталоге dist, здесь повторяем предустановленные условия:
Предположим, хост хоста хоста — api.my_project.com;
Предполагая, что корень, указанный в nginx для проекта php_api_project, является его корневым каталогом;
Предположим, что папка dist в swagger-ui находится в указанном выше корневом каталоге;
Предположим, что файл swagger.json предназначен для размещения в указанном выше каталоге dist (php_api_project/dist/swagger.json). ;
Затем измените следующий фрагмент в index.html на этот:

      var url = window.location.search.match(/url=([^&]+)/);
      if (url && url.length > 1) {
        url = decodeURIComponent(url[1]);
      } else {
        <!-- 就是这行,改成你生成的 swagger.json 可以被访问到的路径即可 -->
        url = "http://api.my_project.com/dist/swagger.json";
      }

3. Скопируйте файл swagger.json в указанный выше каталог.

# 把 swagger-php_dir 这个,换成你的 swagger-php 录即可
cp swagger-php_dir/json_docs/swagger.json php_api_project/dist/

Выполнив вышеуказанные действия, посетитеapi.my_project.com/dis...Вы можете увидеть документацию API небольшого проекта примеров.

Пишите PHP-комментарии

В Примере проекта swagger-php уже есть много связанных примеров, просто скопируйте и вставьте их.
Более подробную документацию по соответствующим правилам аннотации см. здесь:
безудержный and.where/swagger-exp…

Предполагая, что каталог, в котором находится мой контроллер проекта, — php_api_project/controller/, тогда мне нужно сканировать только этот каталог, а не сканировать весь проект php.

Для того, чтобы сгенерировать какую-то унифицированную конфигурацию в swagger.json, создайте каталог php_api_project/controller/swagger, в котором хранится php-файл без кода, а в нем пишутся только комментарии.

Я назвал этот файл Swagger.php, и его общее содержание выглядит следующим образом:

<?php

/**
 * @SWG\Swagger(
 *   schemes={"http"},
 *   host="api.my_project.com",
 *   consumes={"multipart/form-data"},
 *   produces={"application/json"},
 *   @SWG\Info(
 *     version="2.3",
 *     title="my project doc",
 *     description="my project 接口文档, V2-3.<br>
以后大家就在这里愉快的对接口把!<br>
以后大家就在这里愉快的对接口把!<br>
以后大家就在这里愉快的对接口把!<br>
"
 *   ),
 *
 *   @SWG\Tag(
 *     name="User",
 *     description="用户操作",
 *   ),
 *
 *   @SWG\Tag(
 *     name="MainPage",
 *     description="首页模块",
 *   ),
 *
 *   @SWG\Tag(
 *     name="News",
 *     description="新闻资讯",
 *   ),
 *
 *   @SWG\Tag(
 *     name="Misc",
 *     description="其他接口",
 *   ),
 * )
 */

Как показано выше, в моем php-файле нет ни одной строки php-кода, только комментарии для определения некоторых глобальных настроек swagger:

schemes: Использовать соглашение (можно заполнить несколько соглашений)
host: адрес проекта, этот адрес будет использоваться в качестве базы URL-адресов каждого интерфейса, объединенных вместе в качестве адреса доступа.
consumes: тип MIME, получаемый интерфейсом по умолчанию. В моем примере formData соответствует типу формы сообщения. Обратите внимание, что это значение проекта по умолчанию, и это значение может быть переопределено в одном комментарии к интерфейсу.
produces: ответный MIME-тип интерфейса по умолчанию. В основном используется интерфейс API.application/jsonиapplication/xml.
@SWG\Info: Вещи, заполненные этим, будут размещены в самом начале документа и использованы в качестве описания документа.
@SWG\Tag: тег используется для классификации документов, поле имени должно быть уникальным. Интерфейс может указывать несколько тегов, тогда он будет отображаться в нескольких группах классификаций. Здесь также можно использовать теги без предварительного определения, но тогда нет описания. Бесполезно говорить больше, просто попользуйтесь немного, и вы все поймете.

Затем написать комментарии в формате swagger для каждого интерфейса.Возьмем каштан:

    /**
     * @SWG\Post(path="/user/login", tags={"User"},
     *   summary="登录接口(用户名+密码)",
     *   description="用户登录接口,账号可为 用户名 或 手机号. 参考(这个会在页面产生一个可跳转的链接: [用户登录注意事项](http://blog.csdn.net/liuxu0703/)",
     *   @SWG\Parameter(name="userName", type="string", required=true, in="formData",
     *     description="登录用户名/手机号"
     *   ),
     *   @SWG\Parameter(name="password", type="string", required=true, in="formData",
     *     description="登录密码"
     *   ),
     *   @SWG\Parameter(name="image_list", type="string", required=true, in="formData",
     *     @SWG\Schema(type="array", @SWG\Items(ref="#/definitions/Image")),
     *     description="用户相册. 好吧,没人会在登录时要求填一堆图片信息.这里是为了示例 带结构的数据, @SWG\Schema ,这个结构需要另行定义,下面会讲."
     *   ),
     *   @SWG\Parameter(name="video", type="string", required=true, in="formData",
     *     @SWG\Schema(ref="#/definitions/Video"),
     *     description="用户 呃... 视频? 同上,为了示例 @SWG\Schema ."
     *   ),
     *   @SWG\Parameter(name="client_type", type="integer", required=false, in="formData",
     *     description="调用此接口的客户端类型: 1-Android, 2-IOS. 非必填,所以 required 写了 false"
     *   ),
     *   @SWG\Parameter(name="gender", type="integer", required=false, in="formData",
     *     default="1",
     *     description="性别: 1-男; 2-女. 注意这个参数的default上写的不是参数默认值,而是默认会被填写在swagger页面上的值,为的是方便用swagger就地访问该接口."
     *   ),
     * )
     */
    public function loginAction() {
        // php code
    } 

    /**
     * @SWG\Get(path="/User/myWebPage", tags={"User"},
     *   produces={"text/html"},
     *   summary="用户的个人网页",
     *   description="这不是个api接口,这个返回一个页面,所以 produces 写了 text/html",
     *   @SWG\Parameter(name="userId", type="integer", required=true, in="query"),
     *   @SWG\Parameter(name="userToken", type="string", required=true, in="query",
     *     description="用户令牌",
     *   ),
     * )
     */
    public function myWebPageAction(){
        // php code
    }

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

В приведенном выше интерфейсе входа используются две структурированные данные: одна представляет собой массив типа изображения, а другая представляет собой структуру типа видео.
(На самом деле структурированные параметры могут быть толькоin="body"Когда вы можете использовать, но это не мешает нам упростить проблему, структурированные данные отформатированы как строка JSON, поскольку мы покажем в этой структуре документации на него)

Эта структурированная чванливость также может быть определена с помощью аннотаций php:

<?php

/**
 * @SWG\Definition(type="object", @SWG\Xml(name="Image"))
 */
class Image {

    /**
     * @SWG\Property()
     * @var string
     */
    public $url;
    
    /**
     * @SWG\Property(format="int32")
     * @var int
     */
    public $height;
    
    /**
     * @SWG\Property(format="int32")
     * @var int
     */
    public $width;

}

<?php

/**
 * @SWG\Definition(type="object", @SWG\Xml(name="Video"))
 */
class Video {

    /**
     * @SWG\Property()
     * @var string
     */
    public $url;

    /**
     * @SWG\Property()
     * @var string
     */
    public $thumb_url;

    /**
     * @SWG\Property(format="int32")
     * @var int
     */
    public $length;

    /**
     * @SWG\Property(format="int64")
     * @var int
     */
    public $size;

}

Таким образом, когда эти два класса также сканируются swagger-php/bin/swagger, другие места могут правильно ссылаться на две структуры с именами Image и Video.

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

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

Правила написания ответов Swagger основаны на кодах ответов http (404, 401 и т.д.), короче говоря, для нашего интерфейса этот набор правил описания использовать непросто.

Поэтому я напрямую отбросил описание ответа, а напрямую использовал swagger для запроса интерфейса на месте, чтобы посмотреть, что было возвращено.Если это не сработает, я опишу возвращаемую информацию интерфейса в описании.

После того, как документ будет написан, вы можете вызвать команду swagger-php/bin/swagger, чтобы сгенерировать swagger.json, а затем скопировать его в каталог, указанный в swagger-ui, для доступа к документу.

NOTE:

Вы бы видели, что на самом деле аннотацию интерфейса не обязательно писать на интерфейсе, а аннотацию можно написать из воздуха, и документ можно сгенерировать. где размещается каждая аннотация.Например, общее определение swagger, определение тега и т. д., напишите его в любом php-файле, который можно отсканировать.

Краткое описание общих полей

Вот лишь краткое описание собственного понимания и перевода.Для более подробного описания полей вам все равно придется читать документацию.Выложите документацию еще раз:
безудержный and.where/swagger-exp…

Описание интерфейса (@SWGGet, @SWGPost и т. д.) Общие поля:

summary - string
接口的简要介绍,会显示在接口标头上,不能超过120个字符

description - string
接口的详细介绍

externalDocs - string
外部文档链接

operationId - string
全局唯一的接口标识

consumes - [string]
接口接收的MIME类型

produces - [string]
接口返回的MIME类型,如 application/json

schemes -    [string]
接口所支持的协议,取值仅限: "http", "https", "ws", "wss"

parameters -    [Parameter Object | Reference Object]
参数列表

Описание параметра (@SWGParameter) Общие поля:

name - string
参数名. 通过路径传参(in 取值 "path")时有注意事项,没用到,懒得看了...

in - string
参数从何处来. 必填. 取值仅限: "query", "header", "path", "formData", "body"

description - string
参数描述. 最好别太长

type - string
参数类型. 取值仅限: "string", "number", "integer", "boolean", "array", "file"

required - boolean
参数是否必须. 通过路径传参(in 取值 "path")时必须为 true.

default - *
默认值. 在你打算把参数通过 path 传递时规矩挺多,我没用到.用到的同学自己看文档吧.

возникшие проблемы

Междоменные проблемы:

Преимущество swagger Niu X в том, что он может получить доступ к интерфейсу на документе и отобразить вывод, что очень удобно для отладки и интерфейса.Но если вы не хотите развертывать swagger-ui под интерфейсным проектом, то получите доступ к интерфейс в swagger-ui in situ (Заголовки ответа: нет ответа от сервера; Тело ответа: нет содержимого).Мы не будем здесь говорить о том, как решить междоменную проблему, а просто дадим вам идею для тех, кто сталкивается с вышеизложенным проблемы., знайте, что ошибка генерируется междоменной, это легко решить.

Аутентификация входа:

Если вы хотите поместить документ в общедоступную сеть, прямой доступ к вашему интерфейсу не подходит, поэтому вам необходимо аутентифицировать адрес доступа к документу.
Поскольку требования безопасности невысокие, компания меньших развивающихся групп не имеет большого количества персонала, я использовал Basic Auth Auth, предоставляемый Nginx, чтобы сделать аутентификацию входа в систему.
Старые правила, официальные документы первой почты:
www.nginx.com/resourc...
Эта аутентификация очень проста и может быть выполнена за считанные минуты. Не вдаваясь в подробности, всего два шага:

1. Сначала используйте команду htpasswd, чтобы сгенерировать имя учетной записи и пароль для учащихся, которым необходим доступ к документу:

$ htpasswd -cb your/path/to/api_project_accounts.db admin password_for_admin
$ htpasswd -b your/path/to/api_project_accounts.db liuxu 123456
$ htpasswd your/path/to/api_project_accounts.db xiaoming

-cОпция означает, что если файл учетной записи (api_project_accounts.db) не существует, он будет создан, поэтому необходимо добавить -c при создании первой учетной записи и не добавлять -c при ее создании позже.
-bПараметр указывает, что пароль указан в виде простого текста, который является последним вводом в первой и второй командах выше (password_for_admin, 123456), поэтому, если вы не хотите указывать пароль в открытом виде, вы можете опустить -b , Как и третья команда выше, она будет работать с sudo Подобно команде, вы можете ввести невидимый пароль.
Приведенная выше команда создает три учетных записи, admin, liuxu, xiaoming и сохраните пароль учетной записи в файле api_project_accounts.db.

2. Затем дайте себе этот открытый доступ к адресу HTTP Basic Auth в конфигурации проекта Nginx в нем.

location /dist {
    auth_basic              "my api project login";
    auth_basic_user_file    your/path/to/api_project_accounts.db;
}

Не забудьте перезапустить nginx после внесения изменений:

nginx -s reload

Такая простая аутентификация при входе устанавливается.

NOTE:

Если в системе нетhtpassЭта команда может установить apachehttpdсерверное ПО,htpassЭта команда включена в него:

yum install httpd

Ссылаться на:

[1] официальный сайт сваггера
[2] адрес проекта чванства
[3] адрес проекта пользовательского интерфейса swagger
[4] адрес проекта swagger php
[5] справочный адрес документации swagger