devmachine/guzzle-rottentomatoes-client
Lightweight PHP client for the Rotten Tomatoes API built on Guzzle 4. Create a client with your API key and call endpoints like movies search (e.g., query by title) to get structured movie data (ratings, release dates, posters, cast).
Installation:
composer require devmachine/guzzle-rottentomatoes-client:1.0.*
Ensure your composer.json includes the package under require.
API Key Setup:
.env file) and retrieve it via Laravel’s config() helper or environment variables.First Use Case: Fetch movie data for a specific title (e.g., "Terminator 3"):
use Devmachine\Guzzle\RottenTomatoes\RottenTomatoesClient;
$client = RottenTomatoesClient::factory(config('services.rottentomatoes.api_key'));
$result = $client->movies(['q' => 'Terminator 3']);
return $result['movies'][0]['title']; // Output: "Terminator 3 - Rise of the Machines"
Key Files:
vendor/devmachine/guzzle-rottentomatoes-client/src/Devmachine/Guzzle/RottenTomatoes/RottenTomatoesClient.php (core logic).Service Layer Integration: Create a Laravel service class to abstract API calls:
namespace App\Services;
use Devmachine\Guzzle\RottenTomatoes\RottenTomatoesClient;
class RottenTomatoesService {
protected $client;
public function __construct() {
$this->client = RottenTomatoesClient::factory(config('services.rottentomatoes.api_key'));
}
public function getMovieByTitle(string $title) {
return $this->client->movies(['q' => $title]);
}
}
Register the service in AppServiceProvider:
public function register() {
$this->app->singleton(RottenTomatoesService::class, function ($app) {
return new RottenTomatoesService();
});
}
Query Builder Pattern: Use the client’s methods to chain queries (e.g., fetch a movie and its reviews):
$movie = $this->rottentomatoesService->getMovieByTitle('Inception');
$reviews = $this->rottentomatoesService->client->movieReviews($movie['movies'][0]['id']);
Pagination Handling: Manually paginate results (since Guzzle 4 lacks built-in pagination):
$page = 1;
$results = [];
while (true) {
$response = $this->rottentomatoesService->client->movies(['page' => $page, 'q' => 'action']);
if (empty($response['movies'])) break;
$results = array_merge($results, $response['movies']);
$page++;
}
Caching Responses: Cache API responses to reduce calls (e.g., using Laravel’s cache):
$cacheKey = "rottentomatoes_movie_{$title}";
$movie = cache()->remember($cacheKey, now()->addHours(1), function () use ($title) {
return $this->rottentomatoesService->getMovieByTitle($title);
});
Error Handling: Wrap API calls in try-catch blocks to handle Guzzle exceptions:
try {
$result = $this->rottentomatoesService->client->movies(['q' => 'nonexistent']);
} catch (\GuzzleHttp\Exception\RequestException $e) {
Log::error("RottenTomatoes API Error: " . $e->getMessage());
return response()->json(['error' => 'API request failed'], 500);
}
Deprecated Guzzle Version:
API Key Exposure:
.env and config/services.php:
ROTTENTOMATOES_API_KEY=your_api_key_here
// config/services.php
'rottentomatoes' => [
'api_key' => env('ROTTENTOMATOES_API_KEY'),
];
Rate Limiting:
use GuzzleHttp\Exception\TooManyRequestsException;
try {
$response = $client->movies(['q' => 'test']);
} catch (TooManyRequestsException $e) {
sleep(2); // Wait before retrying
retry();
}
Endpoint Changes:
RottenTomatoesClient:
namespace App\Services;
use Devmachine\Guzzle\RottenTomatoes\RottenTomatoesClient;
class ExtendedRottenTomatoesClient extends RottenTomatoesClient {
public function customEndpoint(array $params = []) {
return $this->request('GET', '/custom/endpoint', $params);
}
}
Data Parsing:
null or empty arrays for missing fields.data_get helper for safe access:
$rating = data_get($movie, 'ratings.critics_score', 0);
Enable Guzzle Debugging: Add a middleware to log requests/responses:
$client->getEmitter()->attach(
new \GuzzleHttp\Middleware::tap(function ($request) {
Log::debug('RottenTomatoes Request:', [
'url' => (string) $request->getUri(),
'params' => $request->getQuery(),
]);
})
);
Validate API Responses:
Use Laravel’s Validator to ensure response structure:
$validator = Validator::make($result, [
'movies.*.id' => 'required|string',
'movies.*.title' => 'required|string',
]);
Test Locally: Use Rotten Tomatoes’ sandbox to test endpoints before production.
Custom Requests:
Override the request method to add headers or modify requests:
class CustomRottenTomatoesClient extends RottenTomatoesClient {
protected function request($method, $uri, array $options = []) {
$options['headers']['X-Custom-Header'] = 'value';
return parent::request($method, $uri, $options);
}
}
Response Transformers: Convert API responses to Eloquent models or DTOs:
$movieData = $this->rottentomatoesService->getMovieByTitle('Interstellar');
$movie = (new MovieTransformer())->transform($movieData['movies'][0]);
Mocking for Tests:
Use Laravel’s Mockery to mock the client in tests:
$mockClient = Mockery::mock(RottenTomatoesClient::class);
$mockClient->shouldReceive('movies')
->once()
->andReturn(['movies' => [$fakeMovieData]]);
$this->app->instance(RottenTomatoesClient::class, $mockClient);
How can I help you explore Laravel packages today?