10 Metode Terbaik untuk Menjaga Kode Laravel Tetap Bersih dan Terstruktur
Tags: laravel, programming
Published: 2024-06-02 15:29:20


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/rh6f6vfhl7fjll69or7i.png)

Menulis kode program yang bersih dan terstruktur dalam Laravel, seperti dalam framework PHP lainnya, adalah hal yang sangat penting untuk memastikan bahwa kode temen-temen mudah dipahami, dikelola, dan diubah. Berikut adalah beberapa metode dan praktik terbaik yang dapat diikuti untuk mencapai tujuan ini:

### 1. Gunakan PSR (PHP Standard Recommendations)
Laravel secara otomatis mengikuti standar PSR-1 dan PSR-2 dalam penulisan kode. Pastikan temen-temen juga mengikutinya:

- PSR-1: Prinsip dasar penulisan kode PHP seperti penamaan file, penggunaan namespaces, dan deklarasi class.
- PSR-2: Panduan lebih rinci tentang penulisan kode seperti indentasi, panjang baris, dan penempatan kurung.

Contoh format PSR-2:

```php
<?php
namespace Vendor\Package;

use FooInterface;
use BarClass as Bar;
use OtherVendor\OtherPackage\BazClass;

class Foo extends Bar implements FooInterface
{
    public function sampleFunction($arg1, $arg2 = null)
    {
        if ($arg1 === $arg2) {
            bar();
        } elseif ($arg1 > $arg2) {
            $this->bar();
        } else {
            BazClass::bar($arg1, $arg2);
        }
    }
}
```

### 2. Gunakan Dependency Injection
Menggunakan Dependency Injection (DI) membuat kode lebih modular dan lebih mudah diuji maupun di-maintenance. Daripada temen-temen membuat instance dari class di dalam method, injeksikan dependensi melalui constructor atau method.

```php
<?php

class UserController extends Controller
{
    protected $userService;

    public function __construct(UserService $userService)
    {
        $this->userService = $userService;
    }

    public function index()
    {
        $users = $this->userService->getAllUsers();
        return view('users.index', compact('users'));
    }
}
```

### 3. Gunakan Service Container dan Service Providers
Laravel memiliki Service Container yang kuat dan flexible untuk mengelola dependency injection. Manfaatkan Service Providers untuk mengatur dependency.

Contoh Service Provider:

```php
<?php

namespace App\Providers;

use Illuminate\Support\ServiceProvider;
use App\Services\UserService;

class UserServiceProvider extends ServiceProvider
{
    public function register()
    {
        $this->app->singleton(UserService::class, function ($app) {
            return new UserService();
        });
    }

    public function boot()
    {
        //
    }
}
```

### 4. Gunakan Repositories dan Service Layer
Pisahkan logika bisnis dari controller dengan menggunakan pattern Repository dan Service. Repositories berfungsi sebagai layer abstraksi antara model dan controller.

Contoh Repository:

```php
<?php

namespace App\Repositories;

use App\Models\User;

class UserRepository
{
    public function getAll()
    {
        return User::all();
    }

    public function findById($id)
    {
        return User::find($id);
    }
}
```

Contoh Service:

```php
<?php

namespace App\Services;

use App\Repositories\UserRepository;

class UserService
{
    protected $userRepository;

    public function __construct(UserRepository $userRepository)
    {
        $this->userRepository = $userRepository;
    }

    public function getAllUsers()
    {
        return $this->userRepository->getAll();
    }

    public function getUserById($id)
    {
        return $this->userRepository->findById($id);
    }
}
```

### 5. Gunakan Eloquent Mutators dan Accessors
Eloquent menyediakan mutators dan accessors untuk memodifikasi nilai atribut sebelum disimpan (setter) atau setelah diambil (getter) dari database.

**Accessor**
Apa itu Accessor? Accessors digunakan untuk memformat atau memanipulasi nilai atribut setelah diambil dari database.

Laravel 9 kebawah :

```php
<?php

class User extends Model
{
    public function getFullNameAttribute()
    {
        return "{$this->first_name} {$this->last_name}";
    }
}
```

Dalam Laravel 9, cara mendefinisikan accessors sedikit berbeda dengan versi sebelumnya. Anda sekarang menggunakan metode berbasis closure yang lebih deklaratif.

Laravel 9 keatas :

```php
namespace App\Models;

use Illuminate\Database\Eloquent\Model;

class User extends Model
{
    protected $appends = ['full_name']; // menambahkan atribut 'full_name' ke array model

    // Accessor untuk mendapatkan nama lengkap
    protected function fullName(): Attribute
    {
        return Attribute::make(
            get: fn ($value, $attributes) => "{$attributes['first_name']} {$attributes['last_name']}",
        );
    }
}
```

Penggunaan Accessor:

```php
<?php

$user = User::find(1);
echo $user->full_name; // Output: Nama Depan Nama Belakang
```

**Mutators**
Mutators digunakan untuk memformat atau memanipulasi nilai atribut sebelum disimpan ke database.

Misalkan temen-temen memiliki model User dengan atribut password, dan Anda ingin mengenkripsi password setiap kali disimpan ke database.

Laravel 9 kebawah:

```php
<?php

class User extends Model
{
    public function setPasswordAttribute($password)
    {
        $this->attributes['password'] = bcrypt($password);
    }
}
```

Laravel 9 keatas:

```php
<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Facades\Hash;

class User extends Model
{
    // Mutator untuk mengenkripsi password
    protected function password(): Attribute
    {
        return Attribute::make(
            set: fn ($value) => Hash::make($value),
        );
    }
}
```

Penggunaan Mutators:

```php
<?php

$user = new User;
$user->password = 'plain-text-password';
$user->save();
```

