【问题标题】:Symfony4 API Controller ParentSymfony4 API 控制器父级
【发布时间】:2018-10-31 12:50:12
【问题描述】:

我在 Symfony4 下实现了一个用于创建 API 的应用程序。我希望为 CRUD 创建一个父控制器,该控制器将在我的其他控制器上进行扩展,以避免复制所有 CRUD 代码。请问你有例子吗?这是我在控制器上所做的。

<?php

namespace App\Controller;

use App\Entity\Article;
use App\Exception\ResourceValidationException;
use FOS\RestBundle\Controller\Annotations as Rest;
use FOS\RestBundle\Controller\FOSRestController;
use FOS\RestBundle\Request\ParamFetcherInterface;
use Nelmio\ApiDocBundle\Annotation\Security;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\ParamConverter;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
use App\Representation\Articles;
use Symfony\Component\Validator\ConstraintViolationList;
use Swagger\Annotations as SWG;

class ArticleController extends FOSRestController
{
    /**
     * @Rest\Get(
     *     path="/api/articles/{id}",
     *     name="app_article_show",
     *     requirements={"id"="\d+"}
     * )
     * @Rest\View()
     *
     * @SWG\Response(
     *     response=200,
     *     description="Return article."
     * )
     * @SWG\Tag(name="Article")
     * @Security(name="Bearer")
     */
    public function showAction(Article $article)
    {
        return $article;
    }

    /**
     * @Rest\Post(
     *     path = "/api/articles",
     *     name= "app_article_create",
     *  )
     * @Rest\View(StatusCode= 201)
     * @ParamConverter(
     *     "article", converter="fos_rest.request_body",
     *     options={
                "validator"={ "groups"="Create"}
     *     }
     * )
     * @SWG\Response(
     *     response=200,
     *     description="Create article"
     * )
     * @SWG\Tag(name="Article")
     * @Security(name="Bearer")
     */
    public function createAction(Article $article, ConstraintViolationList $violations)
    {
        if (count($violations)) {
            $message = 'The JSON sent contain invalid data: ';
            foreach ($violations as $violation) {
                $message .= sprintf(
                    "Field %s: %s",
                    $violation->getPropertyPath(),
                    $violation->getMessage()
                );
            }
            throw new ResourceValidationException($message);
        }

        $em = $this->getDoctrine()->getManager();

        $em->persist($article);
        $em->flush();

        return $this->view(
            $article,
            Response::HTTP_CREATED,
            [
                'Location' => $this->generateUrl('app_article_create', ['id', $article->getId()], UrlGeneratorInterface::ABSOLUTE_URL)
            ]
        );
    }

    /**
     * @Rest\Get(
     *     path="/api/articles",
     *     name="app_article_list"
     * )
     * @Rest\QueryParam(
     *     name="keyword",
     *     requirements="[a-zA-Z0-9]",
     *     nullable=true,
     *     description="The keyword to search for."
     * )
     * @Rest\QueryParam(
     *     name="order",
     *     requirements="asc|desc",
     *     default="asc",
     *     description="Sort order (asc or desc)"
     * )
     * @Rest\QueryParam(
     *     name="limit",
     *     requirements="\d+",
     *     default="16",
     *     description="Max number of movies per page."
     * )
     * @Rest\QueryParam(
     *     name="offset",
     *     requirements="\d+",
     *     default="1",
     *     description="The pagination offset"
     * )
     * @Rest\View()
     * @SWG\Response(
     *     response=200,
     *     description="List all articles."
     * )
     * @SWG\Tag(name="Article")
     * @Security(name="Bearer")
     */
    public function listAction(ParamFetcherInterface $paramFetcher)
    {
        $pager = $this->getDoctrine()->getRepository(Article::class)->search(
            $paramFetcher->get('keyword'),
            $paramFetcher->get('order'),
            $paramFetcher->get('limit'),
            $paramFetcher->get('offset')
        );

        return new Articles($pager);
    }
}

感谢您的帮助。

【问题讨论】:

  • 我认为这有很多问题。注释中的东西太多了。你也不应该把从数据库中获取东西的逻辑放在控制器中!你应该是一个依赖注入而不是 $this->getDoctrine() 这只是一个服务定位器模式。为什么要扩展这个控制器?这是针对文章的。我会在没有 FosRestBundle 的情况下重写整个东西来了解它是如何工作的,但是尝试对 symfony 中的 API 设计和一般的 symfony 进行更多研究。

标签: api symfony fosrestbundle symfony4


【解决方案1】:

在 Symfony 4 之前,您可以使用 Doctrine CRUD controller generation feature。如果您只是想要一个示例,请看一下。

现在您可以使用Symfony Maker Bundle作为新的替代方案。他们说 here 有一个新命令 ma​​ke:crud 并且他们改进了现有的 ma​​ke:form

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-01-25
    • 2023-03-28
    • 1970-01-01
    • 1970-01-01
    • 2018-08-08
    • 2018-10-17
    • 2012-03-26
    相关资源
    最近更新 更多