Symfony 4 / FosREST:API 路由 return 404 但不是网络路由
Symfony 4 / FosREST : API routes return 404 but not web routes
我正在建立一个多语言的经典 symfony 4.3 项目(又名网站),所有路径都正常。我想用一个简单的 API REST 公开一些数据(只有 3,4 个路由使用 GET 方法)所以我安装了 FOSRestBundle 2.5。我知道这个版本与 SF 4.*.
兼容
问题是我的 API 路线 return 所有 404 但不是 "web" 路线。我浏览了 symfony 文档和 FOSREST 文档以及一些教程。
在 fos_rest.yaml 中,我在 rules
参数中声明了两种类型的路由。我已经在两个目录中分离了用于 Web 的控制器和用于 API 的控制器(这两个目录安装在 services.yaml 中)
这里是 FOS REST 配置:
config/packages/fos_rest.yaml
fos_rest:
routing_loader:
default_format: json
include_format: false
body_listener: true
format_listener:
rules:
- { path: '^/api', priorities: [ json ], fallback_format: json, prefer_extension: false }
- { path: '^/', priorities: [ 'html', '*/*'], fallback_format: ~, prefer_extension: true }
param_fetcher_listener: true
access_denied_listener:
json: true
view:
view_response_listener: 'force'
formats:
json: true
config/services.yaml:
services:
App\Controller\:
resource: '../src/Controller'
tags: ['controller.service_arguments']
App\ControllerApi\:
resource: '../src/ControllerApi'
tags: ['controller.service_arguments']
和注释定义:
config/routes/annotations.yaml
# https://symfony.com/doc/current/routing.html#localized-routing-i18n
web_controllers:
resource: ../../src/Controller/
type: annotation
prefix:
en: /
fr: /{_locale}
de: /{_locale}
es: /{_locale}
pt: /{_locale}
requirements:
_locale: '%app_locales%'
defaults:
_locale: '%locale%'
# Controller for Rest API
rest_controller:
resource: ../../src/ControllerApi/
type: annotation
prefix: /api
Web 控制器是基础和扩展 AbstractController
。对于 API 控制器,这里有一个例子:
namespace App\ControllerApi;
use FOS\RestBundle\Controller\AbstractFOSRestController;
use FOS\RestBundle\Controller\Annotations as Rest;
use FOS\RestBundle\View\View;
final class fooApiController extends AbstractFOSRestController
{
/**
* @param string $id
*
* @return View
*
* @Rest\Get("/demo/{$id}", name="api_demo")
*/
public function getSimpleDataById($id)
{
/** @var Dso $dso */
$data = $this->myCustomManager->getData($id);
if (!$data instanceof CustomEntity) {
throw new NotFoundHttpException();
}
return View::create($data, Response::HTTP_OK);
}
}
这是生成的路由示例(带有主页的示例):
www-data@php:~/symfony$ php bin/console debug:router | grep home
homepage.en ANY ANY ANY /
homepage.fr ANY ANY ANY /{_locale}/
homepage.de ANY ANY ANY /{_locale}/
homepage.es ANY ANY ANY /{_locale}/
homepage.pt ANY ANY ANY /{_locale}/
一切正常(网络的其他路由也是如此)。
这是 API:
www-data@php:~/symfony$ php bin/console debug:router | grep api
api_demo GET ANY ANY /api/demo/{$id}
所以我卷曲了两个:
curl --head http://symfony.local
HTTP/1.1 200 OK
Server: nginx
Content-Type: text/html; charset=UTF-8
Connection: keep-alive
X-Powered-By: PHP/7.2.14
Set-Cookie: PHPSESSID=336b94195892ebb5a3b4e7f2d2799fbb; path=/; HttpOnly; SameSite=lax
Cache-Control: max-age=0, must-revalidate, private, s-maxage=3600
Date: Fri, 19 Jul 2019 13:26:05 GMT
X-Debug-Token: 5653c7
# Works with others URL...
curl --head http://symfony.local/api/demo/m42
HTTP/1.1 404 Not Found
Server: nginx
Content-Type: application/json
Connection: keep-alive
X-Powered-By: PHP/7.2.14
Cache-Control: max-age=0, must-revalidate, private
Date: Fri, 19 Jul 2019 13:27:03 GMT
我没有找到错误。
感谢阅读和回答
我找到了一个起始解决方案。我在 fos_rest.yaml 上更改了配置文件:
fos_rest:
routing_loader:
default_format: json
include_format: false
body_listener: true
format_listener:
rules:
- { path: '^/api', priorities: [ json ], fallback_format: json, prefer_extension: true }
param_fetcher_listener: true
access_denied_listener:
json: true
view:
view_response_listener: true
formats:
json: true
zone:
- { path: ^/api/* }
我删除了规则“^/”并添加了区域。 404 不在这里。
控制器中的注释也有错误:
这是正确的语法:
/**
* @Rest\View()
* @Rest\Get("/demo/{id}", name="api_demo")
*
* @param string $id
*
* @return View
*/
public function getSimpleDataById(string $id): View
我正在建立一个多语言的经典 symfony 4.3 项目(又名网站),所有路径都正常。我想用一个简单的 API REST 公开一些数据(只有 3,4 个路由使用 GET 方法)所以我安装了 FOSRestBundle 2.5。我知道这个版本与 SF 4.*.
兼容问题是我的 API 路线 return 所有 404 但不是 "web" 路线。我浏览了 symfony 文档和 FOSREST 文档以及一些教程。
在 fos_rest.yaml 中,我在 rules
参数中声明了两种类型的路由。我已经在两个目录中分离了用于 Web 的控制器和用于 API 的控制器(这两个目录安装在 services.yaml 中)
这里是 FOS REST 配置: config/packages/fos_rest.yaml
fos_rest:
routing_loader:
default_format: json
include_format: false
body_listener: true
format_listener:
rules:
- { path: '^/api', priorities: [ json ], fallback_format: json, prefer_extension: false }
- { path: '^/', priorities: [ 'html', '*/*'], fallback_format: ~, prefer_extension: true }
param_fetcher_listener: true
access_denied_listener:
json: true
view:
view_response_listener: 'force'
formats:
json: true
config/services.yaml:
services:
App\Controller\:
resource: '../src/Controller'
tags: ['controller.service_arguments']
App\ControllerApi\:
resource: '../src/ControllerApi'
tags: ['controller.service_arguments']
和注释定义: config/routes/annotations.yaml
# https://symfony.com/doc/current/routing.html#localized-routing-i18n
web_controllers:
resource: ../../src/Controller/
type: annotation
prefix:
en: /
fr: /{_locale}
de: /{_locale}
es: /{_locale}
pt: /{_locale}
requirements:
_locale: '%app_locales%'
defaults:
_locale: '%locale%'
# Controller for Rest API
rest_controller:
resource: ../../src/ControllerApi/
type: annotation
prefix: /api
Web 控制器是基础和扩展 AbstractController
。对于 API 控制器,这里有一个例子:
namespace App\ControllerApi;
use FOS\RestBundle\Controller\AbstractFOSRestController;
use FOS\RestBundle\Controller\Annotations as Rest;
use FOS\RestBundle\View\View;
final class fooApiController extends AbstractFOSRestController
{
/**
* @param string $id
*
* @return View
*
* @Rest\Get("/demo/{$id}", name="api_demo")
*/
public function getSimpleDataById($id)
{
/** @var Dso $dso */
$data = $this->myCustomManager->getData($id);
if (!$data instanceof CustomEntity) {
throw new NotFoundHttpException();
}
return View::create($data, Response::HTTP_OK);
}
}
这是生成的路由示例(带有主页的示例):
www-data@php:~/symfony$ php bin/console debug:router | grep home
homepage.en ANY ANY ANY /
homepage.fr ANY ANY ANY /{_locale}/
homepage.de ANY ANY ANY /{_locale}/
homepage.es ANY ANY ANY /{_locale}/
homepage.pt ANY ANY ANY /{_locale}/
一切正常(网络的其他路由也是如此)。
这是 API:
www-data@php:~/symfony$ php bin/console debug:router | grep api
api_demo GET ANY ANY /api/demo/{$id}
所以我卷曲了两个:
curl --head http://symfony.local
HTTP/1.1 200 OK
Server: nginx
Content-Type: text/html; charset=UTF-8
Connection: keep-alive
X-Powered-By: PHP/7.2.14
Set-Cookie: PHPSESSID=336b94195892ebb5a3b4e7f2d2799fbb; path=/; HttpOnly; SameSite=lax
Cache-Control: max-age=0, must-revalidate, private, s-maxage=3600
Date: Fri, 19 Jul 2019 13:26:05 GMT
X-Debug-Token: 5653c7
# Works with others URL...
curl --head http://symfony.local/api/demo/m42
HTTP/1.1 404 Not Found
Server: nginx
Content-Type: application/json
Connection: keep-alive
X-Powered-By: PHP/7.2.14
Cache-Control: max-age=0, must-revalidate, private
Date: Fri, 19 Jul 2019 13:27:03 GMT
我没有找到错误。 感谢阅读和回答
我找到了一个起始解决方案。我在 fos_rest.yaml 上更改了配置文件:
fos_rest:
routing_loader:
default_format: json
include_format: false
body_listener: true
format_listener:
rules:
- { path: '^/api', priorities: [ json ], fallback_format: json, prefer_extension: true }
param_fetcher_listener: true
access_denied_listener:
json: true
view:
view_response_listener: true
formats:
json: true
zone:
- { path: ^/api/* }
我删除了规则“^/”并添加了区域。 404 不在这里。
控制器中的注释也有错误: 这是正确的语法:
/**
* @Rest\View()
* @Rest\Get("/demo/{id}", name="api_demo")
*
* @param string $id
*
* @return View
*/
public function getSimpleDataById(string $id): View