Laravel Web and API: Same or Separate Controllers?

Sometimes you may encounter the situation that you need to return the same data on the web and via API. Should it be in the same or separate controllers? There are a few ways to handle it.

Option 1. Same Controller with Parameter

app/Http/Controllers/UserController.php:

1class UserController extends Controller {
2 public function index($format = 'view') {
3 $users = User::all();
4 
5 if ($format == 'view') {
6 return view('users.index', compact('users'));
7 } else {
8 return response()->json($users); // or use API Resource here
9 }
10 }
11}

Option 2. Same Controller with Header

The Controller may define what to return based on the Header of the request. Your front-end client may pass the request with Accept: application/json, for example. Then, you can do:

app/Http/Controllers/UserController.php:

1use Illuminate\Http\Request;
2 
3class UserController extends Controller {
4 public function index(Request $request) {
5 $users = User::all();
6 
7 if ($request->expectsJson()) {
8 return response()->json($users);
9 } else {
10 return view('users.index', compact('users'));
11 }
12 }
13}

Option 3. Separate Controllers

Mixing WEB and API Controllers may be a bad practice, because it goes against the "Separation of Concerns" principle: they serve different purposes so should be separated.

app/Http/Controllers/UserController.php:

1class UserController extends Controller {
2 public function index() {
3 $users = User::all();
4 return view('users.index', compact('users'));
5 }
6}

routes/web.php:

1use App\Http\Controllers\UserController;
2 
3Route::get('users', [UserController::class, 'index']);

app/Http/Controllers/Api/UserController.php:

1class UserController extends Controller {
2 public function index() {
3 $users = User::all();
4 return response()->json($users);
5 }
6}

routes/api.php:

1use App\Http\Controllers\Api\UserController;
2 
3Route::get('users', [UserController::class, 'index']);

Then the web page can be accessed with /users, and API endpoint can be called with /api/users, as all the routes in routes/api.php file get the "api" prefix automatically.

No comments or questions yet...

Like our articles?

Become a Premium Member for $129/year or $29/month

Recent Premium Tutorials