简体   繁体   English

Symfony4-在静态API中处理有效负载的位置

[英]Symfony4 - Where process the payload in restful api

I have been working on a restful api, I would like to know where should I process the payload after been validated. 我一直在研究一个宁静的api,我想知道验证后应该在哪里处理有效负载。 Right now it look something like this: 现在看起来像这样:

// 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());
}

I was adviced to create a service to process the data and don't use direct in the controller. 建议我创建一个服务来处理数据,不要在控制器中直接使用。 I actually like to separate the data outside the controller, but then should I create a service for each controller? 我实际上想在控制器外部分离数据,但是我应该为每个控制器创建一个服务吗? something like this: 像这样的东西:

// 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());
}

I have other question, should I validate identifiers, for example if I receive a json body passing the id of a book, if I create a new constraint to verify if the book exist it would require a query in the database (because i'm validating the payload automatically before it gets int he controller) and one more query later to actually create the relation. 我还有其他问题,是否应该验证标识符,例如,如果我收到传递书ID的json正文,是否创建新约束以验证书是否存在,则需要在数据库中进行查询(因为我是在有效负载到达控制器之前自动验证有效负载),然后再进行一次查询以实际创建关系。 Example: 例:

// 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());
}

Or instead of that I just assume that the id of the book pass is valid and if not I just throw an Exception? 或者,我只是假设图书通行证的ID有效,否则我就抛出异常?

The post that I follow to validate automatically the data here 我跟随以自动验证此处数据的帖子

I was adviced to create a service to process the data and don't use direct in the controller. 建议我创建一个服务来处理数据,不要在控制器中直接使用。 I actually like to separate the data outside the controller, but then should I create a service for each controller? 我实际上想在控制器外部分离数据,但是我应该为每个控制器创建一个服务吗?

Or instead of that I just assume that the id of the book pass is valid and if not I just throw an Exception? 或者,我只是假设图书通行证的ID有效,否则我就抛出异常?

I would separate responsibilities as follows. 我将职责划分如下。

  1. Create a ExampleService class (where business logic takes place) and inject it into ExampleController . 创建一个ExampleService类(发生业务逻辑的地方)并将其注入到ExampleController
  2. Pass you validated data-set to ExampleService class. 将经过验证的数据集传递给ExampleService类。
  3. Check if the id of the book in DB. 检查书籍ID是否在DB中。 Throw an exception otherwise. 否则抛出异常。
  4. Create a ExampleFactory class (where data mapping takes place) and inject it into ExampleService . 创建一个ExampleFactory类(在其中进行数据映射)并将其注入到ExampleService
  5. Pass your data-set to ExampleFactory so that it returns ExampleEntity instance. 将您的数据集传递给ExampleFactory以便它返回ExampleEntity实例。
  6. Call persist and flush on ExampleEntity instance. ExampleEntity实例上调用persistflush Assuming that you already injected ExampleRepository class into ExampleService class. 假设您已经将ExampleRepository类注入到ExampleService类中。

Then do whatever else you need to do and return Response::HTTP_CREATED in ExampleController . 然后执行您需要做的其他事情,并在ExampleController返回Response::HTTP_CREATED ExampleController

This was my implementation base on what @BentCoder answered. 这是我基于@BentCoder回答的实现。 After pass the whole day at work thinking factory or no factory ? 经过一天的工作后想到工厂还是没有工厂? I end up trying use factory pattern because: 我最终尝试使用工厂模式,因为:

  • it's smart follow advice of more experienced programmers (or give a try at least) 遵循经验更丰富的程序员的明智建议(或至少尝试一下)
  • better understanding of a pattern 更好地理解模式
  • try out new things (it's a side project so it's ok mess up) 尝试新事物(这是一个附带项目,所以可以把它搞砸了)

     // 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 } } 

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM