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.