Let's dive right into an example.
I was working with third party JSON data which arrives from Webhook request. That data contains information about a Customer. Our interest was to get the "Phone Number" of that customer.
NOTE: this is third party data and we have no control over it.
There were four possible places where we could find Phone Number in that data.
- Directly on incoming data object ( first level )
- In "Customer" object inside data object
- In "shipping_address" object inside data object
- In "billing_address" object
These objects may or may not exist all in same time in a Webhook therefore I had to check with property_exists
.
protected static function extractPhone(object $webhookData): ?string
{
if($webhookData->phone){
return $webhookData->phone;
}
if(property_exists($webhookData,'customer') && $webhookData->customer->phone){
return $webhookData->customer->phone;
}
if(property_exists($webhookData, 'shipping_address') && $webhookData->shipping_address->phone){
return $webhookData->shipping_address->phone;
}
if(property_exists($webhookData, 'billing_address') && $webhookData->billing_address->phone){
return $webhookData->billing_address->phone;
}
return null;
}
Now let's refactor this code with "lookup" array.
We can make an array of "properties" that we need to check, right?
$lookupProperties = ['customer', 'shipping_address', 'billing_address'];
and then loop over these properties like below:
foreach ($lookupProperties as $lookupProperty){
if(property_exists($lookupProperty, $webhookData) && $webhookData->{$lookupProperty}->phone){
return $webhookData->{$lookupProperty}->phone;
}
}
Now our method looks like below:
protected static function extractPhone(object $webhookData): ?string
{
if($webhookData->phone){
return $webhookData->phone;
}
$lookupProperties = ['customer', 'shipping_address', 'billing_address'];
foreach ($lookupProperties as $lookupProperty){
if(property_exists($lookupProperty, $webhookData) && $webhookData->{$lookupProperty}->phone){
return $webhookData->{$lookupProperty}->phone;
}
}
return null;
}
Less lines of code and we have the ability to just add new property in $lookupProperties
if third party data changes in future.
Oldest comments (2)
Thanks
That request data looks to be a handful to deal with and raises some questions about the design of the data:
After we've accepted the fact the data is what it is, we still have at least one big issue to handle.
To me it seems there's not much room to move around the problem. We'll have to parse the data somehow and it's going to be messy.
The trade off looks to be around "explicit vs. dynamic" algorithm.