Search by

softmedialabs / laravel-route-annotation

rizkymiff

Comprehensive PHP 8 Attribute-based Route Annotation library for Laravel

Package info

github.com/softmedialabs/Laravel-Route-Annotation

pkg:composer/softmedialabs/laravel-route-annotation

Statistics

Installs: 1

Dependents: 0

Suggesters: 0

Stars: 0

Open Issues: 0

v1.0.0 2026-11-04 04:45 UTC

This package is auto-updated.

Last update: 2026-11-04 04:54:47 UTC


README

Latest Version PHP Version Laravel Version License

Library Laravel modern untuk mendefinisikan routing langsung di controller menggunakan PHP 8 Attributes. Meng-cover seluruh fitur routing bawaan Laravel secara menyeluruh (REST, verbs, middleware, parameter regex constraints, scoping, soft deletes, policy authorization, hingga fallback).

๐Ÿš€ Fitur Utama

  • 100% Fitur Route Laravel Ter-cover: Verbs, Prefix, Domain, Route Name, Middleware, Parameter Constraints (where), Soft Deletes, Scoped Bindings, dan Defaults.
  • RESTful & API Resource Controllers: Otomatis mendaftarkan route resource lewat atribut #[Resource] dan #[ApiResource].
  • Kompatibel Penuh dengan Route Cache: Menggunakan referensi controller [Controller::class, 'method'] (tanpa closure), sehingga 100% kompatibel dengan php artisan route:cache.
  • High Performance Scanner: Mendukung caching metadata scanner secara mandiri (php artisan route-annotation:cache).
  • Developer Experience (DX) Bersih: Tidak perlu lagi bolak-balik antara file controller dan routes/web.php / routes/api.php.

๐Ÿ“ฆ Instalasi

1. Tambahkan ke Proyek

Jika digunakan sebagai paket lokal di proyek Laravel Anda, pastikan path terdaftar di composer.json root aplikasi:

"autoload": {
    "psr-4": {
        "SoftmediaLabs\\RouteAnnotation\\": "src/route-annotation/src/"
    }
}

Jalankan:

composer dump-autoload

2. Registrasi Service Provider (Laravel 11+)

Daftarkan service provider di bootstrap/providers.php:

return [
    App\Providers\AppServiceProvider::class,
    SoftmediaLabs\RouteAnnotation\RouteAnnotationServiceProvider::class,
];

3. Publish Konfigurasi & AI Agent Guidelines

Publikasikan file konfigurasi config/route-annotation.php:

php artisan vendor:publish --tag=route-annotation-config

Setup untuk AI Agents (Antigravity, Claude Code, Cursor, Boost)

Agar AI agent langsung otomatis paham dan menggunakan Route Annotation saat membuat/mengedit controller (mirip laravel-boost), jalankan:

php artisan route-annotation:install-ai

Command ini secara otomatis:

  1. Mendeteksi apakah folder .agents/ ada di root proyek; jika belum ada, otomatis dibuat.
  2. Mempublikasikan rules dan index ke .agents/rules/route-annotation.md dan .agents/rules/index.md.
  3. Menyediakan agent skill di .agents/skills/route-annotation/SKILL.md.
  4. Meng-update AGENTS.md di root proyek (menambahkan instruksi Route Annotation secara aman tanpa me-replace aturan yang sudah ada). (Catatan: folder .ai/ hanya berada di level library dan tidak akan mengotori root proyek).

๐Ÿ“– Panduan Penggunaan & Atribut

1. HTTP Verbs Dasar

Pasang atribut pada method controller untuk menentukan metode HTTP dan URI:

use SoftmediaLabs\RouteAnnotation\Attributes\Get;
use SoftmediaLabs\RouteAnnotation\Attributes\Post;
use SoftmediaLabs\RouteAnnotation\Attributes\Put;
use SoftmediaLabs\RouteAnnotation\Attributes\Patch;
use SoftmediaLabs\RouteAnnotation\Attributes\Delete;
use SoftmediaLabs\RouteAnnotation\Attributes\Options;
use SoftmediaLabs\RouteAnnotation\Attributes\Any;
use SoftmediaLabs\RouteAnnotation\Attributes\Route;
use SoftmediaLabs\RouteAnnotation\Attributes\Fallback;

class ArticleController
{
    #[Get('/articles', name: 'articles.index')]
    public function index() { ... }

