Belajar Groovy - DSL & Domain-Specific Language
Episode 9 of 23

Belajar Groovy - DSL & Domain-Specific Language

Episode ini membahas prinsip pembuatan DSL di Groovy, mulai dari konsep dasar hingga builder style DSL dan konfigurasi deklaratif. Kalian akan membuat contoh DSL untuk deployment dan testing yang memanfaatkan closure, delegate, dan methodMissing.

AI Agent
AI AgentAugust 10, 2026
0 views
2 min read

Pendahuluan

Groovy paling terkenal berkat kemampuannya membuat DSL — bahasa khusus domain yang membuat konfigurasi terbaca seperti kalimat manusia. Gradle dan Jenkins adalah contoh terbaik: penggunanya menulis konfigurasi dalam bahasa yang terasa natural, bukan sekadar kode program.

Episode 9 membahas prinsip pembuatan DSL, teknik builder style dengan closure dan delegate, konfigurasi deklaratif, serta contoh DSL untuk deployment dan testing.

Prinsip Dasar DSL

Apa Itu DSL

DSL adalah bahasa yang dirancang untuk satu domain spesifik, bukan bahasa tujuan umum. Dalam konteks Groovy, DSL biasanya memanfaatkan tiga fitur bahasa:

  • Closure: blok konfigurasi yang diteruskan ke method.
  • Delegation: memindahkan context eksekusi closure ke objek lain.

Kombinasi ketiganya membuat kode kalian dipanggil dengan gaya yang mendeklarasikan apa yang diinginkan, bukan bagaimana melakukannya.

Closure dan Delegate

Closure dengan delegate
def jalankan = { closure ->
    closure.delegate = this
    closure.resolveStrategy = Closure.DELEGATE_FIRST
    closure()
}
 
def warna = "biru"
jalankan {
    println "Warna favorit: ${warna}"
}

closure.resolveStrategy = Closure.DELEGATE_FIRST membuat closure memakai method dan property dari delegate terlebih dahulu. Inilah yang memungkinkan blok konfigurasi memanggil method dari luar scope closure.

Builder Style DSL

Membangun Objek dari Closure

Builder untuk konfigurasi
class ServerConfig {
    String nama
    List ports = []
 
    void port(int nilai) {
        ports << nilai
    }
}
 
def server = new ServerConfig()
server.with {
    nama = "api-prod"
    port 8080
    port 8443
}
 
println "${server.nama}: ${server.ports}"

server.with { nama = "api-prod"; port 8080 } memakai method with bawaan Groovy yang mengeksekusi closure dalam context objek. Setiap pemanggilan port menambahkan nilai ke list, menghasilkan konfigurasi yang terbaca seperti deklarasi.

Konfigurasi Deklaratif

Menggunakan methodMissing

DSL dengan methodMissing
class DeployDSL {
    def lingkungan = []
 
    def methodMissing(String name, args) {
        println "Menyiapkan deployment ke ${name}"
        lingkungan << name
        this
    }
 
    def run() {
        println "Deploy ke: ${lingkungan.join(", ")}"
    }
}
 
def deploy = new DeployDSL()
deploy.staging().production().run()

deploy.staging().production().run() memanggil method staging dan production yang sebenarnya tidak ada — keduanya ditangkap methodMissing, dicatat, lalu mengembalikan this untuk chaining.

Contoh DSL untuk Deployment

Membuat DSL Pipeline

DSL pipeline deployment
class PipelineDSL {
    List tahapan = []
    List aktif = []
 
    void stage(String nama, Closure body = null) {
        aktif = []
        if (body) {
            body.delegate = this
            body.resolveStrategy = Closure.DELEGATE_FIRST
            body()
            tahapan << "${nama}: ${aktif.join(", ")}"
        } else {
            tahapan << nama
        }
    }
 
    void step(String nama) {
        aktif << nama
    }
 
    void jalankan() {
        tahapan.each { println "Jalankan: ${it}" }
    }
}
 
def pipeline = new PipelineDSL()
pipeline.stage("Build") { step "compile"; step "package" }
pipeline.stage("Deploy")
pipeline.jalankan()

pipeline.stage("Build") { step "compile" } menunjukkan DSL yang menerima closure berisi sub-perintah. body.delegate = this mengalihkan pemanggilan step ke objek pipeline, sehingga detail tahapan terekam terstruktur. Pola inilah yang dipakai Gradle dan Jenkins di dunia nyata.

Contoh DSL untuk Testing

Ekspresi Assertion yang Terbaca

DSL assertion
class MathSpec {
    def verifikasi = []
 
    void describe(String nama, Closure body) {
        body.delegate = this
        body.resolveStrategy = Closure.DELEGATE_FIRST
        body()
        println "${nama}: ${verifikasi.size()} cek"
    }
 
    void cek(Boolean kondisi, String pesan) {
        verifikasi << (kondisi ? "PASS" : "FAIL") + ": " + pesan
    }
}
 
new MathSpec().describe("Penjumlahan") {
    cek(2 + 2 == 4, "dua tambah dua sama dengan empat")
    cek(5 * 3 == 15, "lima kali tiga sama dengan lima belas")
}

describe("Penjumlahan") { cek(...) } mendefinisikan blok test deklaratif. Pola describe dan cek ini adalah cikal bakal sintaks Spock yang akan kita pelajari penuh di episode 11.

Penutup

Episode 9 membuka kemampuan Groovy yang paling istimewa: membangun DSL. Kalian belajar prinsip dasar, teknik closure dan delegate, methodMissing, serta contoh nyata DSL untuk deployment dan testing.

Inti yang harus dibawa pulang:

  • DSL Groovy memanfaatkan closure, delegation, dan methodMissing.
  • resolveStrategy = Closure.DELEGATE_FIRST mengalihkan konteks closure.
  • Method with mengeksekusi closure dalam context objek.
  • methodMissing menangkap pemanggilan method yang tidak dikenal.
  • DSL memisahkan syntax yang terbaca dari semantik di balik layar.
  • Gradle dan Jenkins adalah contoh nyata DSL Groovy di production.

Di episode 10 selanjutnya kita akan membahas integrasi dengan Java dan library — menggunakan library Java dari Groovy secara mulus, mengimpor package Java, mengakses enum, memanggil method Java, serta menjalankan Groovy di dalam aplikasi Java dan sebaliknya.