Courses

Laravel API Code Review and Refactor

Duplicate Code: Make Controller Resourceful

You're reading a FREE PREVIEW of a PREMIUM course.

Link to the repository

[Only for premium members]

The OrderController looks like a typical Resourceful Controller, but the author didn't go that route.

There are separate methods update() with PATCH and replace() with PUT:

routes/api_v1.php:

Route::apiResource('orders', OrderController::class)->except(['update']);
Route::patch('orders/{order}', [OrderController::class, 'update']);
Route::put('orders/{order}', [OrderController::class, 'replace']);

Looking at the Controller, those methods are IDENTICAL, except only for the Form Request classes: UpdateOrderRequest vs ReplaceOrderRequest:

app/Http/Controllers/Api/V1/OrderController.php:

use App\Http\Requests\Api\V1\ReplaceOrderRequest;
use App\Http\Requests\Api\V1\UpdateOrderRequest;
 
// ...
 
public function update(UpdateOrderRequest $request, $order_id)
{
try {
$order = Order::findOrFail($order_id);
$this->isAble('update', $order); // policy
$this->orderService->updateOrderHandleProducts($request, $order);
 
return response()->json(new OrderResource($order), Response::HTTP_OK);
} catch (ModelNotFoundException $eModelNotFound) {
return $this->responseNotFound('Order not found');
} catch (AuthorizationException $eAuthorizationException) {
return $this->responseNotAuthorized();
} catch (QueryException $eQueryException) {
DB::rollback(); // Rollback transaction on database error
 
return $this->responseDbError();
} catch (Throwable $eTh) {
DB::rollback(); // Rollback transaction on any other error
 
return $this->responseUnexpectedError();
}
}
 
public function replace(ReplaceOrderRequest $request, $order_id)
{
// ... The same IDENTICAL 19 lines of code as update()
}

Digging deeper: looking at the Form Request classes, the ONLY difference is the required rules in the ReplaceOrderRequest vs. sometimes rules in the UpdateOrderRequest:

app/Http/Requests/Api/V1/UpdateOrderRequest.php:

return [
'data' => 'required|array',
'data.attributes' => 'sometimes|array',
'data.relationships' => 'sometimes|array',

app/Http/Requests/Api/V1/ReplaceOrderRequest.php:

return [
'data' => 'required|array',
'data.attributes' => 'required|array',
'data.relationships' => 'required|array',
 
// ... ~10 more rules in the same fashion

To me, it just doesn't look/feel right. Too much duplicated code.

I don't know the reasons behind why it was created this way, but it...

The full lesson is only for Premium Members.
Want to access all 15 lessons of this course? (56 min read)

You also get:

  • 76 courses
  • Premium tutorials
  • Access to repositories
  • Private Discord