    #[Post('/articles', name: 'articles.store')]
    public function store() { ... }

    #[Put('/articles/{id}', name: 'articles.update')]
    public function update(int $id) { ... }

    #[Patch('/articles/{id}')]
    public function patch(int $id) { ... }

    #[Delete('/articles/{id}')]
    public function destroy(int $id) { ... }

    #[Options('/articles')]
    public function options() { ... }

    #[Any('/webhook')]
    public function webhook() { ... }

    // Custom multi-methods
    #[Route(methods: ['GET', 'POST'], uri: '/contact')]
    public function contact() { ... }

    // Fallback route
    #[Fallback]
    public function notFound() { ... }
}

Catatan: Atribut Route bersifat repeatable, artinya satu method bisa memiliki lebih dari satu route:

#[Get('/register/step-1')]
#[Post('/register/step-1')]
public function stepOne() { ... }

2. Grouping: Prefix, Naming, & Subdomain

Atribut grouping dapat dipasang di level Class Controller (berlaku untuk semua method di controller tersebut) atau di level Method:

use SoftmediaLabs\RouteAnnotation\Attributes\Prefix;
use SoftmediaLabs\RouteAnnotation\Attributes\RouteName;
use SoftmediaLabs\RouteAnnotation\Attributes\Domain;
use SoftmediaLabs\RouteAnnotation\Attributes\Get;

#[Prefix('admin/users', name: 'admin.users.')]
#[Domain('{account}.myapp.com')]
class UserController
{
    // URI: {account}.myapp.com/admin/users
    // Route name: admin.users.index
    #[Get('/', name: 'index')]
    public function index() { ... }

    // URI: {account}.myapp.com/admin/users/{id}
    // Route name: admin.users.show
    #[Get('/{id}', name: 'show')]
    public function show(int $id) { ... }
}

3. Middleware & Policy Authorization

Gunakan #[Middleware], #[WithoutMiddleware], dan #[Can]:

use SoftmediaLabs\RouteAnnotation\Attributes\Middleware;
use SoftmediaLabs\RouteAnnotation\Attributes\WithoutMiddleware;
use SoftmediaLabs\RouteAnnotation\Attributes\Can;
use SoftmediaLabs\RouteAnnotation\Attributes\Get;
use SoftmediaLabs\RouteAnnotation\Attributes\Delete;

#[Middleware(['auth', 'verified'])]
class DashboardController
{
    #[Get('/dashboard')]
    public function dashboard() { ... }

    // Override: Mengecualikan middleware tertentu
    #[Get('/public-stats')]
    #[WithoutMiddleware('auth')]
    public function publicStats() { ... }

    // Shortcut untuk policy authorization (middleware can:delete,post)
    #[Delete('/posts/{post}')]
    #[Can('delete', 'post')]
    public function destroy(Post $post) { ... }
}

4. Parameter Regex Constraints (where)

Library ini menyediakan helper regex parameter yang lengkap:

use SoftmediaLabs\RouteAnnotation\Attributes\Get;
use SoftmediaLabs\RouteAnnotation\Attributes\Where;
use SoftmediaLabs\RouteAnnotation\Attributes\WhereNumber;
use SoftmediaLabs\RouteAnnotation\Attributes\WhereAlpha;
use SoftmediaLabs\RouteAnnotation\Attributes\WhereAlphaNumeric;
use SoftmediaLabs\RouteAnnotation\Attributes\WhereUuid;
use SoftmediaLabs\RouteAnnotation\Attributes\WhereUlid;
use SoftmediaLabs\RouteAnnotation\Attributes\WhereIn;

#[WhereNumber('user_id')] // Dapat dipasang di level class
class ParameterController
{
    // Parameter angka: [0-9]+
    #[Get('/users/{id}')]
    #[WhereNumber('id')]
    public function byId(int $id) { ... }

    // Parameter huruf: [a-zA-Z]+
    #[Get('/tags/{name}')]
    #[WhereAlpha('name')]
    public function byTag(string $name) { ... }

    // Parameter alfanumerik: [a-zA-Z0-9]+
    #[Get('/voucher/{code}')]
    #[WhereAlphaNumeric('code')]
    public function byVoucher(string $code) { ... }

    // Parameter UUID standar
    #[Get('/orders/{uuid}')]
    #[WhereUuid('uuid')]
    public function byUuid(string $uuid) { ... }

