Skip to content

OpenAPI Specification阅读器,通过对 php 的oas或swagger标准注释文档进行解析,通过swaggerUI渲染成漂亮的API文档

License

Notifications You must be signed in to change notification settings

bestyii/yii2-openapi-reader

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

16 Commits
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Yii2 OpenApi Specification Reader 模块

原理是采用php的注释来写api文档,注释的语法采用php annotation方式进行解析。 解析后符合OpenAPI Specification 规范,可以通过 swagger UI 或 Redoc 进行渲染成可读性强带有交互的api文档。

Latest Stable Version Total Downloads License

swagger UI

alt swagger UI

Redoc:

alt redoc

这个模块集成了:

安装 Installation

通过 composer安装.

项目中直接运行

php composer.phar require bestyii/yii2-openapi-reader:dev-master

或者添加下面代码到 composer.json文件

"bestyii/yii2-openapi-reader": "dev-master"

使用 Usage

Once the extension is installed, simply use it in your code by :

You set url, where locate json file OR set path for scan

if (YII_ENV_DEV) {
 $config['modules']['openapireader'] = [
        'class' => \bestyii\openapiReader\Module::class,
        'defaultDoc' => 'api',
        'path' => [
            'api' => '@grazio/api',
            'extensions' => '@app/extensions',
        ],
        // disable page with your logic
        'isDisable' => function () {
            return false;
        },
        // replace placeholders in swagger content
        'afterRender' => function ($content) {
            $content = str_replace('{{HOST}}', \yii\helpers\Url::base(true), $content);
            $content = str_replace('{{BASE_PATH}}', '/api', $content);
            $content = str_replace('{{SERVER_DESCRIPTION}}', 'description', $content);
            return $content;
        }
    ];
}

现在就可以访问你的API文档了

# swagger 风格
http://yoururl.com/openapireader

# redoc 风格
http://yoururl.com/openapireader/default/redoc

示例 Module

/**
 * @OA\OpenApi(
 *     @OA\Info(
 *         version="0.0.1",
 *         title="OpenApi",
 *         description="This is a sample server Petstore server.  You can find out more about Swagger at [http://swagger.io](http://swagger.io) or on [irc.freenode.net, #swagger](http://swagger.io/irc/).  For this sample, you can use the Bearer `access token` to test the authorization filters.",
 *     ),
 *     @OA\Server(
 *         description="Test",
 *         url="http://api.bestyii.com/api/"
 *     ),
 *     @OA\Server(
 *         description="Prod",
 *         url="http://api.bestyii.com/v2/"
 *     ),
 *     @OA\ExternalDocumentation(
 *         description="更多关于达卡拉的信息",
 *         url="http://bestyii.com"
 *     )
 * )
 */

/**
 * @OA\SecurityScheme(
 *   securityScheme="bearerAuth",
 *   type="http",
 *   scheme="bearer",
 *   in="header",
 *   bearerFormat="JWT"
 * )
 * https://swagger.io/docs/specification/authentication/basic-authentication/
 */

示例 controller

<?php

namespace app\modules\api\controllers;

use app\modules\api\models\UserIdentity;
use Yii;
use app\modules\api\models\User;
use yii\data\ActiveDataProvider;
use app\modules\api\components\ActiveController;
use yii\web\NotFoundHttpException;
use yii\web\ServerErrorHttpException;

/**
 * @OA\Tag(
 *   name="Users",
 *   description="用户账号",
 *   @OA\ExternalDocumentation(
 *     description="更多相关",
 *     url="http://bestyii.com"
 *   )
 * )
 */
class UserController extends ActiveController
{
    public $modelClass = 'app\modules\api\models\UserIdentity';

    /**
     * @OA\Get(
     *     path="/users",
     *     summary="查询 User",
     *     tags={"Users"},
     *     description="",
     *     operationId="findUser",
     *     @OA\Parameter(
     *         name="ids",
     *         in="query",
     *         description="逗号隔开的 id",
     *         required=false,
     *         @OA\Schema(
     *           type="integer",
     *           @OA\Items(type="int20"),
     *         ),
     *     ),
     *     @OA\Response(
     *         response=200,
     *         description="查询成功",
     *         @OA\Schema(
     *             type="array",
     *             @OA\Items(ref="#/components/schemas/User")
     *         ),
     *     ),
     *     @OA\Response(
     *         response="400",
     *         description="无效的id",
     *     ),
     *   security={{
     *     "bearerAuth":{}
     *   }}
     * )
     */
    public function actionIndex()
    {
        $dataProvider = new ActiveDataProvider([
            'query' => UserIdentity::find(),
        ]);
        return $dataProvider;
    }

    /**
     * @OA\Get(
     *     path="/users/{id}",
     *     summary="通过ID显示详情",
     *     description="",
     *     operationId="getUserById",
     *     tags={"Users"},
     *     @OA\Parameter(
     *         description="id",
     *         in="path",
     *         name="id",
     *         required=true,
     *         @OA\Schema(
     *           type="integer",
     *           format="int64"
     *         )
     *     ),
     *     @OA\Response(
     *         response=200,
     *         description="操作成功",
     *         @OA\JsonContent(ref="#/components/schemas/User")
     *     ),
     *     @OA\Response(
     *         response="400",
     *         description="无效的ID"
     *     ),
     *     @OA\Response(
     *         response="404",
     *         description="没有找到相应资源"
     *     ),
     *   security={{
     *     "bearerAuth":{}
     *   }}
     * )
     */
    public function actionView($id)
    {
        return $this->findModel($id);
    }

