How do I convert this cURL request to a Laravel 9.x Http client request?

Stefan Bogdanescu

Founder & Senior Architect · 2026-06-29

Laravel Company

Moving Beyond cURL: Converting Raw Requests to the Laravel HTTP Client

As senior developers, we often encounter legacy codebases or external APIs that rely on raw cURL calls. While cURL offers unparalleled low-level control over network requests, managing headers, error handling, and complex setups manually can quickly become cumbersome, brittle, and hard to maintain. When working within the Laravel ecosystem, there is a superior, more expressive, and object-oriented way to handle HTTP communication: the official Laravel HTTP Client.

This post will guide you through converting a verbose cURL implementation into clean, idiomatic Laravel code using the Illuminate\Support\Facades\Http facade.

Why Ditch cURL for Standard Requests?

The provided cURL example demonstrates manual management of several aspects: constructing the full URL with query parameters, setting detailed HTTP headers (like User-Agent), managing timeouts, and handling execution errors. This process involves many boilerplate lines that abstract away the actual data fetching.

When you use raw cURL, you are responsible for:

  1. Initializing the session (curl_init()).
  2. Setting numerous options (CURLOPT_URL, CURLOPT_RETURNTRANSFER, etc.).
  3. Executing the call and manually checking return codes (curl_exec(), curl_errno()).

In contrast, the Laravel HTTP Client abstracts all this complexity into a fluent interface. This makes your code significantly more readable, easier to test, and less prone to subtle errors. Following the principles of clean architecture promoted by frameworks like Laravel, leveraging built-in tools is always the best approach.

The Conversion: From cURL to Http Facade

The goal is to take the logic from your manual setup (building the URL, setting headers) and map it directly onto the methods provided by the HTTP Client.

Let's look at how we can refactor your example function.

Original cURL Implementation Snapshot

Your original code focuses on:

  1. Constructing the full URL with query parameters.
  2. Setting custom headers (User-Agent, Accept-Language).
  3. Executing the request and getting the raw response body.
// ... inside doExternalApiCall method ...
$url = self::API_URL . $endpoint . http_build_query($params);
$curl = curl_init();
// ... extensive setup of CURLOPT_URL, CURLOPT_HTTPHEADER (headers), etc.
$response = curl_exec($curl);
curl_close($curl);
return $response;

The Laravel HTTP Client Approach

The Laravel client allows you to chain these operations directly. We can achieve the exact same result using simple method calls.

For a GET request with query parameters and custom headers, the conversion looks like this:

use Illuminate\Support\Facades\Http;

class ApiService
{
    protected string $apiUrl = 'https://api.example.com'; // Assuming API_URL setup

    public function doExternalApiCall(string $endpoint = '', array $params = []): ?string
    {
        // 1. Construct the full URL with query parameters directly
        $url = $this->apiUrl . $endpoint;
        if (!empty($params)) {
            $url .= '?' . http_build_query($params);
        }

        try {
            $response = Http::withHeaders([
                'Accept-Language' => 'en-US,en;q=0.9,pt-BR;q=0.8,pt;q=0.7',
                'User-Agent' => 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.45 Safari/537.36'
            ])->timeout(10) // Mapping CURLOPT_TIMEOUT
             ->get($url) // The GET request
             ->throw(); // Throws an exception on 4xx/5xx responses

            // If you need the raw body content instead of a JSON object:
            return $response->body();

        } catch (\Illuminate\Http\Client\RequestException $e) {
            // Handle HTTP errors (404, 500, etc.)
            // Log the error or return an appropriate fallback response
            \Log::error("API Call Failed: " . $e->getMessage());
            return null;
        } catch (\Exception $e) {
            // Handle connection errors or timeouts
            \Log::error("Connection Error: " . $e->getMessage());
            return null;
        }
    }
}

Best Practices for Laravel HTTP Requests

Notice how the Laravel approach inherently improves error handling. Instead of manually checking curl_errno(), which is low-level, we rely on exceptions thrown by the framework when a request fails (e.g., DNS failure, timeout, or non-200 status codes). This shifts error management from manual checks to structured exception handling, which aligns perfectly with modern PHP development standards.

When building robust services in Laravel, always favor the provided tools. For comprehensive details on leveraging Guzzle and HTTP capabilities within your framework, explore the official documentation found at https://laravelcompany.com. By adopting these patterns, you ensure your code remains maintainable, scalable, and aligned with best practices for building powerful applications.

Conclusion

Converting raw cURL calls to the Laravel HTTP Client is not just a syntactic change; it's a paradigm shift toward higher-level abstraction. By replacing manual socket management with fluent methods like Http::get(), you delegate tedious tasks—header management, connection handling, and status code checking—to a robust framework. This results in cleaner, more resilient, and significantly easier-to-read code, making maintenance a breeze.