Last active
May 20, 2024 18:52
-
-
Save lfbn/a92776cbeeceb929c15454231160c35b to your computer and use it in GitHub Desktop.
[[php] Service layer with DTOs in Laravel] Article: https://medium.com/@luis.barros.nobrega/laravel-service-layer-with-dtos-and-validators-2c6303899a57 #laravel
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 App\Services\Dto; | |
abstract class AbstractDto | |
{ | |
/** | |
* AbstractRequestDto constructor. | |
* @param array $data | |
*/ | |
public function __construct(array $data) | |
{ | |
// We create a validator, with all the data we receive. | |
// The rules come from the child class. | |
$validator = Validator::make( | |
$data, | |
$this->configureValidatorRules() | |
); | |
// We now validate the data we receive, for this DTO. | |
// If it fails we throw an exception. | |
if (!$validator->validate()) { | |
throw new InvalidArgumentException( | |
'Error: ' . $validator->errors()->first() | |
); | |
} | |
// The data is valid. | |
// Now we map it. | |
if (!$this->map($data)) { | |
throw new InvalidArgumentException('The mapping failed'); | |
} | |
} | |
/* @return array */ | |
abstract protected function configureValidatorRules(): array; | |
/** | |
* @param array $data | |
* @return bool | |
*/ | |
abstract protected function map(array $data): bool; | |
} |
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 App\Services\Dto; | |
class CreateUserDto extends AbstractDto implements DtoInterface | |
{ | |
/* @var string */ | |
protected $email; | |
/* @return array */ | |
protected function configureValidatorRules(): array | |
{ | |
return [ | |
'email' => 'required' | |
]; | |
} | |
/** | |
* @inheritDoc | |
*/ | |
protected function map(array $data): bool | |
{ | |
$this->email = $data['email']; | |
return true; | |
} | |
} |
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 App\Services; | |
use InvalidArgumentException; | |
class CreateUserService implements ServiceInterface | |
{ | |
/** | |
* @var CreateUserDto | |
*/ | |
private $createUserDto; | |
/** | |
* CreateUserService constructor. | |
* @param CreateUserDto $createUserDto | |
*/ | |
public function __construct(CreateUserDto $createUserDto) | |
{ | |
$this->createUserDto = $createUserDto; | |
} | |
/** | |
* @return bool | |
*/ | |
public function execute(): bool | |
{ | |
// All is done. We create the user. | |
// Everything good. We return the result. | |
return true; | |
} | |
/** | |
* @param DtoInterface $dto | |
* @return ServiceInterface | |
*/ | |
public static function make(DtoInterface $dto): ServiceInterface | |
{ | |
// We check if this is a CreateUserDTO | |
if (!$dto instanceof CreateUserDto) { | |
throw new InvalidArgumentException('CreateUserService needs to receive a CreateUserDto.'); | |
} | |
// All good. We create the instance, and tell the IDE the type of our DTO. | |
/* @var CreateUserDto $dto */ | |
return new CreateUserService($dto); | |
} | |
} |
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 App\Services\Dto; | |
interface DtoInterface | |
{ | |
} |
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 | |
use App\Services\Dto\CreateUserDto; | |
use use App\Services\CreateUserService; | |
// First, we create the DTO. We need it to use the service. | |
$createUserDto = new CreateUserDto( | |
['email' => '[email protected]'] | |
); | |
// Now we have the DTO. We also know that he is valid. | |
// Let's make our service, and execute it. | |
$createUserService = CreateUserService::make($createUserDto); | |
$createUserService->execute(); |
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 App\Services; | |
interface ServiceInterface | |
{ | |
/** | |
* @return bool | |
*/ | |
public function execute(): bool; | |
/** | |
* @param DtoInterface $dto | |
* @return ServiceInterface | |
*/ | |
public static function make(DtoInterface $dto): ServiceInterface; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment