gocanto / relay
Unify data transfer object that is framework agnostic.
Fund package maintenance!
gocanto
github.com/sponsors/gocanto
Installs: 2
Dependents: 0
Suggesters: 0
Security: 0
Stars: 14
Watchers: 2
Forks: 1
Open Issues: 0
Type:php-bundle
Requires
- php: ^7.4
- ext-json: *
- nesbot/carbon: ^2.32
- symfony/validator: ^5.0
Requires (Dev)
- friendsofphp/php-cs-fixer: ^2.0.0
- mockery/mockery: ^1.0.0
- phpmd/phpmd: ^2.0.0
- phpunit/phpunit: ^9.0.0
- squizlabs/php_codesniffer: ^3.0.0
- vimeo/psalm: ^3.0.0
This package is auto-updated.
Last update: 2024-11-20 16:53:47 UTC
README
Relay is a data transfer objects structure that allows you to consume third party API payloads and parse them into their proper type object throughout a promotion mapper to ensure given incoming data abides by its expected type.
How does it work?
Relay is a self-contained attribute bag that maps its values using promoters that parse given incoming payloads into valid data transfer objects. Thus, you will have the option to remove the ability to work with unstructured data in your application by using proper types through wrappers that take care of any sanitation and validation logic constraints.
What are promoters?
A promoter is a data structure that allows us to map given data with the desired data type. By doing so, we will be able
to guard unknown payloads using proper types. For instance, you can specify that a first_name
key value is the type
text
to prevent the transfer object from being created on constraints failures.
Furthermore, you will have the ability to mark keys value as Any
if you are not sure of the data type it belongs to.
Case of study
Let's imagine we are consuming a third party API from an event platform to persist it in our database. Usually, you will be given users information such as email, name or profile URL. This is a pretty challenging case scenario since you will have to validate and sanitize the incoming payload to avoid having inconsistent data in your application.
Now, if you are anything like me, you might be thinking of parsing the incoming payload into an array, and then validate key-value by accessing the array and asking whether we have got the valid information. Such as:
$payload = [ 'name' => 'Gustavo', 'email' => 'gustavoocanto@gmail.com', 'profile_url' => 'http://foo.com/gocanto', ]; if (isset($payload['name']) && is_string($payload['name'])) { //do something amazing! } //is_valid_email is a imaginary function that should check whether a given email is valid or not. if (isset($payload['email']) && is_valid_email($payload['email'])) { //do something amazing! } //is_valid_url is a imaginary function that should check whether a given URL is valid or not. if (isset($payload['profile_url']) && is_valid_email($payload['profile_url'])) { //do something amazing! }
As you can see here, this can go out hands pretty quickly for many reasons. To mention some, we could say the following:
- You will have to repeat yourself every time you need to reference this information in your app.
- These validations do not take into account more complicated validations. Such as, different type of emails, URL or more complex string rules.
- Having unstructured data promotes the way of introducing many bugs into your application by tapping functionality at any given time.
Nevertheless, we are good programmers and like to do better. Furthermore, we love working with
types
don't we?
Using relay to handle your payloads.
after you have installed the relay data transfer in your application, you will be able to consume the above payload like so
declare(strict_types=1); use Gocanto\Relay\Attributes; use Gocanto\Relay\Types\Url; use Gocanto\Relay\Types\Email; use Gocanto\Relay\Types\Text; use Gocanto\Relay\Promoter; $data = [ 'name' => 'Gustavo', 'email' => 'gustavoocanto@gmail.com', 'profile_url' => 'http://foo.com/gocanto', ]; class Payload extends Attributes { } $payload = new Payload($data, [ 'name' => Promoter::make(Text::class), 'email' => Promoter::make(Email::class), 'profile_url' => Promoter::make(Url::class), ]); /** @var Text $name */ $name = $payload->get('name'); /** @var Email $email */ $email = $payload->get('email'); /** @var Url $profileUrl */ $profileUrl = $payload->get('profile_url');
Furthermore, you will be given an Any object wrapper if the asked payload key does not have a specified mapping or was
marked as optional using the ::optional()
construct method
within the promoter object. See example
Note: Any key-value specified in your payload mapper is marked as required
If you would like to know more about the functionality and different uses, please click on here.
Supported types
- boolean
- integer
- Float (floating-point number, aka double)
- string
- mixed
- number
- Url
- Uuid
- Date
To learn more about their functionality, you can click on the following links:
Future scopes.
- Easier mapping mechanism.
- Add more types.
- Add tests for
dot
array access. - Have an idea?
Contributing
Please feel free to fork this package and contribute by submitting a pull request to enhance its functionality.
License
The MIT License (MIT). Please see License File for more information.
How can I thank you?
Why not star the github repo and share the link for this repository on Twitter?
Don't forget to follow me on twitter!
Thanks!
Gustavo Ocanto.