FOSRestBundle,生成 URL 到创建的资源
FOSRestBundle, generate URL to created resource
我正在使用 Symfony 和 FOSRestBundle 创建 REST API,我对两者都非常陌生。
现在我想知道如何为我刚刚创建的资源生成 URL。路线设置如下:
# app/config/routing.yml
characters:
type: rest
prefix: /api
resource: "@Optc/Resources/config/routing/characters_routing.yml"
NelmioApiDocBundle:
prefix: /api/doc
resource: "@NelmioApiDocBundle/Resources/config/routing.yml"
# Resources/Optc/Resources/config/routing/characters_routing.yml
characters:
type: rest
resource: Optc\Controller\CharactersController
创建资源的角色控制器部分:
$character = new Character();
$form = $this->createForm(new CharacterType(), $character);
$form->bind($data);
if ($form->isValid()) {
$em = $this->getDoctrine()->getManager();
$em->persist($character);
$em->flush();
$response->headers->set('Location', $this->generateUrl('get_characters', array('id' => $user->getId()), true));
$view = $this->view($character, 200);
return $this->handleView($view);
}
更新:完整控制器代码:
<?php
namespace Optc\Controller;
use FOS\RestBundle\Controller\Annotations\QueryParam;
use FOS\RestBundle\Controller\FOSRestController;
use Nelmio\ApiDocBundle\Annotation\ApiDoc;
use Optc\Entity\Character;
use Optc\Form\CharacterType;
use Optc\HttpFoundation\File\Base64File;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpKernel\Exception\HttpException;
/**
* Characters Controller
*/
class CharactersController extends FOSRestController
{
/**
* Get the list of characters.
*
* @param string $page integer with the page number (requires param_fetcher_listener: force)
*
* @return array data
*
* @QueryParam(name="page", requirements="\d+", default="1", description="Page number of the overview.")
* @ApiDoc()
*/
public function getCharactersAction($page)
{
$characters = $this
->getDoctrine()
->getRepository('Optc:Character')
->findAll();
$view = $this->view($characters, 200);
return $this->handleView($view);
}
public function getCharacterAction($id)
{
$character = $this
->getDoctrine()
->getRepository('Optc:Character')
->findOneById($id);
if (!$character) {
throw new HttpException(404, sprintf('Character with id %d not found!', $id));
}
$view = $this->view($character, 200);
return $this->handleView($view);
}
/**
* Create a new character.
*
* @param Request $request
*
* @return View view instance
*
* @ApiDoc()
*/
public function postCharacterAction(Request $request)
{
$data = $request->request->all();
// If the request contains image date, first convert it from its base64 enconding to a real file
if ($request->request->has('image') && $request->request->get('id')) {
$imagePath = realpath($this->get('kernel')->getRootDir() . '/../web'.$this->container->getParameter('upload_path_characters')).'/'.$request->request->get('id');
$file = Base64File::create($imagePath, $request->request->get('image'));
$data['image'] = $file;
}
$character = new Character();
$form = $this->createForm(new CharacterType(), $character);
$form->bind($data);
var_dump($form->isValid());
var_dump($form->getErrorsAsString());
var_dump($this->generateUrl('get_characters', array('id' => $character->getId()), true));
die();
if ($form->isValid()) {
$em = $this->getDoctrine()->getManager();
$em->persist($character);
$em->flush();
$response->headers->set('Location', $this->generateUrl('acme_demo_user_get', array('id' => $user->getId()), true));
$view = $this->view($character, 200);
return $this->handleView($view);
}
else {
}
}
}
设置 Location header 的 generateUrl
部分与我预期的不太一样。它吐出 http://optc.local/api/characters?id=2. This will of course only list all resources instead. But what I want is http://optc.local/api/characters/2.
我该怎么做?好像我错过了一些简单的东西。
(顺便说一句,关于返回 Location header 的 PHP 部分来自 http://williamdurand.fr/2012/08/02/rest-apis-with-symfony2-the-right-way/,所以我预计这是"right" 方式。)
您必须使用 get_character
路线而不是 get_characters
路线,
我建议你是实现ClassResourceInterface
还是使用RouteResource
注解,可以使用方法名getAction
,cgetAction
(这只是一个建议)
您应该在终端中检查 app/console debug:router
以查看 symfony 为路由命名的名称
在我的例子中,它使用减号而不是下划线
即 get-character
我正在使用 Symfony 和 FOSRestBundle 创建 REST API,我对两者都非常陌生。
现在我想知道如何为我刚刚创建的资源生成 URL。路线设置如下:
# app/config/routing.yml
characters:
type: rest
prefix: /api
resource: "@Optc/Resources/config/routing/characters_routing.yml"
NelmioApiDocBundle:
prefix: /api/doc
resource: "@NelmioApiDocBundle/Resources/config/routing.yml"
# Resources/Optc/Resources/config/routing/characters_routing.yml
characters:
type: rest
resource: Optc\Controller\CharactersController
创建资源的角色控制器部分:
$character = new Character();
$form = $this->createForm(new CharacterType(), $character);
$form->bind($data);
if ($form->isValid()) {
$em = $this->getDoctrine()->getManager();
$em->persist($character);
$em->flush();
$response->headers->set('Location', $this->generateUrl('get_characters', array('id' => $user->getId()), true));
$view = $this->view($character, 200);
return $this->handleView($view);
}
更新:完整控制器代码:
<?php
namespace Optc\Controller;
use FOS\RestBundle\Controller\Annotations\QueryParam;
use FOS\RestBundle\Controller\FOSRestController;
use Nelmio\ApiDocBundle\Annotation\ApiDoc;
use Optc\Entity\Character;
use Optc\Form\CharacterType;
use Optc\HttpFoundation\File\Base64File;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpKernel\Exception\HttpException;
/**
* Characters Controller
*/
class CharactersController extends FOSRestController
{
/**
* Get the list of characters.
*
* @param string $page integer with the page number (requires param_fetcher_listener: force)
*
* @return array data
*
* @QueryParam(name="page", requirements="\d+", default="1", description="Page number of the overview.")
* @ApiDoc()
*/
public function getCharactersAction($page)
{
$characters = $this
->getDoctrine()
->getRepository('Optc:Character')
->findAll();
$view = $this->view($characters, 200);
return $this->handleView($view);
}
public function getCharacterAction($id)
{
$character = $this
->getDoctrine()
->getRepository('Optc:Character')
->findOneById($id);
if (!$character) {
throw new HttpException(404, sprintf('Character with id %d not found!', $id));
}
$view = $this->view($character, 200);
return $this->handleView($view);
}
/**
* Create a new character.
*
* @param Request $request
*
* @return View view instance
*
* @ApiDoc()
*/
public function postCharacterAction(Request $request)
{
$data = $request->request->all();
// If the request contains image date, first convert it from its base64 enconding to a real file
if ($request->request->has('image') && $request->request->get('id')) {
$imagePath = realpath($this->get('kernel')->getRootDir() . '/../web'.$this->container->getParameter('upload_path_characters')).'/'.$request->request->get('id');
$file = Base64File::create($imagePath, $request->request->get('image'));
$data['image'] = $file;
}
$character = new Character();
$form = $this->createForm(new CharacterType(), $character);
$form->bind($data);
var_dump($form->isValid());
var_dump($form->getErrorsAsString());
var_dump($this->generateUrl('get_characters', array('id' => $character->getId()), true));
die();
if ($form->isValid()) {
$em = $this->getDoctrine()->getManager();
$em->persist($character);
$em->flush();
$response->headers->set('Location', $this->generateUrl('acme_demo_user_get', array('id' => $user->getId()), true));
$view = $this->view($character, 200);
return $this->handleView($view);
}
else {
}
}
}
设置 Location header 的 generateUrl
部分与我预期的不太一样。它吐出 http://optc.local/api/characters?id=2. This will of course only list all resources instead. But what I want is http://optc.local/api/characters/2.
我该怎么做?好像我错过了一些简单的东西。
(顺便说一句,关于返回 Location header 的 PHP 部分来自 http://williamdurand.fr/2012/08/02/rest-apis-with-symfony2-the-right-way/,所以我预计这是"right" 方式。)
您必须使用 get_character
路线而不是 get_characters
路线,
我建议你是实现ClassResourceInterface
还是使用RouteResource
注解,可以使用方法名getAction
,cgetAction
(这只是一个建议)
您应该在终端中检查 app/console debug:router
以查看 symfony 为路由命名的名称
在我的例子中,它使用减号而不是下划线
即 get-character