Kontroler

Kontroler adalah file yang berisi fungsi-fungsi handler untuk setiap endpoint API. Satu kontroler biasanya menangani satu domain bisnis.

Anatomi Kontroler

app/kontroler/ProdukKontroler.ns
// Pola standar setiap fungsi kontroler:
// 1. Cek autentikasi
// 2. Baca request (body, query param)
// 3. Validasi input
// 4. Proses (query model, logic bisnis)
// 5. Kembalikan response

fungsi aksi_produk_simpan(req) {
    // 1. Cek autentikasi — hanya admin
    buat klaim = wajib_admin(req)
    jika klaim == nihil {
        kembalikan resp_error("Akses ditolak — hanya admin")
    }

    // 2. Baca body JSON
    buat body = body_json(req)

    // 3. Validasi input
    buat errors = validasi(body, {
        "nama"  : "wajib|min:2|maks:200",
        "harga" : "wajib"
    })
    jika panjang(errors) > 0 {
        kembalikan resp_validasi("Data produk tidak valid", errors)
    }

    // 4. Simpan ke database via ORM
    Model_buat("Produk", {
        "nama"      : ambil(body, "nama"),
        "harga"     : ambil(body, "harga"),
        "stok"      : ambil(body, "stok"),
        "kategori"  : ambil(body, "kategori")
    })

    // 5. Kembalikan response berhasil
    cetak_log("INFO", "Produk baru ditambahkan oleh:", ambil(klaim, "email"))
    kembalikan resp_ok(nihil, "Produk berhasil ditambahkan")
}

Pola Guard Clause

Selalu gunakan guard clause — kembalikan lebih awal saat ada error untuk mengurangi nesting:

Guard Clause di Kontroler
fungsi aksi_produk_perbarui(req) {
    // Guard 1: Cek auth
    buat klaim = wajib_admin(req)
    jika klaim == nihil { kembalikan resp_error("Akses ditolak") }

    // Guard 2: Cek ID
    buat body = body_json(req)
    buat id   = ambil(body, "id")
    jika id == nihil { kembalikan resp_error("ID wajib diisi") }

    // Guard 3: Cek keberadaan data
    buat produk = Model_temukan("Produk", id)
    jika produk == nihil { kembalikan resp_error("Produk tidak ditemukan") }

    // Sampai sini — semua valid, proses update
    Model_perbarui("Produk", id, {
        "nama"  : ambil(body, "nama"),
        "harga" : ambil(body, "harga")
    })
    kembalikan resp_ok(nihil, "Produk berhasil diperbarui")
}