Membangun aplikasi berskala tim dengan yii2-app-advanced: struktur multi-app yang memisahkan frontend, backend, dan api dalam satu monorepo, sistem environments dengan inisialisasi per environment, serta strategi module untuk memecah aplikasi monolitik menjadi bagian yang terkelola.

Sejauh ini kita bekerja dengan satu aplikasi basic — sempurna untuk belajar dan project kecil. Tapi aplikasi enterprise punya kebutuhan berbeda: admin panel dan situs publik tidak boleh sekode, apalagi se-deploy. Keduanya punya konteks keamanan, skala traffic, dan siklus rilis yang berbeda.
Yii menjawabnya dengan advanced template (yii2-app-advanced): struktur multi-app dalam satu repository yang memisahkan frontend, backend, api, dan common, plus sistem environments untuk menangani perbedaan konfigurasi Dev/Staging/Prod. Di episode ini kita bangun monorepo app admin + API yang mencerminkan arsitektur production nyata.
composer create-project --prefer-dist yiisoft/yii2-app-advanced learn-yii-advancedStruktur yang dihasilkan:
learn-yii-advanced/
├── common/
│ ├── config/ # konfigurasi bersama semua app
│ ├── mail/ # template email
│ └── models/ # model yang dipakai semua app (User, dsb.)
├── frontend/ # situs publik (customer-facing)
│ ├── controllers/
│ ├── models/
│ ├── views/
│ ├── config/
│ └── web/
├── backend/ # admin panel (internal)
│ ├── controllers/
│ ├── models/
│ ├── views/
│ └── web/
├── console/ # cron jobs, queue worker, seeder
├── environments/ # template per environment
├── init # inisialisasi environment
└── yii # console entry point (advanced)Perhatikan filosofinya: empat aplikasi Yii terpisah — frontend, backend, console, dan (opsional) api — berbagi satu folder common/. Setiap app punya entry point, config, dan session sendiri. Ini bukan pilihan estetika; ini isolasi:
Yii memberi setiap app alias untuk referensi path lintas app: @common, @frontend, @backend, @console. Inilah cara satu app memakai model dari app lain:
use common\models\User; // class ada di common/models
// dalam kode Yii, alias dipakai untuk path
Yii::getAlias('@common'); // /path/to/learn-yii-advanced/commonAlias didefinisikan di common/config/bootstrap.php lewat Yii::setAlias() — kita akan melihatnya lagi saat membahas Yii3 di episode 23, karena konsepnya sama.
Satu kode sumber, banyak target deploy — environments menyelesaikan perbedaan konfigurasi ini. init menyalin file dari folder environment terpilih ke posisi aktif:
php init # pilih Development atau Productionenvironments/
├── dev/
│ └── common/config/main-local.php # DB dev, debug aktif
│ └── frontend/config/main-local.php
│ └── backend/config/main-local.php
└── prod/
└── common/config/main-local.php # DB prod, debug mati
└── ...File -local.php adalah konfigurasi yang di-merge ke config utama. Pola main.php (umum, di-commit) + main-local.php (spesifik environment, biasanya gitignored) adalah jantung sistem ini:
<?php
return [
'components' => [
'db' => require __DIR__ . '/db.php',
'cache' => [
'class' => 'yii\caching\FileCache',
],
// param lain yang sama untuk semua app
],
];<?php
return [
'components' => [
'db' => [
'dsn' => getenv('DB_DSN'),
'username' => getenv('DB_USER'),
'password' => getenv('DB_PASS'),
],
],
];php init tidak pernah menimpa file -local.php yang sudah ada — jadi nilai production aman dari overwrite saat developer menjalankan init lagi. Di production, nilai sebenarnya datang dari environment variable (episode 22).
Tip
Aturan merancang konfigurasi multi-app: jangan ulangi (pakai common/config/), jangan bocorkan rahasia (secret hanya di -local.php dan env vars, gitignored), dan ganti cepat (jalur di main.php hanya menyimpan default). Cek git status setelah php init untuk memastikan secret tidak ter-commit.
Di dalam satu app, aplikasi yang tumbuh membesar butuh pemisahan lebih lanjut — di situlah module berperan. Kita sudah melihat dasar module di episode 4; sekarang kita praktikkan strategi modularisasi nyata.
Contoh: backend app memiliki modul user, report, dan setting, masing-masing dengan controller dan view sendiri:
'modules' => [
'user' => [
'class' => 'backend\modules\user\Module',
],
'report' => [
'class' => 'backend\modules\report\Module',
],
'setting' => [
'class' => 'backend\modules\setting\Module',
],
],<?php
namespace backend\modules\user;
use Yii;
class Module extends \yii\base\Module
{
public $controllerNamespace = 'backend\modules\user\controllers';
public function init(): void
{
parent::init();
// konfigurasi khusus modul bisa dipasang di sini
}
}Akses via URL: /user/user/index (modul user, controller user, action index). Setiap module punya controllers/, views/, models/, config/ sendiri — sebuah "aplikasi mini" yang bisa dikembangkan tim berbeda tanpa saling tabrak file.
Ini pertanyaan arsitektur yang sering salah dijawab:
| Keputusan | Gunakan Module | Gunakan App Terpisah (advanced) |
|---|---|---|
| Pemisahan fungsi dalam satu konteks | Ya (modul report di backend) | — |
| Konteks keamanan berbeda | — | Ya (admin vs publik) |
| Skala traffic sangat berbeda | — | Ya (frontend vs api) |
| Siklus rilis berbeda | — | Ya (deploy per app) |
| Tim berbeda mengerjakan | Module (batasi scope) | Ya |
Bangun skenario nyata: frontend publik + backend admin + api. Karena advanced template tidak menyediakan api app secara bawaan, tambahkan sebagai module di common atau app terpisah. Pendekatan paling sederhana untuk memulai: jadikan API module dari frontend atau buat app api/ baru dengan menyalin pola app yang ada.
composer create-project --prefer-dist yiisoft/yii2-app-advanced learn-yii-advanced
cd learn-yii-advanced
php init --env=Development --overwrite=n
php yii migrate/up --interactive=0Konfigurasi koneksi di common/config/main-local.php, lalu jalankan kedua app:
php yii serve --port=8080 # frontend: http://localhost:8080
php yii serve backend/web --port=8081 # backend: http://localhost:8081Login admin di backend (template menyediakan admin/123456 untuk development — ganti di production), dan kalian sudah punya arsitektur dua-app: satu untuk customer, satu untuk internal, dalam satu repository yang terkontrol.
Important
Advanced template menyertakan akun admin bawaan (admin / 123456) yang dibuat oleh migration awal. Ini untuk development saja. Sebelum deploy, wajib: hapus/ubah kredensial bawaan, ganti cookieValidationKey per app, dan nonaktifkan Gii/debug. Kebocoran akun default adalah salah satu penyebab kompromi paling umum di aplikasi Yii production.
Inti yang harus dibawa pulang:
common, frontend, backend, console (+ opsional api).@common, @frontend, @backend menghubungkan path lintas app.php init) menyalin config spesifik Dev/Prod ke -local.php yang di-merge ke main.php.Di episode 21 selanjutnya, kita mengaktifkan caching dan session lintas instance: Redis & session management — mengonfigurasi Redis sebagai cache dan session store, memahami mengapa session harus dibuang dari filesystem, serta praktik terbaik aplikasi stateless untuk horizontal scaling. Sampai jumpa di episode 21!