はじめに
こんばんは。 この記事は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
入りました。
次は、公式のインストール手順を確認しながらNelmioApiDocBundleをインストールしてみます。
ライブラリインストール
$ composer require nelmio/api-doc-bundle $ php bin/console assets:install
次はAppKernel.phpにインストールしたパッケージをnewするところです。
ただ、AppKernel.phpが存在しない。。。
自分で作るのかどうするのか調べてたんですが、↓を見る感じ、config/bundles.phpに追加するようです。
バージョンが上がってからの変更だと思います。
- https://symfony.com/doc/current/bundles.html
- https://stackoverflow.com/questions/51310447/how-can-i-find-app-appkernel-php-in-symfony-4
次に、ドキュメントを表示するための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)$) ]
とりあえずローカルで表示できました。
実際に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}"); } }
表示されました。
/api/doc.jsonにアクセスすると、今回作成したデータが含まれたjsonが表示されます。
本当にswaggerが食ってくれるか、swagger editorで確認してみます。
本来は、ci回して、そのときに開発サーバーとかに、api/doc.jsonが展開される感じかと思いますが、今回はローカルなので、jsonファイルにしてアップします。
$ wget http://127.0.0.1:8000/api/doc.json
表示されました。
終わりに
最新のSymfonyの動きについていけてなかったので、無駄にはまってしましましたが、記事書きながら2~3時間程度でなんとかなりました。
そして久しぶりにSymfonyに触ったのですが、Symfony2の頃よりディレクトリ構造など、わかりやすくなっている印象を受けました。
また触り始めたいです。
簡単でしたが、現場からは以上です。