LoginSignup
3
4

More than 3 years have passed since last update.

Laravel + SwaggerUI + DockerでAPI仕様書を表示する

Last updated at Posted at 2020-08-27

はじめに

DockerでSwaggerUIコンテナを立ち上げ、Laravelで作成したAPIからAPI仕様書を表示します。

やりたいこと

  • SwaggerUIでAPI仕様書を表示したい

この記事で触れないこと

  • LaravelのAPI開発手順など

ディレクトリ構成

.
├── docker-file
│   └── web
│       ├── Dockerfile
│       └── php.ini
├── swagger-docs
│       └── swagger.json
├── volumes
│   └── swagger-api
└── docker-compose.yml

各ファイルの内容

docker-compose.yml

今回はswagger-uiに焦点を当てている為、dbの項目の記載は省略しています。

docker-compose.yml
version: '3'

services:

  web:
    container_name: web
    build: ./docker-file/web/
    ports:
      - 8080:80
    volumes:
      - ./volumes/swagger-api:/var/www/html/swagger-api

  db:
    container_name: mysql
    ....

  swagger:
    container_name: swagger-ui
    image: swaggerapi/swagger-ui
    volumes:
      - ./swagger-docs/swagger.json:/usr/share/nginx/html/swagger.json
    environment:
      API_URL: swagger.json
    ports:
      - "8081:8080"

docker-file/web/Dockerfile

FROM php:7.4-apache

COPY ./php.ini /usr/local/etc/php/

RUN apt-get update \
  && apt-get install --no-install-recommends -y git curl wget sudo libfreetype6-dev libjpeg62-turbo-dev libmcrypt-dev libmcrypt-dev libxml2-dev libpq-dev libzip-dev libpq5 postgresql-client default-mysql-client libicu-dev libonig-dev \
  && mv /etc/apache2/mods-available/rewrite.load /etc/apache2/mods-enabled \
  && docker-php-ext-configure gd --with-freetype=/usr/include/ --with-jpeg=/usr/include/ \
  && docker-php-ext-install -j$(nproc) zip gd xml pdo pdo_mysql mysqli soap intl \
  && rm -r /var/lib/apt/lists/*

RUN /bin/sh -c a2enmod rewrite

docker-file/web/php.ini

php.ini
[Core]
display_errors = On
error_reporting = E_ALL
error_log = /var/log/apache2/error.log
log_errors = On

[Date]
date.timezone = 'Asia/Tokyo'

[mbstring]
mbstring.language = Japanese
mbstring.internal_encoding = auto
mbstring.http_input = auto
mbstring.http_output = auto
mbsting.encoding_translation = Off
mbstring.detect_order = auto

swagger-docs/swagger.json

空ファイルを用意しておきます。

実行

docker-composeで起動します。

$ docker-compose up -d
Creating network "swagger-ui-docker_default" with the default driver
Creating swagger-ui ... done
Creating mysql      ... done
Creating web        ... done

Swagger

インストール

composerで必要なライブラリをインストールします。
最新は3.x系ですが、以前使っていた2.x系とかなり変わっているようなので今回は2.x系の最新版をインストールします。

$ composer require zircote/swagger-php:2.0.16

Swagger用phpファイル設置

ドキュメントを生成したいディレクトリにphpファイルを作成します。
今回はControllersディレクトリの直下に配置します。

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

/**
 * @SWG\Swagger(
 *     @SWG\Info(
 *         version="1.0",
 *         title="Laravel API Specification",
 *     ),
 * )
 */

ControllerにSwagger用コメントを記載

今回は例としてGet/Post/Put/Deleteを持つProductControllerを作成しました。
メソッドの中身は省略しています。

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

....

class ProductController extends Controller
{

