My Yii2 application (in PHP 7, so unfortunately I do not have strict types) receives from an API call responses which should be nested arrays looking like:
$response = [
'session' => [
'userData' => ['user_id' => 232, ...],
'sessionData => ['status' => 'ONGOING', 'details' => 'Some details here...', ...],
'additionalData' => [...]
]
]
Currently in my application logic, when I receive the response I manually check that each field exists and is of the required type. So for example I start by checking that $response['session']
exists and is an array, and I throw an exception if it doesn’t, so something like:
if (!array_key_exists($response, 'session')) {
throw new Exception('Invalid response: missing "session" key in response array.');
}
if (!is_array($response['session'])) {
throw new Exception('Invalid response: "session" is not an array in response array.');
}
Then I check for $response['session']['userData']
and I check that it’s an array, and so on. When I am certain that $response['session']['userData']['user_id']
exists, I also check that it is an integer, so I also do validation for the primitive received types.
I would like to decouple this logic from my main application, by having a separate model which stores all the primitive properties I want from the response and validates the primitive ones.
My problem is that I’m uncertain what would be the best design pattern to implement this.
My initial thought was to build a DTO-Hydrator-like pattern, so:
- A model (DTO) having as fields only the ‘primitive’ properties such as
user_id
,status
,details
, etc, but not the arrays likesession
,userData
. This model would only be responsible for validation of the primitive fields (so checking thatuser_id
is an integer for instance, checking that ‘status’ is in an array of admissible statuses, etc.) - A Hydrator model which is responsible for checking that all desired
primitive fields exist, and of course, that everything ‘in-between’
exists, and then loading the primitive fields into the DTO.
However, this approach seems overly complicated. For one thing, I would have to instantiate both the DTO and the Hydrator each time I have to handle a response in my application logic, which would still make that logic too cumbersome for what I want. Ideally I would like to only do something like
$model->process($response)
in my application logic, but in a way that is also an endorsed design pattern. So is there a way to do this without the (seeming) overcomplication of the DTO-Hydrator pattern?