20
21

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

PHPでSwagger3(OpenAPI Specification 3)

Last updated at Posted at 2019-02-05

Swagger-PHP v3.xの使い方です

ドキュメント
サンプル

OpenAPI Specification 3

OpenAPI SpecificationOAS3

Swagger-PHP

composer require zircote/swagger-php
vendor/bin/openapi -h
Usage: openapi [--option value] [/path/to/project ...]

Options:
  --output (-o)     Path to store the generated documentation.
                    ex: --output openapi.yaml
  --exclude (-e)    Exclude path(s).
                    ex: --exclude vendor,library/Zend
  --bootstrap (-b)  Bootstrap a php file for defining constants, etc.
                    ex: --bootstrap config/constants.php
  --processor       Register an additional processor.
  --format          Force yaml or json.
  --debug           Show additional error information.
  --help (-h)       Display this help message.

openapiファイルの作成(アノテーション記述後)

vendor/bin/openapi -o {出力先} --format {出力フォーマット} {スキャン対象ディレクトリ}
example
vendor/bin/openapi -o openapi.json --format json --debug app/Http/Controllers/Api/

vendor/bin/openapi -o openapi.json --format json app/Http/Controllers/Api/

アノテーションの記述方法

まとめて設定するもの

infoObject
ServerObject
SecurityRequirementObject
TagObject
ExternalDocumentationObject
の設定は下記のようにスキャン対象ディレクトリ内に作る(ファイル名は自由)

ServerObjectはアクセスするAPIになるのでほぼ必須

app/Http/Controllers/Api/swagger.php
<?php

// 必須
/**
 * @OA\Info(
 *  title="API Example",
 *  description="description",
 *  version="1.0.0",
 *   @OA\Contact(
 *     email="support@example.com"
 *   )
 * )
 */

// オプション
/**
 * @OA\Server(
 *   description="OpenApi host",
 *   url="http://192.168.99.100"
 * ),
 * @OA\SecurityScheme(
 *   securityScheme="api_key",
 *   type="apiKey",
 *   in="header",
 *   name="api_key"
 * ),
 * @OA\ExternalDocumentation(
 *   description="Find out more about Swagger",
 *   url="http://192.168.99.100"
 * ),
 * @OA\Tag(
 *   name="example",
 *   description="example",
 *   @OA\ExternalDocumentation(
 *     description="Find out more",
 *     url="http://192.168.99.100"
 *   )
 * )
 */

JSON形式のAPI設定例

app/Http/Controllers/Api/ExampleController.php

/**
 * @OA\Post(
 *   path="/api/example/{id}",
 *   summary="具体例が無かったので寄せ集めてみた",
 *   @OA\RequestBody(
 *     required=true,
 *     @OA\JsonContent(
 *       type="object",
 *       required={"number", "text"},
 *       @OA\Property(
 *         property="number",
 *         type="integer",
 *         format="int32",
 *         example=1,
 *         description="リクエストボディのjsonのプロパティの例"
 *       ),
 *       @OA\Property(
 *         property="text",
 *         type="string",
 *         example="text",
 *         description="リクエストボディのjsonのプロパティの例"
 *       )
 *     )
 *   ),
 *   @OA\Parameter(
 *     name="id",
 *     in="path",
 *     required=true,
 *     description="パスからのパラメータ例",
 *     @OA\Schema(type="string")
 *   ),
 *   @OA\Parameter(
 *     name="queryString",
 *     in="query",
 *     required=true,
 *     description="クエリーストリングからのパラメータ例",
 *     @OA\Schema(type="string")
 *   ),
 *   @OA\Response(
 *     response=200,
 *     description="OK",
 *     @OA\JsonContent(
 *       type="object",
 *       @OA\Property(
 *         property="message",
 *         type="string",
 *         description="レスポンスボディjsonパラメータの例"
 *       )
 *     )
 *   ),
 *   @OA\Response(
 *     response=400,
 *     description="Bad Request",
 *     @OA\JsonContent(
 *       type="object",
 *       @OA\Property(
 *         property="message",
 *         type="string",
 *         description="レスポンスボディjsonパラメータの例"
 *       )
 *     )
 *   ),
 *   @OA\Response(
 *     response=401,
 *     description="Unauthorized",
 *     @OA\JsonContent(
 *       type="object",
 *       @OA\Property(
 *         property="message",
 *         type="string",
 *         description="レスポンスボディjsonパラメータの例"
 *       )
 *     )
 *   ),
 *   @OA\Response(
 *     response="default",
 *     description="Unexpected Error",
 *     @OA\JsonContent(
 *       type="object",
 *       @OA\Property(
 *         property="message",
 *         type="string",
 *         description="レスポンスボディjsonパラメータの例"
 *       )
 *     )
 *   )
 * )
 */