    /**
     * @SWG\Get(
     *     path="/api/product/{product_id}",
     *     summary="商品情報取得",
     *     description="商品情報を取得します。",
     *     produces={"application/json"},
     *     tags={"Product"},
     *     @SWG\Parameter(
     *         name="product_id",
     *         description="商品ID",
     *         in="path",
     *         required=true,
     *         type="integer"
     *     ),
     *     @SWG\Response(
     *         response=200,
     *         description="Success",
     *     ),
     *     @SWG\Response(
     *         response=400,
     *         description="Bad Request error",
     *     ),
     *     @SWG\Response(
     *         response=401,
     *         description="Unauthorized error"
     *     ),
     * )
     */
    public function show($product_id)
    {
        ....
    }

    /**
     * @SWG\Post(
     *     path="/api/product",
     *     summary="商品情報登録",
     *     description="商品情報を登録します。",
     *     produces={"application/json"},
     *     tags={"Product"},
     *     @SWG\Parameter(
     *         in="body",
     *         name="Product",
     *         description="List of product object",
     *         @SWG\Schema(
     *             type="object",
     *             @SWG\Property(property="code", type="string", description="商品コード"),
     *             @SWG\Property(property="name", type="string", description="商品名"),
     *             @SWG\Property(property="price", type="integer", description="販売価格"),
     *         )
     *     ),
     *     @SWG\Response(
     *         response=200,
     *         description="Success",
     *     ),
     *     @SWG\Response(
     *         response=400,
     *         description="Bad Request error",
     *     ),
     *     @SWG\Response(
     *         response=401,
     *         description="Unauthorized error"
     *     ),
     * )
     */
    public function store(Request $request)
    {
        ....
    }

    /**
     * @SWG\Put(
     *     path="/api/product",
     *     summary="商品情報更新",
     *     description="商品情報を更新します。",
     *     produces={"application/json"},
     *     tags={"Product"},
     *     @SWG\Parameter(
     *         in="body",
     *         name="Product",
     *         description="List of product object",
     *         @SWG\Schema(
     *             type="object",
     *             @SWG\Property(property="product_id", type="integer", description="商品ID"),
     *             @SWG\Property(property="code", type="string", description="商品コード"),
     *             @SWG\Property(property="name", type="string", description="商品名"),
     *             @SWG\Property(property="price", type="integer", description="販売価格"),
     *         )
     *     ),
     *     @SWG\Response(
     *         response=200,
     *         description="Success",
     *     ),
     *     @SWG\Response(
     *         response=400,
     *         description="Bad Request error",
     *     ),
     *     @SWG\Response(
     *         response=401,
     *         description="Unauthorized error"
     *     ),
     * )
     */
    public function update(Request $request)
    {
        ....
    }

    /**
     * @SWG\Delete(
     *     path="/api/product",
     *     summary="商品情報削除",
     *     description="商品情報を削除します。",
     *     produces={"application/json"},
     *     tags={"Product"},
     *     @SWG\Parameter(
     *         in="body",
     *         name="Product",
     *         description="List of product object",
     *         @SWG\Schema(
     *             type="object",
     *             @SWG\Property(property="product_id", type="integer", description="商品ID"),
     *         ),
     *     ),
     *     @SWG\Response(
     *         response=200,
     *         description="Success",
     *     ),
     *     @SWG\Response(
     *         response=400,
     *         description="Bad Request error",
     *     ),
     *     @SWG\Response(
     *         response=401,
     *         description="Unauthorized error"
     *     ),
     * )
     */
    public function destroy(Request $request)
    {
        ....
    }
}

swagger.json生成

以下コマンドで、記載したコメントからswagger.jsonを生成します。

-oの後ろが出力するディレクトリです。
出力する場所はどこでも大丈夫ですが、最終的にdocker側のswagger-docsディレクトリに配置する為ここで指定しています。

$ vendor/bin/swagger app/Http/Controllers/ -o ../../swagger-docs/

ブラウザで確認

docker-compose.ymlで先ほど出力したswagger-docs/swagger.jsonを参照するようにしているので、以下URLにアクセスするとAPI仕様書が確認できるようになっています。

localhost_8081_.png

3
4
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
3
4