Laravel Architectural Pattern
What’s Architectural Pattern
Simply put, an Architectural Pattern is a code writing rule that aims to make the code structure easy to read, maintain and develop. Some popular architectural patterns: MVC, MVVM, Layered Architecture, Microservices, and others.
Model — View — Controller (MVC)
Is Architectural Pattern which focuses on the separation of model (entity), view, and controller
Model (Entity)
The model is responsible for processing logic integrated with the database or external third parties used in application development.
View
The view is responsible for providing the user interface within the application.
Controller
The controller is responsible for managing data flow and logical operations that are integrated with the model and view.
When to use MVC ?
MVC is good for creating small-scale or monolith applications, because the MVC architecture is known for its speed during the development and deployment process.
MVC is not good for building large-scale applications, because the code and logical operations that focus on the controller and model make the code more complicated to read and maintain.
Example Implementation MVC
Model
proper implementation
In the model, it is not recommended to use complicated logical operations, because the model is a representation of a table in the database. Usually, the model is only used to initiate relations or get data from the database.
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class Example extends Model
{
use HasFactory;
protected $table = 'example';
protected $primaryKey = 'id';
protected $fillable = [
'column_1',
'column_2',
'column_3',
'column_4',
];
public $timestamps = true;
public function getAll()
{
return $this->get();
}
public function contact()
{
return $this->belongsTo(Contact::class. 'column_1', 'column_1');
}
}
improper implementation
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class Example extends Model
{
public function getAllWithLogic()
{
$data = $this->get();
$result = [];
foreach ($data as $value) {
if ($value->column_1 == 'boob') {
$result[] = $value;
}
}
return $result;
}
public function fizzBuzz(string $params)
{
if ($params == 'fizz') {
return 1;
} elseif ($params == 'buzz') {
return 0;
} else {
return 2;
}
}
}
View
proper implementation
In best practice, views should only manage views and receive data from BE/controllers. Views should not directly call Models or Controllers as this can cause workflow inconsistencies.
proper implementation
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
<div class="input-group">
{!! Form::select('id_pelanggan', $OptionPelanggan, null, ['class' => 'form-control', 'id' => 'pelanggan']) !!}
<div class="input-group-append">
<button type="button" class="btn btn-primary" id="btnAddPelanggan" onclick="formAddPelanggan()"><i class="fa fa-plus"></i></button>
</div>
</div>
</body>
</html>
improper implementation
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
<div class="input-group">
{!! Form::select('id_pelanggan', App\Models\Pelanggan::pluck('nama', 'id')->toArray(), null, ['class' => 'form-control', 'id' => 'pelanggan']) !!}
<div class="input-group-append">
<button type="button" class="btn btn-primary" id="btnAddPelanggan" onclick="formAddPelanggan()"><i class="fa fa-plus"></i></button>
</div>
</div>
</body>
</html>
Controller
proper implementation
In the controller we are free to put all application logic in it, because MVC itself is a branch of monolith architecture, which focuses on collecting processes in it.
<?php
namespace App\Http\Controllers;
use App\Models\Contact;
use App\Models\Example;
use Illuminate\Http\Request;
class WelcomeController extends Controller
{
public function index()
{
return view('livewire');
}
public function get()
{
if (request()->ajax()) {
$exampleModel = Example::query()->get();
$result = [];
foreach ($exampleModel as $example) {
if ($example->number % 3 == 0) {
$result[] = $example->number;
}
}
return $result;
}
return view('welcome');
}
}
improper implementation
<?php
namespace App\Http\Controllers;
use App\Models\Contact;
use App\Models\Example;
use Illuminate\Http\Request;
class WelcomeController extends Controller
{
public function index()
{
return view('livewire');
}
public function getV2()
{
if (request()->ajax()) {
$exampleModel = Example::query()->select('*')->where('number', request('number'))->get();
$result = [];
foreach ($exampleModel as $example) {
if ($example->number % 3 == 0) {
$contract = Contact::query()->selectRaw('CASE WHEN expired = 1 THEN \'kadaluarsa\' ELSE \'berlaku\'')->where('example_id', $example->id)->get();
$example->contract = $contract;
$result[] = $example;
}
}
return $result;
}
return view('welcome');
}
}
Conclusion
MVC Architectural Pattern providing convenience in application development, with various advantages offered, to build applications on a small scale MVC is highly recommended, but besides its advantages, each architectural pattern has disadvantages, use it according to your needs.