Last active
August 2, 2022 11:32
-
-
Save fesor/8c8632099530fa730181 to your computer and use it in GitHub Desktop.
DTO example
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
namespace SomeApp\Application\DTO; | |
use Symfony\Component\OptionsResolver\OptionsResolver; | |
abstract class AbstractRequest | |
{ | |
public function __construct(array $data) | |
{ | |
$options = new OptionsResolver(); | |
$this->configureOptions($options); | |
$this->map($options); | |
} | |
abstract protected function configureOptions(OptionsResolver $options); | |
protected function map(OptionsResolver $options) | |
{ | |
// just plain mapping, all other things | |
// like snake case to camel case convertion or keys aliases resolving | |
// should be done in controller | |
// values normalization could be done via option resolver's normalizers | |
$options->resolve($data); | |
foreach ($options->getDefinedOptions() as $prop) { | |
$this->$prop = $options[$prop]; | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
namespace SomeApp\Application\DTO\Something; | |
use Symfony\Component\OptionsResolver\OptionsResolver; | |
use SomeApp\Infrastructure\Security\UserSession; | |
class DoSomethingRequest extends AbstractRequest | |
{ | |
protected $userSession; | |
protected $foo; | |
protected $fooBar; | |
/** | |
* @param UserSession $userSession - id of user | |
* @param array $data - array of options to be resolved | |
*/ | |
public function __construct(UserSession $userSession, array $data) | |
{ | |
// this is only for example, | |
// I usually have UserSession object wich implements UserInterface | |
// UserSession isn't doctrine entity, it just data container which hydrates from JWT token | |
// It contains user Id, some other information (isAdmin flag for example) and so on. | |
$this->userSession = $userSession; | |
parent::__contruct($data); | |
} | |
protected function configureOptions(OptionsResolver $options) | |
{ | |
$options | |
->setRequired(['foo', 'bar']) | |
->setAllowedTypes([ | |
'foo' => 'string', | |
'fooBar' => ['int', 'string'] | |
]) | |
; | |
} | |
public function getUserID() | |
{ | |
return $this->userSession->getUserID(); | |
} | |
public function getFoo() | |
{ | |
return $this->foo; | |
} | |
public function getFooBar() | |
{ | |
return $this->fooBar; | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
class SomethingController extends Controller | |
{ | |
public function createSomething(Request $request) { | |
// handled via symfony/serializer in middleware | |
// or you can map it with jms serializer or just by yourself here in controller | |
$requestData = $request->request->all(); | |
// create request DTO | |
$requestDTO = new DoSomethingRequest($this->getUser(), $requestData); | |
// pass it to application layer, which will return response dto | |
$responseDTO = $this->get('something_maker')->doStuff($requestDTO); | |
return $responseDTO; // middleware will serialize it, or we can use JsonResponse and map data to array... | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
I've did not check the whole code, but you can improve your abstract request class.
First, what kind of request is it? A http request? I know, this is for demonstration purpose, but in that case the AbstractSomerRequest could be more luckily.
Based on this: (http://misko.hevery.com/code-reviewers-guide/flaw-constructor-does-real-work/) the constructor of this class should be:
public function __construct(array $data, OptionResolver $options)