Installation Add the bundle via Composer:
composer require circleofnice/restclientbundle
Register the bundle in config/bundles.php:
return [
// ...
CircleOfNice\RestClientBundle\CircleOfNiceRestClientBundle::class => ['all' => true],
];
First Use Case
Inject the RestClient service into your controller or service:
use CircleOfNice\RestClientBundle\RestClient;
public function __construct(RestClient $restClient) {
$this->restClient = $restClient;
}
Make a simple GET request:
$response = $this->restClient->get('https://api.example.com/users');
$data = json_decode($response->getContent(), true);
Where to Look First
config/packages/circle_of_nice_rest_client.yaml for default settings (e.g., timeout, headers).src/RestClient.php for method signatures and response handling.Response object methods (e.g., getStatusCode(), getHeaders()).Basic CRUD Operations Use the intuitive HTTP method wrappers:
// Create
$response = $this->restClient->post('https://api.example.com/users', [
'name' => 'John Doe',
'email' => 'john@example.com'
]);
// Read
$response = $this->restClient->get('https://api.example.com/users/1');
// Update
$response = $this->restClient->put('https://api.example.com/users/1', [
'name' => 'Updated Name'
]);
// Delete
$response = $this->restClient->delete('https://api.example.com/users/1');
Handling Responses
Treat responses as Symfony Response objects:
if ($response->isSuccessful()) {
$data = json_decode($response->getContent(), true);
} else {
throw new \RuntimeException('API Error: ' . $response->getStatusCode());
}
Authentication Add headers globally (e.g., in config) or per-request:
# config/packages/circle_of_nice_rest_client.yaml
circle_of_nice_rest_client:
default_options:
headers:
Authorization: "Bearer YOUR_TOKEN"
Or dynamically:
$this->restClient->get('https://api.example.com/protected', [], [
'headers' => ['X-API-KEY' => 'secret_key']
]);
Error Handling
Use Symfony’s HttpException or custom exceptions:
try {
$response = $this->restClient->get('https://api.example.com/fail');
} catch (\Symfony\Component\HttpKernel\Exception\HttpException $e) {
// Handle HTTP errors (4xx, 5xx)
}
Integration with Symfony Components
$data = $this->serializer->deserialize($response->getContent(), 'array', 'json');
Custom Middleware
Extend the RestClient to add preprocessing/postprocessing:
use CircleOfNice\RestClientBundle\RestClientInterface;
class CustomRestClient implements RestClientInterface {
private $decorated;
public function __construct(RestClient $decorated) {
$this->decorated = $decorated;
}
public function get($url, array $options = []) {
// Pre-process (e.g., add logging)
$response = $this->decorated->get($url, $options);
// Post-process (e.g., transform data)
return $response;
}
}
Register as a service:
services:
App\Service\CustomRestClient:
decorates: circle_of_nice_rest_client.rest_client
arguments: ['@App\Service\CustomRestClient.inner']
Rate Limiting
Use Symfony’s Stopwatch to track and throttle requests:
$stopwatch = $this->container->get('debug.stopwatch');
if ($stopwatch->section('api_rate_limit')->getDuration() < 1000) {
$this->restClient->get('https://api.example.com/rate-limited');
}
Caching Responses
Cache responses with Symfony’s HttpCache or Cache component:
$cache = $this->container->get('cache.app');
$cacheKey = 'api_users_' . md5($url);
if (!$cache->has($cacheKey)) {
$response = $this->restClient->get($url);
$cache->set($cacheKey, $response->getContent(), 3600);
} else {
$response = new Response($cache->get($cacheKey));
}
Deprecated Package
symfony/http-client if critical bugs arise.Leaky Abstraction
curl options may still leak (e.g., CURLOPT_* constants). Avoid relying on undocumented behavior.curl options:
$this->restClient->get($url, [], [
'curl_options' => [CURLOPT_HTTPHEADER => ['X-Raw-Header: value']]
]);
Response Handling
$xml = simplexml_load_string($response->getContent());
isSuccessful() or status codes before parsing.Configuration Overrides
default_options) may override per-request settings unintentionally. Test edge cases:
# config/packages/circle_of_nice_rest_client.yaml
circle_of_nice_rest_client:
default_options:
timeout: 30 # Overrides all requests unless specified otherwise
SSL/TLS Issues
curl may fail silently on self-signed certs. Explicitly allow insecure options:
$this->restClient->get($url, [], [
'curl_options' => [CURLOPT_SSL_VERIFYPEER => false] // Use cautiously!
]);
Enable Verbose Logging
Add to config/packages/monolog.yaml:
handlers:
rest_client:
type: stream
path: "%kernel.logs_dir%/rest_client.log"
level: debug
channels: ["!event"]
Then enable debug mode in RestClient:
$this->restClient->setDebug(true);
Inspect Raw cURL Command
Use CURLOPT_VERBOSE to log the exact cURL command:
$this->restClient->get($url, [], [
'curl_options' => [
CURLOPT_VERBOSE => true,
CURLOPT_STDERR => fopen('php://temp', 'w+')
]
]);
Symfony Profiler
Use the Web Profiler to inspect Response objects and headers:
$response = $this->restClient->get('https://api.example.com/debug');
$this->addFlash('debug', $response->getStatusCode());
Custom Response Transformers
Decorate the RestClient to transform responses:
class TransformerRestClient implements RestClientInterface {
public function get($url, array $options = []) {
$response = $this->decorated->get($url, $options);
$content = $response->getContent();
$data = json_decode($content, true);
// Custom logic (e.g., flatten arrays)
$response->setContent(json_encode($data));
return $response;
}
}
Plugin System
Create a RestClientPlugin interface to extend functionality:
interface RestClientPluginInterface {
public function onBeforeRequest(RestClient $client, string $method, string $url, array $options);
public function onAfterResponse(RestClient $client, Response $response, string $method, string $url);
}
Register plugins in the RestClient constructor.
**Event
How can I help you explore Laravel packages today?