LaravelでScribeを使ってみた

4 min read読了の目安(約4300字

Scribeって?

  • APIドキュメント生成ツールの1つ
  • PHPDocからドキュメントを自動生成
  • PostmanやSwagger用の設定ファイルも一緒に生成してくれる
  • Docも簡単に書ける
  • 公式

Scribeを見つけた経緯

検証

環境

  • Windows10 Home(Localで検証)
  • Laravel 8.27.0
  • php 7.4.12
  • sqlite 3.32.3
  • scribe 2.0

検証用APIについて

  • 書籍のタイトルと価格の一覧表示、登録処理をするAPIのみ用意
    • Scribeの紹介がメインなのでその他の機能は実装しない

Scribe準備

  • Laravelプロジェクトを用意
laravel new BookProject
  • Scribeのパッケージをインストール
composer require --dev knuckleswtf/scribe
  • scribeの設定ファイルを作成
// 下記実行でconfig下にscribe.phpが作成される
php artisan vendor:publish --provider="Knuckles\Scribe\ScribeServiceProvider" --tag=scribe-config
  • ユーザーがブラウザからエンドポイントをテストするためのパッケージを追加
composer require fruitcake/laravel-cors
  • scribe.phpを修正
/*
 * The base URL to be used in examples. If this is empty, Scribe will use the value of config('app.url').
 */
 'base_url' => 'http://localhost:8000', // <-ローカルで検証する場合
 // 'base_url' => null, // <-default

PHPDocを作成

※Modelやenv等については省略

api.php

Route::get('book/index', 'App\Http\Controllers\BookController@index');
Route::post('book/store', 'App\Http\Controllers\BookController@store');

App\Http\Controllers\BookController.php

<?php

namespace App\Http\Controllers;

use App\Models\Book;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Validator;

class BookController extends Controller
{
    /**
     * 書籍一覧取得
     *
     * 書籍一覧の情報を返却する
     *
     * @response {
     *  "id": 1,
     *  "title": "Book Title1",
     *  "cost": 630
     */
    public function index()
    {
        return Book::all();
    }
    
    /**
     * 書籍登録
     *
     * 書籍情報を登録する
     *
     * @bodyParam title string 書籍タイトル
     * @bodyParam cost integer 書籍の価格
     *
     * @response message string 登録完了しました
     */
    public function store(Request $request): string
    {
        Validator::make($request->all(), [
            'title' => 'required',
            'cost' => 'required',
        ])->validate();

        Book::create([
            'title' => $request->title,
            'cost' => $request->cost,
        ]);

        return "登録完了しました";
    }
}

仕様書を生成

php artisan scribe:generate

// public/docs下に仕様書等が作成される
public/docs
 ├css
 ├images
 ├js
 ├collection.json
 ├index.html
 └openapi.yml

上記のindex.htmlファイルをブラウザで開いてみると…

PHPDocで書いた内容が反映されているだけでなく、「Try it out」ボタンでAPIの挙動を確認できる

collection.jsonをPostmanにインポートすれば、1から作らなくても使用できる

同様にopenapi.yamlを使えば、Swaggerでの確認も可能

ポイント

scribeの設定(scribe.phpの修正)

  • config下のファイルなので修正後はキャッシュクリアを忘れずに
  • domainの指定
    • 使用する環境に応じて、base_urlを変更する
  • 仕様書の生成方法等を指定
/*
 * The type of documentation output to generate.
 * - "static" will generate a static HTMl page in the /public/docs folder,
 * - "laravel" will generate the documentation as a Blade view, so you can add routing and authentication.
 */
// 'type' => 'static', <-default
 'type' => 'laravel',
  • 認証の有効無効
    • auth.default を true に設定することで、すべてのエンドポイントを認証済みとしてマークすることができる

仕様書作成対象としたくないものがある場合

  • 方法としては2つ
    • コントローラメソッドまたはクラスの docblock に、@hideFromAPIDocumentationを追加
    • scribe.phpのroutesで設定する

Versionの違い

「Try it out」ボタンでAPIの挙動を確認できる

ScribeのVer2.0から搭載されたもの。Ver1.0では使えないから導入の際は注意

仕様書を更新したい

php artisan scribe:generate を再度実行すればOK

使ってみて思ったこと

メリット

  • 学習コストは低い
  • PHPDocの書き方に関する1つの指標にはなる

気になった点

  • PHPDocの量が確実に多くなる
  • 仕様書を作成するためのDocが至る所に存在することになるので、管理が大変になることはないだろうか?

現状の見解

  • 以下の運用でならScribeを使うのはいいかもしれない
    • Scribe用のPHPDocはControllerクラスのみに記載
    • Controllerはレスポンス等を返却する処理程度しか記載しない
      • バリデーション等はServiceクラスとかにもっていく
    • ServiceクラスやRepositoryクラス等の他のファイルはIDEの機能で自動生成する
  • Scribeを使ってみて、今のプロジェクトに合わないなぁ…と思えば、自動生成したyamlファイルを使ってSwaggerに移行する手もありそう

参考