### 6. Gunakan Request Validation
Daripada melakukan validasi di dalam controller, temen-temen bisa gunakan Request Validation untuk membuat kode lebih bersih dan terorganisir.

Contoh Request Validation:

```php
<?php

namespace App\Http\Requests;

use Illuminate\Foundation\Http\FormRequest;

class StoreUserRequest extends FormRequest
{
    public function authorize()
    {
        return true;
    }

    public function rules()
    {
        return [
            'name' => 'required|string|max:255',
            'email' => 'required|string|email|max:255|unique:users',
            'password' => 'required|string|min:8|confirmed',
        ];
    }
}
```

Penggunaan di Controller:

```php
<?php

public function store(StoreUserRequest $request)
{
    $validated = $request->validated();
    User::create($validated);
    return redirect()->route('users.index');
}
```

### 7. Gunakan Resource Controllers
Laravel menyediakan resource controllers untuk membuat controller yang clean dan mengikuti prinsip RESTful sehingga controller resource di Laravel bisa menentukan operasi CRUD (Create, Read, Update, Delete) standar. Temen-temen bisa menggunakan **php artisan make:controller** untuk membuat resource controller.

Contoh pembuatan resource controller:

```bash
php artisan make:controller UserController --resource
```

Nanti akan menghasilkan controller seperti berikut:

```php
<?php

namespace App\Http\Controllers;

use App\Models\User;
use Illuminate\Http\Request;

class UserController extends Controller
{
    // Menampilkan daftar resource
    public function index()
    {
        $users = User::all();
        return view('users.index', compact('users'));
    }

    // Menampilkan form untuk membuat resource baru
    public function create()
    {
        return view('users.create');
    }

    // Menyimpan resource baru ke database
    public function store(Request $request)
    {
        $validated = $request->validate([
            'name' => 'required|string|max:255',
            'email' => 'required|string|email|max:255|unique:users',
            'password' => 'required|string|min:8',
        ]);

        $user = new User($validated);
        $user->password = bcrypt($request->password);
        $user->save();

        return redirect()->route('users.index');
    }

    // Menampilkan resource yang spesifik
    public function show($id)
    {
        $user = User::findOrFail($id);
        return view('users.show', compact('user'));
    }

    // Menampilkan form untuk mengedit resource yang spesifik
    public function edit($id)
    {
        $user = User::findOrFail($id);
        return view('users.edit', compact('user'));
    }

    // Memperbarui resource yang spesifik di database
    public function update(Request $request, $id)
    {
        $validated = $request->validate([
            'name' => 'required|string|max:255',
            'email' => 'required|string|email|max:255|unique:users,email,' . $id,
            'password' => 'nullable|string|min:8',
        ]);

        $user = User::findOrFail($id);
        $user->update($validated);

        if ($request->filled('password')) {
            $user->password = bcrypt($request->password);
            $user->save();
        }

        return redirect()->route('users.index');
    }

    // Menghapus resource yang spesifik dari database
    public function destroy($id)
    {
        $user = User::findOrFail($id);
        $user->delete();

        return redirect()->route('users.index');
    }
}
```

Kemudian jangan lupa menambahkan routing pada web.php

```php
<?php

use App\Http\Controllers\UserController;

Route::resource('users', UserController::class);
```

Dengan menggunakan **Route::resource**, Laravel akan secara otomatis menghasilkan semua route yang diperlukan untuk operasi CRUD:

- GET **/users** - index
- GET **/users/create** - create
- POST **/user**s - store
- GET **/users/{user}** - show
- GET **/users/{user}/edit** - edit
- PUT/PATCH **/users/{user}** - update
- DELETE **/users/{user}** - destroy

### 8. Gunakan Resource untuk JSON Responses
Saat mengembangkan API, gunakan Resources untuk memastikan struktur respons yang konsisten.

Untuk membuatnya temen-temen bisa menjalankan perintah 

```bash
php artisan make:resource UserResource
```

Contoh Resource:

```php
<?php

namespace App\Http\Resources;

use Illuminate\Http\Resources\Json\JsonResource;

class UserResource extends JsonResource
{
    public function toArray($request)
    {
        return [
            'id' => $this->id,
            'name' => $this->name,
            'email' => $this->email,
            'created_at' => $this->created_at->toDateString(),
            'updated_at' => $this->updated_at->toDateString(),
        ];
    }
}
```
Penggunaan di Controller:

```php
<?php

use App\Http\Resources\UserResource;

public function show($id)
{
    $user = User::findOrFail($id);
    return new UserResource($user);
}
```

### 9. Gunakan Policies dan Gates untuk Authorization
Laravel menyediakan mekanisme untuk mengelola authorization melalui Policies dan Gates.

Contoh Policy:

```php
<?php

namespace App\Policies;

use App\Models\User;
use App\Models\Post;

class PostPolicy
{
    public function update(User $user, Post $post)
    {
        return $user->id === $post->user_id;
    }
}
```
Penggunaan Policy:

```php
<?php

public function update(Request $request, Post $post)
{
    $this->authorize('update', $post);
    // Update logic here
}
```

### 10. Gunakan Route Model Binding
Laravel mendukung route model binding untuk secara otomatis menginjeksikan model instance ke dalam route handler.

Contoh Route Model Binding:

```php
<?php

Route::get('users/{user}', function (User $user) {
    return $user;
});
```

Dengan semua _best practice_ ini, temen-temen bisa memastikan bahwa kode Laravel temen-temen tetap _clean_, dapat dikelola, dan mengikuti standar industri. Kode yang clean tidak hanya membuat proses pengembangan lebih efisien tetapi juga meningkatkan kualitas dan pemeliharaan aplikasi jangka panjang. Sampai jumpa di artikel yang lain!!