Symfony Advent Calendar 2019 9日目の記事です。
昨日は idaniさんのsymfony/mailerでbase64やiso-2022-jpを試してみる でした。

ルーティングのプリフィクスを特定ディレクトリ配下に一括で効かせたい

Symfony4ではアプリケーション内は基本的にバンドルレスで開発するのがデフォルトになったので、大きめのアプリケーションを開発していると src/Controller ディレクトリ内が混雑しがちですね。 そうなると、ディレクトリ分けをしたくなるのが人情です。

メジャーなディレクトリ戦略には機能ごと( src/Controller/Usersrc/Controller/Group とか)と権限ごと( src/Controller/Api とか src/Controller/Admin とか)がありますが、後者の分け方をした場合に、ディレクトリ内のコントローラアクションのroutingにまとめてプリフィクスを付けたい場合は多いと思います。
たとえば src/Controller/Api にあるコントローラにすべて /api をつけたりとか。

一見こんな感じで書けそうです。

# config/routes/annotations.yaml

controllers:
    resource: ../../src/Controller/
    type: annotation
api_controllers:
    resource: ../../src/Controller/Api
    type: annotation
    prefix: /api
    name_prefix: api_

src/Controller/Api/MyController.php

class MyController
{
    /**
     * @Route("/me", name="api_me")
     */
    public function me()
    {
        return [];
    }
}

しかし、これだとapi系は2つルーティングが定義されて、どっちのルーティングでもアクセスできるようになってしまいます。
具体的には

  • /api/me
  • /me

前者だけ使いたいのに後者も使えてしまうんです。
security.yaml でURLベースのアクセスコントロールを設定している場合にこれは困りますね :sweat_drops:

解決策

色々試行錯誤した結果、プリフィクスなしの全コントローラ指定の対象を src/Controller 直下のControllerファイルに限るという方法で回避できました。

# config/routes/annotations.yaml

controllers:
    resource: ../../src/Controller/*Controller.php
    type: annotation
api_controllers:
    resource: ../../src/Controller/Api
    type: annotation
    prefix: /api
    name_prefix: api_

まとめ

Symfonyの設定機構はかなり強力なので、やりたいと思ってできないことはほぼないと思ってます。 :smile: