Symfony4 - где обрабатывать полезную нагрузку в остальных API - PullRequest
0 голосов
/ 05 сентября 2018

Я работал над успокоительным API, я хотел бы знать, где я должен обрабатывать полезную нагрузку после проверки. Прямо сейчас это выглядит примерно так:

// src/Controller/ExampleController.php
public function create(Request $request, EntityManagerInterface $manager)
{
    // the getPayload gonna return a object representing my data
    // already validate, ready to be processed
    $data = $this->getPayload()

    $exampleEntity = new ExampleEntity();
    $exampleEntity
        ->setUser($this->getUser())
        ->setBook($data->book);
    $manager->persist($exampleEntity);
    $manager->flush();

    return new JsonResponse($example->getResult());
}

Мне посоветовали создать сервис для обработки данных и не использовать напрямую в контроллере. Я на самом деле хотел бы отделить данные вне контроллера, но тогда я должен создать службу для каждого контроллера? как то так:

// src/Controller/SomeController.php
public function create(Request $request, \App\Service\Example $example)
{
    // the getPayload gonna return a object representing my data
    // already validate, ready to be processed
    $data = $this->getPayload()
    $example->setPayload($data);
    $example->process();

    return new JsonResponse($example->getResult());
}

У меня есть другой вопрос, должен ли я проверять идентификаторы, например, если я получаю тело json, передающее идентификатор книги, если я создаю новое ограничение, чтобы проверить, существует ли книга, это потребует запроса в базе данных (потому что я проверяю полезную нагрузку автоматически, прежде чем она попадет в контроллер), и еще один запрос позже, чтобы фактически создать отношение. Пример:

// src/Controller/ExampleController.php
public function create(
    Request $request,
    ExampleReposiry $repository,
    EntityManagerInterface $manager)
{
    // the getPayload gonna return a object representing my data
    // already validate, ready to be processed
    $data = $this->getPayload()

    $exampleEntity = new ExampleEntity();
    $exampleEntity
        ->setUser($this->getUser())
        // $data->book is only the id, not the actually object book
        // this is the second time query for the object, the fist
        // time was inside the custom constraint that validate
        // to see if the id pass is valid.
        ->setBook($repository->findBy(['id' => $data->book]));
    $manager->persist($exampleEntity);
    $manager->flush();

    return new JsonResponse($example->getResult());
}

Или вместо этого я просто предполагаю, что идентификатор прохода книги действителен, а если нет, я просто выбрасываю исключение?

Пост, которому я следую, чтобы автоматически проверять данные здесь

Ответы [ 2 ]

0 голосов
/ 06 сентября 2018

Это была моя основа реализации, на которую ответил @BentCoder. После того, как целый день на работе думаешь фабрика или нет фабрика? Я пытаюсь использовать фабричный шаблон, потому что:

  • умно следовать советам более опытных программистов (или хотя бы попробовать)
  • лучшее понимание шаблона
  • попробуйте новые вещи (это побочный проект, так что все в порядке)

    // src/Controller/ExampleController.php
    public function create(\App\Service\Example $exampleService)
    {
        $exampleService->process($this->getPayload());
        // .. do something
    }
    
    // src/Service/Example.php
    public function process(App\Model\ExampleInterface $data)
    {
        // factory was receive via dependency injection in the constructor
        $objects = $this->factory->create($data);
        // .. do something
    }
    
    // src/Model/Example/Create.php
    class Create implements App\Model\ExampleInterface
    {
        public $property1;
        public $property2;
    }
    
    // src/Model/Example/Update.php
    class Update implements App\Model\ExampleInterface
    {
        public $property2;
    }
    
    // src/Factory/ExampleFactory.php
    public function create(App\Model\ExampleInterface $data)
    {
        if ($data instanceof App\Model\Example\Create::class) (
            // .. return a array of instantiated object
        } elseif ($data instanceof App\Model\Example\Update::class) {
            // .. returm only one object
        }
    }
    
0 голосов
/ 05 сентября 2018

Мне посоветовали создать сервис для обработки данных и не использовать напрямую в контроллере. Я на самом деле хотел бы отделить данные вне контроллера, но тогда я должен создать службу для каждого контроллера?

Или вместо этого я просто предполагаю, что идентификатор прохода книги действителен, а если нет, я просто выбрасываю исключение?

Я бы разделил обязанности следующим образом.

  1. Создайте класс ExampleService (где имеет место бизнес-логика) и внедрите его в ExampleController.
  2. Передайте проверенный набор данных в класс ExampleService.
  3. Проверьте, есть ли идентификатор книги в БД. В противном случае создайте исключение.
  4. Создайте класс ExampleFactory (где осуществляется сопоставление данных) и вставьте его в ExampleService.
  5. Передайте ваш набор данных в ExampleFactory, чтобы он возвратил ExampleEntity экземпляр.
  6. Позвоните persist и flush на ExampleEntity экземпляр. Предполагая, что вы уже внедрили класс ExampleRepository в класс ExampleService.

Затем сделайте все, что вам нужно, и верните Response::HTTP_CREATED в ExampleController.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...