yoanbernabeu / Airtable-Client-Bundle

Simple Client for Airtable API
MIT License
33 stars 12 forks source link

[HttpClient] Deal with ScopedClient #14

Closed ismail1432 closed 3 years ago

ismail1432 commented 3 years ago

At the moment we have to pass the base uri api.airtable.com/v0/ and the key and I think we can configure the HTTP client to already have these value see https://symfony.com/doc/current/http_client.html#scoping-client

yoanbernabeu commented 3 years ago

I think this is a great idea!

Have you ever implemented this outside of a Symfony project?

ismail1432 commented 3 years ago

Never but I can give a try 😁

yoanbernabeu commented 3 years ago

I want to see this and learn 😁

ismail1432 commented 3 years ago

The big advantage of using a scoped client is to let the responsibility to the Symfony Http Client to add token, content type and any other option when the request match the base uri.

I think we can improve the current AirtableClient by moving all method not related to a real HttpRequest outside, that means all method like findAll findBy... will be in a dedicated repository like an AirTableHttpRepository with this approach The repository doesn't care about passing $this->id or $this->key or Accept header... all of this stuff is the job of the HttpClient not the repository.

We have a good separation of concerns:

AirtableClient => Concrete call to the API AirtableHttpRepository => Prepare the query, return a Response with the desired format


class AirtableHttpRepository implements AirtableRepositoryInterface
{
    public function __construct(HttpClientInterface $httpClientSma, ObjectNormalizer $objectNormalizer)
    {
        $this->httpClient = $httpClient;
        $this->normalizer = $objectNormalizer;
    }

    public function findAll(string $table, ?string $view = null, ?string $dataClass = null): array;
  { 

       // remove passing $this->id
         $url = sprintf('%s%s', $table, null !== $view ? '?view='.$view : '');

       // remove request method from this class
        $response = $this->httpClient->request($url);

        return $this->mapRecordsToAirtableRecords($response->toArray()['records'], $dataClass);
  }
    public function findBy(string $table, string $field, string $value, ?string $dataClass = null): array;
 // and so on
}

class AirtableClient extends ScopingHttpClient
{
    public function __construct(HttpClientInterface $client, array $defaultOptionsByRegexp, string $defaultRegexp = null)
    {
        parent::__construct($client, $defaultOptionsByRegexp, $defaultRegexp);
    }
}

WDYT? I can open a PR to see difference and let you trying :+1: