![](/img/trans.png)
[英]How can I serve HTML and JSON requests from the same route, using Symfony 2 and FOSRestBundle, using headers in addition to the _format?
[英]How to return or display data in JSON format using FOSRestBundle
我正在使用Symfony2和FOSRestBundle在Restful API中工作。 我已經閱讀了視圖層文檔,但我不清楚如何處理API的輸出。 我想要實現的很簡單:顯示或返回或輸出結果作為有效的JSON。 這就是我在控制器上所擁有的:
<?php
/**
* RestAPI: Company.
*/
namespace PDI\PDOneBundle\Controller\Rest;
use FOS\RestBundle\Controller\FOSRestController;
use FOS\RestBundle\Request\ParamFetcherInterface;
use Nelmio\ApiDocBundle\Annotation\ApiDoc;
use FOS\RestBundle\Controller\Annotations\QueryParam;
use FOS\RestBundle\Controller\Annotations\Get;
class CompanyRestController extends FOSRestController
{
/**
* Gets all companies.
*
* @return array
*
* @ApiDoc(
* resource = true,
* https = true,
* description = "Gets all companies",
* statusCodes = {
* 200 = "Returned when successful",
* 400 = "Returned when errors"
* }
* )
* @Get("/api/v1/companies")
*
*/
public function getCompaniesAction()
{
$response = array();
$em = $this->getDoctrine()->getManager();
$entities = $em->getRepository('PDOneBundle:Company')->findAll();
if ($entities) {
foreach ($entities as $entity) {
$response['companies'][] = [
'id' => $entity->getId(),
'createdAt' => $entity->getCreatedAt(),
'updatedAt' => $entity->getUpdatedAt(),
'name' => $entity->getName(),
'logo_url' => $entity->getLogoUrl(),
'division' => $entity->getDivision(),
'inactive' => $entity->getInactive(),
];
}
$response['status'] = 'ok';
} else {
$response['status'] = 'error';
}
return $response;
}
}
如果我嘗試這個URL: /app_dev.php/api/v1/companies.json
我收到404錯誤:
{"code":404,"message":"No route found for \"GET\/api\/v1\/companies.json\""}
如果我嘗試此網址: https://reptool.dev/app_dev.php/api/v1/companies
: https://reptool.dev/app_dev.php/api/v1/companies
錯誤開啟:
無法找到模板“”。 500內部服務器錯誤 - InvalidArgumentException 3鏈接的異常:Twig_Error_Loader»InvalidArgumentException»InvalidArgumentException»
我也檢查了FOSRestBundleByExample,但沒有得到太多幫助。
我在這里缺少什么? 我如何實現我的需求? 有什么建議?
FOSRest配置
我忘了在config.yml
添加config.yml
:
#FOSRestBundle
fos_rest:
param_fetcher_listener: true
body_listener: true
format_listener:
rules:
- { path: ^/, priorities: [ json, html ], fallback_format: ~, prefer_extension: true }
media_type:
version_regex: '/(v|version)=(?P<version>[0-9\.]+)/'
body_converter:
enabled: true
validate: true
view:
mime_types:
json: ['application/json', 'application/json;version=1.0', 'application/json;version=1.1']
view_response_listener: 'force'
formats:
xml: false
json: true
templating_formats:
html: true
exception:
codes:
'Symfony\Component\Routing\Exception\ResourceNotFoundException': 404
'Doctrine\ORM\OptimisticLockException': HTTP_CONFLICT
messages:
'Symfony\Component\Routing\Exception\ResourceNotFoundException': true
allowed_methods_listener: true
access_denied_listener:
json: true
我感覺到你的痛苦。 我也遇到了麻煩。 一個重要的起點是配置。 這是我在實現中使用的內容。
fos_rest:
param_fetcher_listener: true
view:
mime_types:
json: ['application/json', 'application/json;version=1.0', 'application/json;version=1.1']
view_response_listener: 'force'
formats:
xml: false
json: true
templating_formats:
html: true
format_listener:
rules:
- { path: ^/, priorities: [ json, html ], fallback_format: ~, prefer_extension: true }
media_type:
version_regex: '/(v|version)=(?P<version>[0-9\.]+)/'
exception:
codes:
'Symfony\Component\Routing\Exception\ResourceNotFoundException': 404
'Doctrine\ORM\OptimisticLockException': HTTP_CONFLICT
messages:
'Symfony\Component\Routing\Exception\ResourceNotFoundException': true
allowed_methods_listener: true
access_denied_listener:
json: true
body_listener: true
在format_listener
如果您希望JSON成為默認響應,請確保首先在優先級中設置它。 否則,您的標頭每次都需要包含Accept: application/json
。 這可能是您嘗試使用twig渲染HTML輸出時出現樹枝錯誤的原因。
另外,請確保安裝了http://jmsyst.com/bundles/JMSSerializerBundle等序列化程序並將其包含在AppKernal中。
在你的控制器中,我發現像你一樣擴展FOSRestController最容易,但也返回一個視圖對象,而不是自己創建數組。 序列化器將為您處理所有這些。
/**
* RestAPI: Company.
*/
namespace PDI\PDOneBundle\Controller\Rest;
use FOS\RestBundle\Controller\FOSRestController;
use FOS\RestBundle\Request\ParamFetcherInterface;
use Nelmio\ApiDocBundle\Annotation\ApiDoc;
use FOS\RestBundle\Controller\Annotations\QueryParam;
use FOS\RestBundle\Controller\Annotations\Get;
class CompanyRestController extends FOSRestController
{
/**
* Gets all companies.
*
* @return array
*
* @ApiDoc(
* resource = true,
* https = true,
* description = "Gets all companies",
* statusCodes = {
* 200 = "Returned when successful",
* 400 = "Returned when errors"
* }
* )
* @Get("/api/v1/companies")
*
*/
public function getCompaniesAction()
{
$response = array();
$em = $this->getDoctrine()->getManager();
$entities = $em->getRepository('PDOneBundle:Company')->findAll();
if(!$entities)
{
return $this->view(null, 400);
}
return $this->view($entities, 200);
}
}
希望這會有幫助。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.