4
I’m implementing two video service Apis (Youtube and Vimeo), and because it’s a layer of data, I thought it was ideal to create repositories for each one, with the API being the "source" of the data.
something like:
class YoutubeApiRepository implements VideoRepositoryContract
{
public function search(string $term): ?array
{
$YoutubeApi = new YoutubeApi;
return $YoutubeApi->findVideos('baby shark');
// return Google_Service_YouTube_SearchResult
}
}
class VimeoApiRepository implements VideoRepositoryContract
{
public function search(string $term): ?array
{
$VideoApi = new VimeoApiClient;
return $VideoApi->findAllByTerm('baby shark')
// return []
}
}
The "problem" is that each API has a return in a different format...
1 - Would it be wrong for a Repository to iterate and manipulate the results of these Apis to standardize them? or it would be better if attached to another class "transformative"?
2 - In the case of a transformative class, an interface and a concrete implementation are created for each repository, such as
would it be possible to standardize the past parameters? for example, Youtube
returns an instance of the Object Google_Service_YouTube_SearchResult
, already the Vimeo
returns a Array
""and any data could be passed to the transformer...
Example of the class "transformer":
Interface VideoResponseTransformer
{
public function transform($rawData): array
}
class YoutubeResponseTransformer implements VideoResponseTransformer
{
public function transform($rawData) //Google_Service_YouTube_SearchResult
{
foreach ($rawData as $video) {
....
}
}
}
class VimeoResponseTransformer implements VideoResponseTransformer
{
public function transform($rawData) //Array
{
foreach ($rawData as $video) {
....
}
}
}
Curiosity you are using in a framework?
– novic
Yes, I’m wearing Laravel
– Thiago
Not only that: https://laravel.com/docs/8.x/eloquent-resources#generating-Resources you need?
– novic
Thanks for the suggestion, I know there are Resources, but I wanted to know how to implement this independent framework solution
– Thiago
look at this is problematic:
YoutubeApiRepository implements VideoRepositoryContract
andclass VimeoApiRepository implements VideoRepositoryContract
the correct is that each repository implements exclusively its Interface, until it can extend of this one but, each one has its mainly to work with injection of dependency. The other part of formatting the data follows the example I quoted and if you can read this data you can format your way you are on the path but, some changes are missing in your code.– novic
I understood, only that this way, with different interfaces, these two classes would not be easily replaceable, right?
– Thiago
What do you mean? I don’t understand!
– novic
@Virgilionovic I wish these implementations could be replaced in a simple way, and being of the same type (same interface), I get it
– Thiago
Thiago does not !!! you ai are breaking the sole responsibility, in POO is said that each code solves a problem, and you are condensing everything into one, is what I said each concrete Class has its interface and this interface can extend from another standard type interface, because at the time of the injection you will specify the class that implements the concrete. Well that’s how I ride and what I see do, including the Laravel Framework itself is like this.
– novic
basically:
interface VideoRepositoryContract extends RepositoryContract
andclass YoutubeApiRepository implements VideoRepositoryContract
and so on, being thatRepositoryContract
is your main base.– novic
Ah one thing I saw these days in your code:
$YoutubeApi = new YoutubeApi;
and$VideoApi = new VimeoApiClient;
could be injected also and these two classes be designed in the same way. Good is an idea of how to use.– novic
@Virgilionovic but how is this instilling sole responsibility? Repository only returns the data, and the doubt is whether they can also manipulate them, and in Laravel I do not use the concrete class, the parameter passed is the Interface, and the Laravel service container can assemble a concrete class later
– Thiago
So I don’t think it makes much sense to have a generic repository interface, because each type has its characteristics (different interfaces), what do you think?
– Thiago