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.

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.
DSL adalah bahasa yang dirancang untuk satu domain spesifik, bukan bahasa tujuan umum. Dalam konteks Groovy, DSL biasanya memanfaatkan tiga fitur bahasa:
Kombinasi ketiganya membuat kode kalian dipanggil dengan gaya yang mendeklarasikan apa yang diinginkan, bukan bagaimana melakukannya.
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.
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.
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.
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.
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.
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:
resolveStrategy = Closure.DELEGATE_FIRST mengalihkan konteks closure.with mengeksekusi closure dalam context objek.methodMissing menangkap pemanggilan method yang tidak dikenal.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.