🤔

API PlatformをBrefで動かしてみたい

2023/12/11に公開

こんにちは、ちゃちいです。
今回は API Platform Advent Calendar 2023 11日の記事です。カレンダー空きがいっぱいなのでどなたか書いて、どうぞ。


特段、見所はない記事になってしまいました


API PlatformをBrefで動かした

できあがりはコチラです
https://github.com/chatii/api-platform-advent-calendar-2023-12-11

AWS CDKスキーなので、CDKです。特につまづくことなく動作しました。うそです、今回やりたかったけどできなかった件を最後に書いています。

Symfony CLIからSymfonyをセットアップする

https://symfony.com/download#step-1-install-symfony-cli

Symfony CLIは強力なツールです。参考 @ippey_s さんの紹介記事。
https://qiita.com/ippey_s/items/8919f618d13b3b6242e9

これで Symfony をセットアップします。

symfony new <target_dir>

真新しいSymfonyにAPI Platformを追加する

API Platformのドキュメントを参考に。

https://api-platform.com/docs/core/getting-started/

composer require api

Brefを追加する

https://bref.sh/docs/symfony/getting-started

BrefでSymfonyを動かすための手順が書いてあります。ここはAPI Platform関係ないですね。

CDKでデプロイする

LambdaにURLを持たせることができて本当にラクになりましたね。API Gatewayいらず。

BrefはCDKに対応しており、専用のコンストラクトが提供されています。
https://github.com/brefphp/constructs

const helloApi = new PhpFpmFunction(this, 'Hello', {
	handler: 'public/index.php',
	phpVersion: '8.3',
	code: new AssetCode('../api/', {
		exclude: [
		    'tests/**',
		    'var/**',
		],
	}),
	tracing: Tracing.ACTIVE,
	environment: {
		'APP_ENV': 'prod',
	},
});

helloApi.addFunctionUrl({
	authType: FunctionUrlAuthType.NONE,
});

AWSの認証などを準備した上で、cdk deployすれば、デプロイされたLambdaにURLが割り当てられます。そのURLに /api/~ とすれば実行されているのがわかるでしょう。

おわり。


本当はやりたかったこと

なんというたちの悪いチュートリアルもどき記事なんでしょう。もう少し書きます。

今回のアドベントカレンダーにタイトル登録した時点で、本当は「API PlatformはAWS API Gatewayと互換している」というのを実験したかったんです。
(API Platformと紛らわしいので、「AWS API Gateway」と書くようにします)

https://api-platform.com/docs/core/openapi/#compatibility-layer-with-amazon-api-gateway

AWS API Gateway supports OpenAPI partially, but it requires some changes. API Platform provides a way to be compatible with Amazon API Gateway.

To enable API Gateway compatibility on your OpenAPI docs, add api_gateway=true as query parameter: http://www.example.com/docs.jsonopenapi?api_gateway=true. The flag --api-gateway is also available through the command-line.

CDKも含めてデプロイできたらおいしいのでは?と思いまして。で、試してみたんですが、動かなかったんですよ。

先に結論

  • OpenAPIの持ち運びがうまくいかないことへ対応する労力ゥ…
    • AWS側のOpenAPIの解釈がアレなのかな???
  • そもそもAWS API Gatewayって本当に必要か?
    • 今回に限らず、フルスタックなWebフレームワーク使ってるなら要らないんじゃ
    • 今はLambda Function URLsがあるし…
      • CloudFrontと組み合わせて使えばいいよね

?api_gateway=trueオプションをつけたJSONをAWS API Gatewayは理解してくれない

オプションの有無でdiffを取ってみると、確かにAWS API Gateway向けっぽいJSONが吐き出されるんですが、これをAWSコンソールに貼り付けても "Invalid OpenAPI input." と言われるだけでした。

スクショを見て頂くとわかると思うんですが、OpenAPIのバージョンが "3.1.0"指定になっています。これは、(おそらく)AWS API Gatewayは対応していない(はず)です。

単純に、"3.0.0"に書き換えると以下のようなエラーになりました。

Warnings found during import: Parse issue: attribute components.schemas.Review.owl:maxCardinality is unexpected Parse issue: attribute components.schemas.Reviewjsonld.owl:maxCardinality is unexpected Parse issue: attribute basePath is unexpected Parse issue: attribute paths.'/api/books'(get).responses.200.content.schema.type is not of type string Parse issue: attribute paths.'/api/reviews'(get).responses.200.content.schema.type is not of type string Parse issue: attribute components.schemas.Book.type is not of type string Parse issue: attribute components.schemas.Review.type is not of type string Parse issue: attribute components.schemas.Bookjsonld.type is not of type string Parse issue: attribute components.schemas.Reviewjsonld.type is not of type string

うーん、わからん!となったので諦めました。

他にも

OpenAPIのバージョンを2にすればいいのかな、と思い

https://api-platform.com/docs/core/openapi/#using-the-openapi-command

If you want to use the old OpenAPI v2 (Swagger) JSON format, use:

docker compose exec php \
    bin/console api:swagger:export

とあったので、bin/console api:swagger:exportを実行すると、api:swaggerの名前空間自体がありませんでした。(API Platform v3.2)

また、api:openapi:exportには--spec-versionというオプションもあるのですが、

--spec-version[=SPEC-VERSION]  Open API version to use (2 or 3) (2 is deprecated) [default: "3"]

この--spec-versionを利用しているコードが見つかりませんでした。まあ、古いバージョンを使うのはどうかと思うので…。

蛇足

この辺りを掘っていたら、わりと直近のissueを見つけまして

https://github.com/api-platform/core/issues/5978

OpenAPIはツラみがあるなと。幸せにOpenAPIを利活用できている人っているんだろうか、という気持ちになりました。

Discussion