public function example($id)
{
    // example
}

設定の使いまわし

OpenAPI Specificationではグローバルなcomponents.schemasセクションに登録して、$refを使用して使いまわすことができるのでそれの設定を行えば良い

/**
 * @OA\Schema(
 *   schema="product_id",
 *   type="integer",
 *   format="int32",
 *   description="参照用"
 * )
 */

/components/schemas/product_idで参照可能

参照を使用した例

app/Http/Controllers/Api/ExampleController.php
/**
 * @OA\Schema(
 *   schema="message",
 *   type="object",
 *   description="参照用",
 *   @OA\Property(
 *     property="message",
 *     type="string",
 *     description="レスポンスボディjsonパラメータの例"
 *   )
 * )
 */

/**
 * @OA\Post(
 *   path="/api/example/{id}",
 *   summary="具体例が無かったので寄せ集めてみた",
 *   @OA\RequestBody(
 *     required=true,
 *     @OA\JsonContent(
 *       type="object",
 *       required={"number", "text"},
 *       @OA\Property(
 *         property="number",
 *         type="integer",
 *         format="int32",
 *         example=1,
 *         description="リクエストボディのjsonのプロパティの例"
 *       ),
 *       @OA\Property(
 *         property="text",
 *         type="string",
 *         example="text",
 *         description="リクエストボディのjsonのプロパティの例"
 *       )
 *     )
 *   ),
 *   @OA\Parameter(
 *     name="id",
 *     in="path",
 *     required=true,
 *     description="パスからのパラメータ例",
 *     @OA\Schema(type="string")
 *   ),
 *   @OA\Parameter(
 *     name="queryString",
 *     in="query",
 *     required=true,
 *     description="クエリーストリングからのパラメータ例",
 *     @OA\Schema(type="string")
 *   ),
 *   @OA\Response(
 *     response=200,
 *     description="OK",
 *     @OA\JsonContent(@OA\Property(ref="#/components/schemas/message"))
 *   ),
 *   @OA\Response(
 *     response=400,
 *     description="Bad Request",
 *     @OA\JsonContent(@OA\Property(ref="#/components/schemas/message"))
 *   ),
 *   @OA\Response(
 *     response=401,
 *     description="Unauthorized",
 *     @OA\JsonContent(@OA\Property(ref="#/components/schemas/message"))
 *   ),
 *   @OA\Response(
 *     response="default",
 *     description="Unexpected Error",
 *     @OA\JsonContent(@OA\Property(ref="#/components/schemas/message"))
 *   )
 * )
 */
public function example($id)
{
    // example
}

プロパティをネストする例

/**
 * @OA\Schema(
 *   schema="message",
 *   type="object",
 *   description="message",
 *   @OA\Property(
 *     property="message",
 *     type="string",
 *     description="メッセージ"
 *   )
 * ),
 * @OA\Schema(
 *   schema="user",
 *   type="object",
 *   description="user",
 *   required={"message", "user"},
 *   @OA\Property(property="message", ref="#/components/schemas/message"),
 *   @OA\Property(
 *     property="user",
 *     type="object",
 *     description="ユーザー",
 *     required={"id", "name"},
 *     @OA\Property(
 *       property="id",
 *       type="string",
 *       description="ID"
 *     ),
 *     @OA\Property(
 *       property="name",
 *       type="string",
 *       description="名前"
 *     )
 *   )
 * )
 */

