Я работаю над микросервисом на основе Symfony 4.1.0, и у него есть следующий REST API, определенный в config / routes.yaml:
import:
path: /sip/calls/
controller: App\Controller\ApiController::import
methods: [POST]
Проблема в том, что запрос POST к /sip/calls вызывает NotFoundHttpException (маршрут для «POST / sip / звонков» не найден). Если я удалю завершающую косую черту из пути маршрута в config / routes.yaml, запросы к /sip/calls пройдут, но /sip/calls/ перестанет работать.
Почему так себя ведет? Как заставить игнорировать косую черту или ее отсутствие?






Как объяснено в: Перенаправление URL-адресов с помощью косой черты в конце Symfony 4.1 обрабатывает это внутреннее, создавая перенаправление 301. Но проблема в том, что это перенаправление не работает для запросов POST.
Как упоминалось здесь Почему в HTTP нет перенаправления POST, теоретически вы можете использовать перенаправление 307 или 308, но у меня были некоторые проблемы с этим в прошлом, поэтому я выбрал простое решение с дублированным путем с завершающей косой чертой.
Это предполагаемое поведение, как указано @LukaszJakubek. Если вам нужно сопоставить маршрут в обоих направлениях, вы можете просто назначить несколько маршрутов, и это должно сработать:
#config/routes.yaml
with_slash:
path: test/
controller: App\Controller\TestController::something
methods: [POST]
without_slash:
path: test
controller: App\Controller\TestController::something
methods: [POST]
Результат при использовании команды отладки:
bin/console router:match /test --method=POST
[OK] Route "without_slash" matches
+--------------+---------------------------------------------------------+
| Property | Value |
+--------------+---------------------------------------------------------+
| Route Name | without_slash |
| Path | /test |
| Path Regex | #^/test$#sD |
| Host | ANY |
| Host Regex | |
| Scheme | ANY |
| Method | POST |
| Requirements | NO CUSTOM |
| Class | Symfony\Component\Routing\Route |
| Defaults | _controller: App\Controller\TestController::something |
| Options | compiler_class: Symfony\Component\Routing\RouteCompiler |
+--------------+---------------------------------------------------------+
bin/console router:match /test/ --method=POST
[OK] Route "with_slash" matches
+--------------+---------------------------------------------------------+
| Property | Value |
+--------------+---------------------------------------------------------+
| Route Name | with_slash |
| Path | /test/ |
| Path Regex | #^/test/$#sD |
| Host | ANY |
| Host Regex | |
| Scheme | ANY |
| Method | POST |
| Requirements | NO CUSTOM |
| Class | Symfony\Component\Routing\Route |
| Defaults | _controller: App\Controller\TestController::something |
| Options | compiler_class: Symfony\Component\Routing\RouteCompiler |
+--------------+---------------------------------------------------------+
Потрясающие. Похоже, это работает и с аннотациями. Спасибо.
это не работает для меня, когда используется префикс, т.е. маршрут, определенный в пакете и префикс в приложении, использующем этот пакет
@meridius Это зависит от того, как пакет предоставляет маршруты. Теоретически у вас должна быть возможность перезаписать их. Может быть, вы можете открыть новый вопрос с вашей конкретной проблемой, то есть какой пакет вызывает ваши проблемы и конфигурацию маршрутизации (и пакета)?
Это хорошо известная особенность. Вы можете поискать и прочитать некоторые обсуждения. Ваш маршрут действительно будет работать для GET, но не для POST. Печальный факт в том, что что касается http, добавление косой черты в конце действительно делает его другим ресурсом. Вы можете использовать магию регулярных выражений, чтобы обойти это, или просто определить два маршрута.