Based on @ocramius Handling optional input parameters in PHP with vimeo/psalm and azjezz/psl I tried to use the same approach for out API implementation also with shared SDK DTOs.
Using the same OptionalField
given from ocramius, we can leverage that to add optional fields into the json serialized response.
This way we also add the ability to work with
- absent values
- adding/updating values
- or removal of values
A Delivery
has a DeliveryId
and a possible Tracking
DTO. This Tracking
DTO holds a Carrier
.
But not all deliveries might have a Tracking
available for them. To avoid handling null values on receiver and api provider side
we can leverage the use of OptionalField
.
To be able to call json_encode
on Delivery
we need to make sure to only include the field with OptionalValue
if it even has a value.
So if OptionalValue::hasValue
returns true.
Otherwise we would again include the field with an absent value into the response having it null
, which is not correct.
So we need to to give the OptionalField::apply()
method a call back which adds the data into the return value for jsonSerializer()
.
public function jsonSerialize(): mixed
{
$data = new stdClass();
$valueExtractor = static fn(string $name, OptionalField $value): callable => static fn(mixed $value): mixed => $data->$name = $value;
foreach (get_object_vars($this) as $name => $value) {
if ($value instanceof OptionalField) {
// This only adds $data->$name = $value if OptionalField::hasValue === true
$value->apply($valueExtractor($name, $value));
continue;
}
$data->$name = $value;
}
return $data;
}
We need to also be aware that if we want the Tracking
to be empty, we need to make sure, that we can create it using Tracking::fromArray(null)
which just returns null
on creation for the OptionalField
.