openapiファイルを作成し終わったら

これで作ったjsonyamlSwagger UIに読み込ませて終わり

Swagger UI

htmlファイルのみで作るなら
https://github.com/swagger-api/swagger-ui/blob/v3.18.3/dist/index.html
こちらと同じようにhtmlを作成しリンクを以下に変更し、https://petstore.swagger.io/v2/swagger.json部分をローカルに作ったものに置き換える

差し替えるリンク
(現時点の最新)
https://unpkg.com/swagger-ui-dist@3.20.6/swagger-ui.css
https://unpkg.com/swagger-ui-dist@3.20.6/favicon-32x32.png
https://unpkg.com/swagger-ui-dist@3.20.6/favicon-16x16.png
https://unpkg.com/swagger-ui-dist@3.20.6/swagger-ui-bundle.js
https://unpkg.com/swagger-ui-dist@3.20.6/swagger-ui-standalone-preset.js

出力されたopenapiファイル

{
    "openapi": "3.0.0",
    "info": {
        "title": "API Example",
        "description": "description",
        "contact": {
            "email": "support@example.com"
        },
        "version": "1.0.0"
    },
    "servers": [
        {
            "url": "http://192.168.99.100",
            "description": "OpenApi host"
        }
    ],
    "paths": {
        "/api/example/{id}": {
            "post": {
                "summary": "具体例が無かったので寄せ集めてみた",
                "operationId": "App\\Http\\Controllers\\Api\\ExampleController::example",
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "description": "パスからのパラメータ例",
                        "required": true,
                        "schema": {
                            "type": "string"
                        }
                    },
                    {
                        "name": "queryString",
                        "in": "query",
                        "description": "クエリーストリングからのパラメータ例",
                        "required": true,
                        "schema": {
                            "type": "string"
                        }
                    }
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "required": [
                                    "number",
                                    "text"
                                ],
                                "properties": {
                                    "number": {
                                        "description": "リクエストボディのjsonのプロパティの例",
                                        "type": "integer",
                                        "format": "int32",
                                        "example": 1
                                    },
                                    "text": {
                                        "description": "リクエストボディのjsonのプロパティの例",
                                        "type": "string",
                                        "example": "text"
                                    }
                                },
                                "type": "object"
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "description": "OK",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "properties": {
                                        "": {
                                            "$ref": "#/components/schemas/message"
                                        }
                                    },
                                    "type": "object"
                                }
                            }
                        }
                    },
                    "400": {
                        "description": "Bad Request",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "properties": {
                                        "": {
                                            "$ref": "#/components/schemas/message"
                                        }
                                    },
                                    "type": "object"
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Unauthorized",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "properties": {
                                        "": {
                                            "$ref": "#/components/schemas/message"
                                        }
                                    },
                                    "type": "object"
                                }
                            }
                        }
                    },
                    "default": {
                        "description": "Unexpected Error",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "properties": {
                                        "": {
                                            "$ref": "#/components/schemas/message"
                                        }
                                    },
                                    "type": "object"
                                }
                            }
                        }
                    }
                }
            }
        }
    },
    "components": {
        "schemas": {
            "message": {
                "description": "参照用",
                "properties": {
                    "message": {
                        "description": "レスポンスボディjsonパラメータの例",
                        "type": "string"
                    }
                },
                "type": "object"
            }
        },
        "securitySchemes": {
            "api_key": {
                "type": "apiKey",
                "name": "api_key",
                "in": "header"
            }
        }
    },
    "tags": [
        {
            "name": "example",
            "description": "example",
            "externalDocs": {
                "description": "Find out more",
                "url": "http://192.168.99.100"
            }
        }
    ],
    "externalDocs": {
        "description": "Find out more about Swagger",
        "url": "http://192.168.99.100"
    }
}
20
21
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
20
21

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?