2 min read
Working With Third Parties
When integrating with third-party services, structure their code as self-contained mini domains within your application. Each third party gets its own folder, containing the service class, any data transfer objects, and value objects it needs.
For example, a Mailchimp integration might produce the following folder structure:
- Services
- Mailchimp
- DataTransferObject
- ValueObject
- MailchimpService.php
- MailchimpClient.php
- Mailchimp
Mailchimp Client
The MailchimpClient class stores the authentication credentials and default headers for the API.
namespace App\Services\Mailchimp; use GuzzleHttp\Client; class MailchimpClient extends Client { public function __construct(array $config = []) { parent::__construct([ 'timeout' => 30, 'connect_timeout' => 1, 'base_uri' => 'https://<dc>.api.mailchimp.com/3.0/', 'headers' => [ 'Content-Type' => 'application/json', 'Accept' => 'application/json', 'Authorization' => 'Bearer: ' . config('services.mailchimp.secret'), ], ]); } }
Mailchimp Service
The service class interacts with the Mailchimp API and performs operations such as sending campaigns, managing lists, and retrieving analytics.
namespace App\Services\Mailchimp; class MailchimpService { public function __construct(private readonly MailchimpClient $client) {} public function createCampaign(array $data): CampaignData { $response = $this->client->post('/campaigns', [ 'json' => $data, ]); return new CampaignData(json_decode($response->getBody()->getContents(), true)); } // Other methods for interacting with the Mailchimp API }
Data Transfer Objects
Use Data Transfer Objects (DTOs) to encapsulate the data sent to and from the Mailchimp API.
namespace App\Services\Mailchimp\DataTransferObject; class CampaignData { public function __construct( public readonly string $id, public readonly string $name, public readonly string $status, ) { } }
Value Objects
Use Value Objects (VOs) to represent concepts in your domain with a clear and explicit API.
namespace App\Services\Mailchimp\ValueObject; class CampaignStatus { private function __construct(private readonly string $value) { } public static function create(string $value): self { // Validate and sanitise the value return new self($value); } public function getValue(): string { return $this->value; } }