Sepanjang Fase 2 kita berulang kali menyinggung application-dev.yml tanpa membahasnya secara menyeluruh sebagai satu sistem. Bab penutup Fase 2 ini menyatukan semuanya: bagaimana Order Service punya konfigurasi berbeda untuk development, test, dan production, tanpa harus menulis ulang atau mengedit manual setiap kali pindah environment.
Base config dan spring.profiles.active
Semuanya berawal dari application.yml, config dasar yang berlaku di environment mana pun:
server:
port: 8082
spring:
application:
name: order-service
profiles:
active: dev
app:
info:
name: Order Service
description: Service pengelolaan order - seri Belajar Kotlin Backend untuk Microservice
inventory-service:
base-url: http://localhost:8081
spring.profiles.active: dev adalah baris kuncinya — ini memberitahu Spring Boot: "kalau tidak ada yang override, aktifkan profile dev". Begitu sebuah profile aktif, Spring Boot secara otomatis mencari file bernama application-{profile}.yml (dalam kasus ini application-dev.yml) dan melayer isinya di atas application.yml — properti yang sama akan ditimpa oleh nilai dari file profile, sementara properti yang cuma ada di salah satu file tetap dipakai apa adanya.
Aktivasi profile ini bisa dioverride tanpa mengubah kode sama sekali, misalnya lewat environment variable saat menjalankan aplikasi:
SPRING_PROFILES_ACTIVE=prod java -jar order-service.jar
application-dev.yml — untuk kerja sehari-hari di laptop
spring:
datasource:
url: jdbc:postgresql://localhost:5432/order_service_dev
username: order_service
password: order_service
jpa:
hibernate:
ddl-auto: validate
show-sql: true
properties:
hibernate:
format_sql: true
flyway:
enabled: true
logging:
level:
com.indokoding.orderservice: DEBUG
Sudah kita bahas lengkap di bab 13: datasource menunjuk ke container Postgres lokal dari docker-compose.yml, show-sql: true untuk melihat query mentah di log, dan level logging DEBUG khusus package com.indokoding.orderservice supaya lebih mudah menelusuri apa yang terjadi saat development — tanpa membanjiri log dengan detail internal framework yang tidak relevan.
application-test.yml — konsistensi saat @SpringBootTest
spring:
jpa:
hibernate:
ddl-auto: validate
show-sql: false
flyway:
enabled: true
logging:
level:
com.indokoding.orderservice: INFO
org.testcontainers: INFO
File ini aktif ketika sebuah test menyalakan Spring context dengan profile test. Perhatikan tidak ada blok spring.datasource sama sekali di sini — ini bukan file yang belum lengkap, tapi sengaja: seperti yang sempat kita singgung di bab 17, integration test Order Service (OrderTransactionIntegrationTest dan AbstractIntegrationTest) mendapatkan datasource-nya secara dinamis dari container PostgreSQL Testcontainers lewat @DynamicPropertySource, bukan dari nilai statis di file YAML manapun. application-test.yml tetap berguna untuk menjaga konsistensi pengaturan lain (ddl-auto: validate, flyway.enabled: true, level logging yang lebih tenang daripada dev) supaya perilaku test sedekat mungkin dengan production — kita akan membahas pola Testcontainers ini lebih dalam di Fase 3.
application-prod.yml — kredensial lewat environment variable, bukan hardcode
spring:
datasource:
url: ${DATABASE_URL}
username: ${DATABASE_USERNAME}
password: ${DATABASE_PASSWORD}
jpa:
hibernate:
ddl-auto: validate
show-sql: false
flyway:
enabled: true
logging:
level:
root: WARN
com.indokoding.orderservice: INFO
inventory-service:
base-url: ${INVENTORY_SERVICE_URL}
Bandingkan dengan application-dev.yml: di sana url, username, password ditulis eksplisit sebagai teks (order_service, order_service) karena memang cuma dipakai di komputer masing-masing developer untuk database yang isinya boleh dibuang kapan saja. Di production, ketiganya diganti dengan sintaks ${...} — placeholder yang di-resolve Spring Boot dari environment variable saat aplikasi benar-benar dijalankan (DATABASE_URL, DATABASE_USERNAME, DATABASE_PASSWORD, INVENTORY_SERVICE_URL).
Ini bukan sekadar gaya penulisan, tapi prinsip keamanan dasar: kredensial production tidak pernah ikut ter-commit ke git. Kalau application-prod.yml berisi password database asli secara hardcode, siapa pun yang punya akses ke repository — atau riwayat git-nya — otomatis punya akses ke database production. Dengan pola ${DATABASE_URL}, file yang di-commit hanya berisi nama variable yang dibutuhkan, sementara nilai sesungguhnya disuntikkan lewat mekanisme lain saat deploy (environment variable di server, secret manager, atau konfigurasi platform hosting) — sesuatu yang akan kita sentuh lagi di Fase 8 (Containerization & Deployment).
Perbedaan lain yang layak dicatat: show-sql: false dan level logging root: WARN di production, dibanding show-sql: true dan DEBUG di dev. Mencetak setiap query SQL mentah ke log production itu boros (volume log jadi besar) dan berisiko (log bisa memuat data sensitif) — sesuatu yang hanya masuk akal saat development aktif, bukan saat aplikasi sudah melayani traffic sungguhan.
Satu pola, tiga environment
Ketiga file ini adalah contoh nyata kenapa hardcode satu file konfigurasi tunggal untuk semua environment adalah ide buruk: kebutuhan dev (kredensial lokal yang boleh terbuka, logging verbose) sangat berbeda dari kebutuhan production (kredensial rahasia lewat env var, logging minim). Dengan profile terpisah, satu baris spring.profiles.active (atau override lewat SPRING_PROFILES_ACTIVE) sudah cukup memindahkan seluruh perilaku aplikasi ke environment yang tepat, tanpa menyentuh kode Kotlin sama sekali.
Dengan ini, Fase 2 selesai — Order Service sekarang benar-benar tersambung ke PostgreSQL, skemanya dikelola lewat Flyway yang reviewable, query-nya efisien lewat projection, operasi bulk-nya aman lewat transaction, dan konfigurasinya adaptif per environment. Fase 3 berikutnya: kita bahas cara menguji semua ini dengan benar — dari unit test tercepat sampai integration test lawan database asli.
Bagian dari Series: Kotlin Backend Microservice - Belajar Fundamental sampai Microservice Nyata
Belajar Kotlin + Spring Boot dari fundamental bahasa (null safety, OOP, coroutines) sampai membangun sistem microservice sungguhan - REST API, Postgre...
Lihat Series Lengkap