【发布时间】:2014-03-10 22:48:01
【问题描述】:
我目前正在使用 Symfony2 创建(并学习如何)一个 REST API。我正在使用 FOSRestBundle,并创建了一个“ApiControllerBase.php”,其中包含以下内容:
<?php
namespace Utopya\UtopyaBundle\Controller;
use FOS\RestBundle\Controller\FOSRestController;
use FOS\RestBundle\View\View;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormTypeInterface;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
/**
* Class ApiControllerBase
*
* @package Utopya\UtopyaBundle\Controller
*/
abstract class ApiControllerBase extends FOSRestController
{
/**
* @param string $entityName
* @param string $entityClass
*
* @return array
* @throws NotFoundHttpException
*/
protected function getObjects($entityName, $entityClass)
{
$dataRepository = $this->container->get("doctrine")->getRepository($entityClass);
$entityName = $entityName."s";
$data = $dataRepository->findAll();
foreach ($data as $object) {
if (!$object instanceof $entityClass) {
throw new NotFoundHttpException("$entityName not found");
}
}
return array($entityName => $data);
}
/**
* @param string $entityName
* @param string $entityClass
* @param integer $id
*
* @return array
* @throws NotFoundHttpException
*/
protected function getObject($entityName, $entityClass, $id)
{
$dataRepository = $this->container->get("doctrine")->getRepository($entityClass);
$data = $dataRepository->find($id);
if (!$data instanceof $entityClass) {
throw new NotFoundHttpException("$entityName not found");
}
return array($entityClass => $data);
}
/**
* @param FormTypeInterface $objectForm
* @param mixed $object
* @param string $route
*
* @return Response
*/
protected function processForm(FormTypeInterface $objectForm, $object, $route)
{
$statusCode = $object->getId() ? 204 : 201;
$em = $this->getDoctrine()->getManager();
$form = $this->createForm($objectForm, $object);
$form->submit($this->container->get('request_stack')->getCurrentRequest());
if ($form->isValid()) {
$em->persist($object);
$em->flush();
$response = new Response();
$response->setStatusCode($statusCode);
// set the `Location` header only when creating new resources
if (201 === $statusCode) {
$response->headers->set('Location',
$this->generateUrl(
$route, array('id' => $object->getId(), '_format' => 'json'),
true // absolute
)
);
}
return $response;
}
return View::create($form, 400);
}
}
这处理获取一个具有给定 id 的对象、所有对象并处理一个表单。但是要使用它,我必须根据需要创建尽可能多的控制器。举例:GameController。
<?php
namespace Utopya\UtopyaBundle\Controller;
use FOS\RestBundle\Controller\FOSRestController;
use FOS\RestBundle\Controller\Annotations as Rest;
use FOS\RestBundle\View\View;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
use Utopya\UtopyaBundle\Entity\Game;
use Utopya\UtopyaBundle\Form\GameType;
/**
* Class GameController
*
* @package Utopya\UtopyaBundle\Controller
*/
class GameController extends ApiControllerBase
{
private $entityName = "Game";
private $entityClass = 'Utopya\UtopyaBundle\Entity\Game';
/**
* @Rest\View()
*/
public function getGamesAction()
{
return $this->getObjects($this->entityName, $this->entityClass);
}
/**
* @param int $id
*
* @return array
* @throws \Symfony\Component\HttpKernel\Exception\NotFoundHttpException
* @Rest\View()
*/
public function getGameAction($id)
{
return $this->getObject($this->entityName, $this->entityClass, $id);
}
/**
* @return mixed
*/
public function postGameAction()
{
return $this->processForm(new GameType(), new Game(), "get_game");
}
}
这听起来对我来说不是那么糟糕,但有一个主要问题:如果我想创建另一个控制器(例如服务器或用户或角色),我将不得不做同样的过程,我不想因为这将是相同的逻辑。
另一个“可能”的问题可能是我的 $entityName 和 $entityClass。
有什么想法或者我可以做得更好吗?
谢谢!
===== 编辑 1 =====
我想我已经下定决心了。对于那些基础控制器。我希望能够“配置”而不是“重复”。
例如,我可以使用以下内容在 config.yml 中创建一个新节点:
#config.yml
mynode:
game:
entity: 'Utopya\UtopyaBundle\Entity\Game'
这是一个非常基本的示例,但是否可以通过 3 个方法路由(getGame、getGames、postGame)将其转换为我的 GameController?
如果我真的可以通过这种方式实现,我只想要一些线索,如果可以,使用哪些组件? (配置、路由器等)
如果没有,我该怎么办? :)
谢谢!
【问题讨论】:
-
看看 SyliusResourceBundle ;)
-
谢谢,我会看看这个:)
-
它可能不能直接用于您的项目,但它可以为您提供提示。 Sylius 是一个大型的电子商务项目,大部分请求都由
ResourceController处理。
标签: php symfony dry fosrestbundle