I'm writing an integration with a 3rd party API Gateway, and in an effort to make it as decoupled as possible (and to be able to change the provider in the future), I created 3 interfaces that will contain methods for reading, writing and deleting from the gateway (because there are a lot of methods that I need to use so I don't want to cram everything in one large interface and violate interface segregation principle). The API Gateway is used to handle app creation and other CRUD operations.
And I'm not sure what is the best way to move forward. I can create an interface like this
interface Api_Gateway_Create {
public function create_app( string $organization, string $developer_id, string $body );
// other methods.
}
And then, when doing a concrete implementation, I will create a class that implements this, and when I need to use it, I need to provide the three arguments.
This seems a bit constricting. What if, when I replace the provider, I no longer need the $developer_id
? I could set all the arguments with some default value
interface Api_Gateway_Create {
public function create_app( string $organization,
string $developer_id = 'some-default-value',
string $body = 'some-default-value' );
// other methods.
}
But that means that I'll end up with arguments I don't need potentially and that could mess up my implementation.
The last thing that came to mind is that I could just put a variadic, and then let the implementation take care of the arguments
interface Api_Gateway_Create {
public function create_app( ...$arguments_list );
// other methods.
}
In the implementation I'd have
class Create_App_Implementation1 implements Api_Gateway_Create {
public function create_app( ...$arguments_list ) {
list( $organization, $developer_id, $body ) = $arguments;
// Some business logic.
}
}
or
class Create_App_Implementation2 implements Api_Gateway_Create {
public function create_app( ...$arguments_list ) {
list( $organization, $app_key, $body ) = $arguments;
// Some business logic.
}
}
That way I don't need to care if my provider offers these arguments, because I'll just implement the ones I need.
This however presents another problem. In the consuming code, say a class that will use create_app()
method via dependency injection, I need to make extra care that the correct values are passed. And this is not future proof, as I'd need to change the code in the consuming class as well (which to me seems like the opposite intention of the interface).
With first one I will never have to change the consuming code, because I don't care what provider I'm using, if I'm expecting the same result (based on the same input arguments). But as I've mentioned, this seems a bit constricting. Two providers could have different way of handling this.
Did anybody have to face this kind of thing and what is the industry standard of handling this?
I'm writing in PHP, but I think Java could also be suited because of its object oriented nature.