How to read JSON from api url with laravel 5.5
Stefan Bogdanescu
Founder & Senior Architect · 2026-06-29
How to Read JSON from an API URL with Laravel 5.5 while Maintaining the MVC Format
As a senior developer, I often see developers wrestling with this exact dilemma: how to bridge the gap between raw data fetching (like using file_get_contents and json_decode) and the structured, maintainable architecture of a framework like Laravel's Model-View-Controller (MVC). You are absolutely right to seek a solution that keeps the logic within the Controller layer, rather than polluting it with raw PHP scripting.
This post will walk you through the proper, idiomatic way to consume external JSON data in Laravel, ensuring you maintain architectural integrity and adhere to best practices.
The Problem with Plain Decoding in Laravel
The simple solution you mentioned—using json_decode(file_get_contents($url), true) directly in a controller—works functionally. However, it violates the principle of separation of concerns that Laravel champions. When you embed raw HTTP fetching and JSON parsing directly into your Controller method, you create tightly coupled code that is difficult to test, reuse, and maintain.
The goal should not be just reading the data, but processing it using Laravel's powerful tooling. We want the Controller to focus on handling requests, calling services, and preparing data for the View, not acting as a raw PHP script interpreter.
The Laravel Way: Using HTTP Clients in Controllers
The proper Laravel approach is to leverage built-in or package-based HTTP clients within your Controller. This keeps the network operation separate from the business logic, which aligns perfectly with the MVC pattern. For Laravel 5.5, while the Illuminate\Http\Request handles incoming requests beautifully, fetching external data requires a dedicated method.
We will use the Illuminate\Support\Facades\Http facade (introduced later in older versions, but conceptually applicable, or Guzzle wrappers if necessary) to make clean, robust HTTP requests.
Step 1: Setting up the Controller Logic
Let's assume we are fetching product data from an external API and want to pass it to a view.
<?php
namespace App\Http\Controllers;
use Illuminate\Support\Facades\Http;
use Illuminate\Http\Request;
class ProductController extends Controller
{
public function index()
{
$apiUrl = 'http://example.com/api/products'; // The external API URL
try {
// 1. Make the HTTP request using the Laravel Http Facade
$response = Http::get($apiUrl);
// 2. Check if the request was successful (status code 200-299)
if ($response->successful()) {
// 3. Decode the JSON response directly into a PHP array/object
$data = $response->json();
// 4. Pass the clean data to the view
return view('products.index', ['products' => $data]);
} else {
// Handle API errors gracefully
return view('error', ['message' => 'Failed to fetch data from external API.']);
}
} catch (\Exception $e) {
// Handle network or connection errors
return view('error', ['message' => 'An error occurred: ' . $e->getMessage()]);
}
}
}
Step 2: Maintaining Architectural Integrity
Notice how this approach achieves the MVC goal:
- Controller: Handles the request, delegates the external communication (HTTP call), handles potential failures, and prepares the final data payload. It is orchestrating, not scripting raw I/O.
- Service Layer (Best Practice): For complex applications, instead of putting the HTTP logic directly in the Controller, you would delegate this action to a dedicated Service class. This makes your code even cleaner and testable, which is crucial when building robust systems, as emphasized by concepts found on https://laravelcompany.com.
- View: Receives only the clean, structured data (
$products), ensuring it remains purely responsible for presentation.
Handling Headers and JSON Results
You also asked about maintaining headers and JSON results. When dealing with external APIs, you are primarily dealing with two concepts: the HTTP response (headers) and the body content (JSON).
- Headers: The
Http::get()method automatically allows you to inspect the response object ($response). You can check status codes (e.g.,$response->successful()) and inspect headers directly from it, ensuring that error responses or rate-limiting messages are handled correctly before attempting to parse the body. - JSON: Using
$response->json()is the safest method. It attempts to decode the response stream into a PHP structure. If the API returns invalid JSON, Laravel's HTTP client will throw an exception, which you can catch gracefully, preventing runtime errors in your application flow.
Conclusion
To summarize, avoid using raw json_decode inside controllers when dealing with external APIs. Instead, embrace Laravel's ecosystem. By utilizing the built-in HTTP facade, you encapsulate the network logic within a structured controller method. This ensures that your application remains clean, testable, and scalable—the very essence of good software design promoted by modern frameworks like https://laravelcompany.com. Focus on orchestrating data flow rather than executing raw I/O commands.