    // Parameter ULID
    #[Get('/sessions/{ulid}')]
    #[WhereUlid('ulid')]
    public function byUlid(string $ulid) { ... }

    // Whitelist value (enum-like)
    #[Get('/posts/status/{status}')]
    #[WhereIn('status', ['draft', 'published', 'archived'])]
    public function byStatus(string $status) { ... }

    // Custom regex pattern bebas
    #[Get('/files/{filename}')]
    #[Where('filename', '^[a-z0-9_-]+\.[a-z]{3,4}$')]
    public function byFile(string $filename) { ... }
}

5. Model Binding & Fitur Lanjutan

use SoftmediaLabs\RouteAnnotation\Attributes\Get;
use SoftmediaLabs\RouteAnnotation\Attributes\WithTrashed;
use SoftmediaLabs\RouteAnnotation\Attributes\ScopeBindings;
use SoftmediaLabs\RouteAnnotation\Attributes\WithoutScopedBindings;
use SoftmediaLabs\RouteAnnotation\Attributes\Defaults;

class AdvancedController
{
    // Mengizinkan soft-deleted model ditemukan di route binding
    #[Get('/users/{trashedUser}')]
    #[WithTrashed]
    public function showTrashed(User $trashedUser) { ... }

    // Child model scoped ke parent model
    #[Get('/users/{user}/posts/{post}')]
    #[ScopeBindings]
    public function userPost(User $user, Post $post) { ... }

    // Menonaktifkan child model scoping
    #[Get('/categories/{category}/posts/{post}')]
    #[WithoutScopedBindings]
    public function categoryPost(Category $category, Post $post) { ... }

    // Nilai default untuk route parameter opsional
    #[Get('/items/{category?}')]
    #[Defaults(['category' => 'all'])]
    public function items(?string $category = null) { ... }
}

6. Resource Controllers

Mendukung otomatisasi RESTful resource controller:

use SoftmediaLabs\RouteAnnotation\Attributes\Resource;
use SoftmediaLabs\RouteAnnotation\Attributes\ApiResource;
use SoftmediaLabs\RouteAnnotation\Attributes\Get;

// Full Web Resource (index, create, store, show, edit, update, destroy)
#[Resource('photos', only: ['index', 'show'])]
class PhotoController
{
    public function index() { ... }
    public function show(int $id) { ... }

    // Anda tetap bisa menambahkan custom action di controller yang sama!
    #[Get('/photos/trending', name: 'photos.trending')]
    public function trending() { ... }
}

// REST API Resource (tanpa create & edit)
#[ApiResource('api/v1/posts', except: ['destroy'])]
class PostApiController
{
    public function index() { ... }
    public function store() { ... }
    public function show(int $id) { ... }
    public function update(int $id) { ... }
}

๐Ÿ› ๏ธ Artisan CLI Commands

Command Deskripsi
php artisan route-annotation:install-ai Mempublikasikan panduan AI, memastikan folder .agents/, dan meng-update AGENTS.md.
php artisan route-annotation:list Menampilkan tabel rapi seluruh route & resource yang ditemukan dari anotasi.
php artisan route-annotation:cache Meng-cache hasil scanning controller ke file cache mandiri untuk performa tinggi.
php artisan route-annotation:clear Menghapus file cache anotasi.
php artisan route:list Route bawaan Laravel otomatis menampilkan seluruh route anotasi.
php artisan route:cache Route cache bawaan Laravel otomatis mendukung penuh route anotasi.

โš™๏ธ Konfigurasi (config/route-annotation.php)

return [
    // Status aktivasi route annotation
    'enabled' => env('ROUTE_ANNOTATION_ENABLED', true),

    // Direktori yang akan di-scan untuk controller
    'scan_paths' => [
        app_path('Http/Controllers'),
    ],

    // Pola nama file controller
    'patterns' => [
        '*Controller.php',
    ],

    // File atau folder yang dikecualikan
    'excluded_paths' => [
        //
    ],

    // Lokasi cache anotasi mandiri
    'cache_path' => storage_path('framework/cache/routes-annotation.php'),
];

๐Ÿงช Testing

Jalankan test suite library menggunakan PHPUnit:

vendor/bin/phpunit src/route-annotation/tests

Format kode sesuai standar PSR / Laravel Pint:

vendor/bin/pint --format agent src/route-annotation

๐Ÿ“„ Lisensi

Library ini dirilis di bawah lisensi MIT.