もがき系プログラマの日常

もがき系エンジニアの勉強したこと、日常のこと、気になっている技術、備忘録などを紹介するブログです。

Symfony4でNelmioApiDocBundleを試してみた

はじめに

こんばんは。 この記事はSymfony Advent Calendar 2018 20日目の記事です。

よろしくおねがいします。

現在僕は、CakePHP+Nuxtを使用して、webアプリケーションのフルリプレイス作業を行っています。

バックエンドのフレームワークは、人数や時間、スキル的な縛りがあり、既存で使用しているCakePHPのままになりました。

フロントはNuxtを採用しており、バックエンドの役割はapiやshellのみになっています。

そのため、APIドキュメントをきちんと作成するためSwaggerを採用しています。

CakePHPでは良さげなパッケージがあったのですが、@polidogさんからSymfony Advent Calendar の話を聞いて、ふと、Symfonyだとどうやるのかな?と思って、やってみました。

ちなみに自分のSymfony歴は、1系を1.5年程度、2系(2.2とかだった気がする)を1年程度で、それ以降は完全に離れていて、完全に浦島太郎です。

やってみた

packagistで調べてみると、以下あたりが該当しそうでした。

その後、Symfony自体の操作を思い出すために公式を流し見していたのですが、NelmioApiDocBundleの紹介があり、Swaggerの記載があったので、使えるのかな?と思い、こちらにしました。

と、いうより、まず最新のsymfonyを全く触ってないので、そこからでした。

なので、インストールからやります。

インストール

$ composer create-project symfony/website-skeleton test-swagger

実行してみる

$ php bin/console server:start                                                                     
 [OK] Server listening on http://127.0.0.1:8000

f:id:kojirooooocks:20181205025517p:plain

入りました。

次は、公式のインストール手順を確認しながらNelmioApiDocBundleをインストールしてみます。

ライブラリインストール

$ composer require nelmio/api-doc-bundle
$ php bin/console assets:install 

次はAppKernel.phpにインストールしたパッケージをnewするところです。

f:id:kojirooooocks:20181205025535p:plain

ただ、AppKernel.phpが存在しない。。。

自分で作るのかどうするのか調べてたんですが、↓を見る感じ、config/bundles.phpに追加するようです。

バージョンが上がってからの変更だと思います。

f:id:kojirooooocks:20181205025551p:plain

次に、ドキュメントを表示するためのroutingを登録します。

ここは公式通りでいけました。

config/routes.yaml
app.swagger_ui:
    path: /api/doc
    methods: GET
    defaults: { _controller: nelmio_api_doc.controller.swagger_ui }

app.swagger:
    path: /api/doc.json
    methods: GET
    defaults: { _controller: nelmio_api_doc.controller.swagger }

公式では次に、config/config.ymlに設定ファイルを登録するようですが、config.ymlが存在しませんでした。

調べてみると、以下を見かけました。

https://stackoverflow.com/questions/49799385/symfony4-app-config-config-yml-is-missing

config/packages/***.yaml として登録するようです。

こちらもバージョンが上がってからの変更だと思います。

なので、nelmio_api_doc.yamlとして配置します。

内容はほぼ公式のままです。

nelmio_api_doc:
  documentation:
    host: 127.0.0.1:8000
    schemes: [http]
    info:
      title: My App
      description: This is an awesome app!
      version: 1.0.0
  areas:
    path_patterns: [ ^/api(?!/(doc|doc.json)$) ]

f:id:kojirooooocks:20181205025611p:plain

f:id:kojirooooocks:20181205025621p:plain

とりあえずローカルで表示できました。

実際にAPI追加してみます。

指定されたAnnotationで登録していきます。

SymfonyのRoute Annotationを書くと、APIのパスとmethodを、Swaggerの形式によしなに解釈してくれるようです。

<?php
/**
 * Created by PhpStorm.
 * User: yudai_fujita
 * Date: 2018-12-05
 * Time: 01:21
 */

namespace App\Controller;

use Nelmio\ApiDocBundle\Annotation\Model;
use Nelmio\ApiDocBundle\Annotation\Security;
use Swagger\Annotations as SWG;
use Symfony\Component\Routing\Annotation\Route;
use Symfony\Component\HttpFoundation\JsonResponse;

class HelloController
{
    /**
     * @Route("/api/hello/{name}/", methods={"GET"})
     * @SWG\Parameter(
     *     name="name",
     *     in="path",
     *     description="挨拶したい名前",
     *     type="string"
     * )
     * @SWG\Response(
     *     response=200,
     *     description="挨拶するよ",
     *     @SWG\Schema(
     *         type="string"
     *     )
     * )
     * @SWG\Tag(name="hello")
     */
    public function hello(string $name = '')
    {
        return JsonResponse::fromJsonString("hello {$name}");
    }
}

f:id:kojirooooocks:20181205025638p:plain

f:id:kojirooooocks:20181205025654p:plain

表示されました。

/api/doc.jsonにアクセスすると、今回作成したデータが含まれたjsonが表示されます。

f:id:kojirooooocks:20181205025724p:plain

本当にswaggerが食ってくれるか、swagger editorで確認してみます。

本来は、ci回して、そのときに開発サーバーとかに、api/doc.jsonが展開される感じかと思いますが、今回はローカルなので、jsonファイルにしてアップします。

$ wget http://127.0.0.1:8000/api/doc.json

f:id:kojirooooocks:20181205025739p:plain

表示されました。

終わりに

最新のSymfonyの動きについていけてなかったので、無駄にはまってしましましたが、記事書きながら2~3時間程度でなんとかなりました。

そして久しぶりにSymfonyに触ったのですが、Symfony2の頃よりディレクトリ構造など、わかりやすくなっている印象を受けました。

また触り始めたいです。

簡単でしたが、現場からは以上です。