    /**
     * @OA\Post(
     *     path="/users",
     *     tags={"Users"},
     *     operationId="addUser",
     *     summary="添加",
     *     description="",
     *   @OA\RequestBody(
     *       required=true,
     *       description="创建 User 对象",
     *       @OA\JsonContent(ref="#/components/schemas/User"),
     *       @OA\MediaType(
     *           mediaType="application/x-www-form-urlencoded",
     *           @OA\Schema(
     *               type="object",
     *               ref="#/components/schemas/User"
     *          ),
     *       )
     *   ),
     *     @OA\Response(
     *         response=201,
     *         description="操作成功",
     *         @OA\JsonContent(ref="#/components/schemas/User")
     *     ),
     *     @OA\Response(
     *         response=405,
     *         description="无效的输入",
     *     ),
     *   security={{
     *     "bearerAuth":{}
     *   }}
     * )
     */
    public function actionCreate()
    {
        $model = new UserIdentity();
        if ($model->load(Yii::$app->getRequest()->getBodyParams(), '') && $model->save()) {
            $response = Yii::$app->getResponse();
            $response->setStatusCode(201);
        } elseif (!$model->hasErrors()) {
            throw new ServerErrorHttpException('Failed to create the object for unknown reason.');
        }
        return $model;
    }

    /**
     * @OA\Put(
     *     path="/users/{id}",
     *     tags={"Users"},
     *     operationId="updateUserById",
     *     summary="更新指定ID数据",
     *     description="",
     *     @OA\Parameter(
     *         description="id",
     *         in="path",
     *         name="id",
     *         required=true,
     *         @OA\Schema(
     *           type="integer",
     *           format="int64"
     *         )
     *     ),
     *   @OA\RequestBody(
     *       required=true,
     *       description="更新 User 对象",
     *       @OA\JsonContent(ref="#/components/schemas/User"),
     *       @OA\MediaType(
     *           mediaType="multipart/form-data",
     *           @OA\Schema(ref="#/components/schemas/User")
     *       )
     *   ),
     *     @OA\Response(
     *         response=200,
     *         description="操作成功",
     *         @OA\JsonContent(ref="#/components/schemas/User")
     *     ),
     *     @OA\Response(
     *         response=400,
     *         description="无效的ID",
     *     ),
     *     @OA\Response(
     *         response=404,
     *         description="没有找到相应资源",
     *     ),
     *     @OA\Response(
     *         response=405,
     *         description="数据验证异常",
     *     ),
     *   security={{
     *     "bearerAuth":{}
     *   }}
     * )
     */
    public function actionUpdate($id)
    {
        $model = $this->findModel($id);
        if ($model->load(Yii::$app->request->getBodyParams(), '') && $model->save()) {
            Yii::$app->response->setStatusCode(200);
        } elseif (!$model->hasErrors()) {
            throw new ServerErrorHttpException('Failed to update the object for unknown reason.');
        }
        return $model;
    }

    /**
     * @OA\Delete(
     *     path="/users/{id}",
     *     summary="删除User",
     *     description="",
     *     operationId="deleteUser",
     *     tags={"Users"},
     *     @OA\Parameter(
     *         description="需要删除数据的ID",
     *         in="path",
     *         name="id",
     *         required=true,
     *         @OA\Schema(
     *             type="integer",
     *             format="int64"
     *         )
     *     ),
     *     @OA\Response(
     *         response=204,
     *         description="没有找到相应资源"
     *     ),
     *     @OA\Response(
     *         response=400,
     *         description="无效的ID"
     *     ),
     *     @OA\Response(
     *         response=404,
     *         description="没有找到相应资源"
     *     ),
     *   security={{
     *     "bearerAuth":{}
     *   }}
     * )
     */
    public function actionDelete($id)
    {
        $model = $this->findModel($id);
        if ($model->softDelete() === false) {
            throw new ServerErrorHttpException('Failed to delete the object for unknown reason.');
        }
        Yii::$app->getResponse()->setStatusCode(204);
    }

    /**
     * Finds the User model based on its primary key value.
     * If the model is not found, a 404 HTTP exception will be thrown.
     * @param string $id
     * @return User the loaded model
     * @throws NotFoundHttpException if the model cannot be found
     */
    protected function findModel($id)
    {
        if (($model = UserIdentity::findOne($id)) !== null) {
            return $model;
        }
        throw new NotFoundHttpException('The requested User does not exist.');
    }
}

示例 model

/**
 * @OA\Schema(
 *      schema="User",
 *      required={"username"},
 *     @OA\Property(
 *        property="id",
 *        description="User ID",
 *        type="integer",
 *        format="int64",
 *    ),
 *     @OA\Property(
 *        property="username",
 *        description="用户名",
 *        type="string",
 *        maxLength=100,
 *    ),
 *     @OA\Property(
 *        property="email",
 *        description="邮箱",
 *        type="string",
 *        maxLength=100,
 *    ),
 *     @OA\Property(
 *        property="password",
 *        description="密码",
 *        type="string",
 *        maxLength=64,
 *    ),
 *     @OA\Property(
 *        property="created_at",
 *        description="创建时间",
 *        type="string",
 *        default="0",
 *    ),
 *     @OA\Property(
 *        property="updated_at",
 *        description="更新时间",
 *        type="string",
 *        default="0",
 *    ),
 *     @OA\Property(
 *        property="last_login_at",
 *        description="最后登录时间",
 *        type="string",
 *        default="0",
 *    ),
 *     @OA\Property(
 *        property="ip",
 *        description="登录IP ip2long",
 *        type="integer",
 *        format="int64",
 *        default=0,
 *    ),
 *)
 */

TODO

  • add cache
  • add customization