Series MapLesson 45 / 112
Focus mode active/Press Alt+Shift+R to toggle/Esc to exit
Build CoreOrdered learning track

Application Composition Review

Application Composition Review Checklist

Checklist komposisi aplikasi JAX-RS enterprise untuk senior PR review: wiring, scope, config, secret, lifecycle, shutdown, observability, security, dan test seam

4 min read676 words
PrevNext
Lesson 45112 lesson track22–61 Build Core
#architecture-review#dependency-injection#application-composition#lifecycle+5 more

Part 045 — Application Composition Review Checklist

Fokus part ini: menyatukan beberapa part sebelumnya menjadi checklist review yang bisa dipakai saat membaca PR, onboarding codebase, atau mengevaluasi service JAX-RS enterprise. Ini bukan checklist kosmetik. Ini checklist untuk menemukan bug lifecycle, hidden dependency, unsafe scope, config drift, weak shutdown, missing observability, dan deployment-risk sebelum masuk production.

Application composition adalah cara sebuah service disusun saat runtime.

Bukan hanya struktur folder.

Bukan hanya dependency injection.

Bukan hanya ResourceConfig.

Application composition adalah jawaban atas pertanyaan:

Ketika service start, object apa dibuat?
Siapa membuatnya?
Scope-nya apa?
Config dari mana?
Secret dari mana?
Lifecycle-nya kapan dimulai dan selesai?
Thread mana yang menjalankan logic-nya?
Context apa yang ikut terbawa?
Bagaimana object itu di-test?
Bagaimana object itu dimatikan saat shutdown?
Apa failure mode kalau dependency-nya tidak tersedia?

Senior engineer tidak cukup bertanya:

Apakah code ini compile?
Apakah endpoint ini return 200?

Senior engineer harus bertanya:

Apakah service ini tersusun dengan lifecycle yang benar?
Apakah wiring-nya eksplisit?
Apakah failure-nya bisa diobservasi?
Apakah rollback-nya aman?
Apakah perubahan ini memperbesar coupling tersembunyi?

1. Why Application Composition Review Exists

Bug application composition biasanya tidak muncul di unit test sederhana.

Ia muncul saat:

- service baru start di environment tertentu
- config berbeda antara local/staging/prod
- injection gagal karena binding tidak terdaftar
- provider global berubah dan memengaruhi semua endpoint
- singleton menyimpan mutable/request-specific state
- thread pool tidak membawa MDC/security context
- shutdown tidak menutup HTTP client/Kafka producer/DB pool
- secret rotation tidak diambil ulang
- feature flag default salah
- tenant resolver tidak tersedia di background thread

Ini jenis bug yang mahal karena gejalanya sering terlihat seperti hal lain:

- 500 random
- timeout sporadis
- memory leak
- connection leak
- missing trace ID
- audit log kosong
- tenant data leakage
- startup failure hanya di production-like environment

Application composition review bertujuan menemukan risiko itu sebelum deploy.


2. Composition Mental Model

Sebuah JAX-RS service enterprise biasanya memiliki komposisi seperti ini:

flowchart TD A[Runtime / Container] --> B[JAX-RS Application / ResourceConfig] B --> C[Resources] B --> D[Providers] B --> E[Filters / Interceptors] B --> F[ExceptionMappers] C --> G[Application Services] G --> H[Domain Services] G --> I[Repositories] G --> J[Integration Clients] G --> K[Event Publishers] I --> L[DataSource / Connection Pool] J --> M[HTTP Client Pool] K --> N[Kafka Producer / Messaging Client] B --> O[DI Container: HK2 / CDI / Manual Wiring] O --> C O --> D O --> E O --> F O --> G O --> I O --> J O --> K P[Configuration Sources] --> O Q[Secret Sources] --> O R[Feature Flag System] --> G S[Telemetry / Logging] --> E S --> G

Review harus membaca graph ini dari atas ke bawah.

Jangan hanya membaca resource method.

Resource method hanyalah titik masuk.

Yang lebih penting adalah object graph yang terbentuk di belakangnya.


3. Review Order

Urutan review yang praktis:

1. Bootstrap and runtime entrypoint
2. Resource/provider/filter/mapper registration
3. Dependency injection and object lifecycle
4. Configuration and secret resolution
5. Tenant, feature flag, and environment-specific behavior
6. Threading, executor, and context propagation
7. External resource ownership
8. Shutdown and cleanup
9. Error handling and observability wiring
10. Security and audit wiring
11. Test seams and local workflow
12. Rollout, rollback, and compatibility implications

Rule of thumb:

Review composition from startup to shutdown, not only from request to response.

4. Bootstrap and Runtime Entrypoint Checklist

Cari titik start aplikasi.

Kemungkinan bentuk:

- web.xml
- ServletContainerInitializer
- subclass Application
- Jersey ResourceConfig
- embedded Grizzly main class
- container-provided GlassFish deployment
- Tomcat/Jetty WAR deployment
- custom launcher
- Spring/Dropwizard/MicroProfile wrapper jika ada

Checklist:

[ ] Runtime entrypoint jelas.
[ ] JAX-RS application class jelas.
[ ] Base path jelas.
[ ] Package scanning atau explicit registration dipahami.
[ ] Tidak ada duplicate registration yang silent.
[ ] Startup logs menunjukkan resource/provider aktif.
[ ] Startup failure fail-fast, bukan lazy failure saat request pertama.
[ ] Environment-specific bootstrap tidak berbeda secara liar.

Senior review question:

Bisakah engineer baru menjawab: “apa yang membuat endpoint ini aktif di runtime?”

Kalau tidak bisa, composition terlalu implisit.


5. Resource, Provider, Filter, and Mapper Registration Checklist

Dalam JAX-RS/Jersey, banyak behavior penting datang dari extension point.

- Resource class
- ContainerRequestFilter
- ContainerResponseFilter
- ReaderInterceptor
- WriterInterceptor
- MessageBodyReader
- MessageBodyWriter
- ExceptionMapper
- Feature
- Binder

Checklist:

[ ] Semua global provider/filter/interceptor diketahui.
[ ] Auth filter order jelas.
[ ] Logging filter tidak membaca body besar secara berbahaya.
[ ] ExceptionMapper precedence jelas.
[ ] MessageBodyReader/Writer tidak overlap media type secara ambigu.
[ ] Provider yang security-sensitive tidak hanya bergantung pada package scanning tersembunyi.
[ ] Registration eksplisit untuk behavior kritikal.
[ ] Startup test membuktikan provider penting terdaftar.

Anti-pattern:

// Anti-pattern: critical behavior hanya bergantung pada package scanning
@Provider
public class SecurityFilter implements ContainerRequestFilter {
    // jika package scanning berubah, security bisa hilang
}

Lebih aman untuk behavior kritikal:

public class ApiApplication extends ResourceConfig {
    public ApiApplication() {
        register(SecurityFilter.class);
        register(ApiExceptionMapper.class);
        register(CorrelationIdFilter.class);
    }
}

Catatan:

Ini bukan berarti package scanning selalu buruk.
Yang buruk adalah behavior security/observability kritikal yang tidak dapat diverifikasi secara eksplisit.

6. Dependency Injection Checklist

DI review bukan sekadar melihat @Inject.

Pertanyaan utama:

Siapa owner object ini?
Scope-nya apa?
State-nya apa?
Apakah object ini thread-safe?
Apakah dependency-nya required atau optional?
Bagaimana object ini diganti di test?

Checklist:

[ ] Constructor injection diprioritaskan untuk dependency mandatory.
[ ] Field injection tidak menyembunyikan dependency penting.
[ ] Scope eksplisit untuk singleton/request/application/session jika ada.
[ ] Tidak ada mutable request-specific state di singleton.
[ ] Tidak ada circular dependency.
[ ] Tidak ada service locator call tersebar di business logic.
[ ] Factory/provider digunakan hanya saat lifecycle memang dinamis.
[ ] Binding test dapat mengganti dependency eksternal.
[ ] Injection failure fail-fast saat startup bila memungkinkan.

Red flag:

public class QuoteResource {
    @Inject
    private QuoteService quoteService;

    @Inject
    private TenantContext tenantContext;

    @Inject
    private FeatureFlagClient featureFlagClient;
}

Bukan karena field injection selalu salah.

Masalahnya: dependency penting tersembunyi dari constructor dan sulit dibaca saat review.

Lebih eksplisit:

public class QuoteResource {
    private final QuoteService quoteService;
    private final TenantContext tenantContext;
    private final FeatureFlagClient featureFlagClient;

    @Inject
    public QuoteResource(
        QuoteService quoteService,
        TenantContext tenantContext,
        FeatureFlagClient featureFlagClient
    ) {
        this.quoteService = quoteService;
        this.tenantContext = tenantContext;
        this.featureFlagClient = featureFlagClient;
    }
}

7. Scope and Lifecycle Checklist

Scope bug sering sulit dilacak.

Contoh:

- request-scoped object diinjeksi ke singleton tanpa proxy yang benar
- singleton menyimpan tenant ID terakhir
- provider global menyimpan user ID di field
- object mahal dibuat per request
- object yang harus ditutup tidak pernah ditutup

Checklist:

[ ] Resource lifecycle diketahui: per-request atau singleton.
[ ] Provider lifecycle diketahui.
[ ] Singleton object thread-safe.
[ ] Request-scoped dependency tidak bocor ke background thread.
[ ] Expensive object tidak dibuat per request tanpa alasan.
[ ] Resource closeable memiliki shutdown hook.
[ ] Object lifecycle selaras dengan underlying resource lifecycle.

Senior heuristic:

Mutable state + singleton + request data = incident candidate.

8. Configuration Composition Checklist

Konfigurasi adalah bagian dari composition.

Config menentukan object graph.

Contoh:

- timeout outbound client
- DB pool size
- Kafka topic name
- feature flag default
- tenant routing mode
- auth issuer/audience
- serializer settings
- cache TTL

Checklist:

[ ] Config source jelas.
[ ] Precedence jelas: default < file < env < secret store < runtime override.
[ ] Required config divalidasi saat startup.
[ ] Invalid config membuat service fail-fast.
[ ] Default aman untuk production.
[ ] Config sensitive tidak masuk log.
[ ] Config drift antar environment bisa dideteksi.
[ ] Runtime reload tidak menyebabkan partial update berbahaya.
[ ] Per-tenant config punya fallback aman.

Anti-pattern:

int timeoutMs = Integer.parseInt(System.getenv("DOWNSTREAM_TIMEOUT"));

Masalah:

- tidak ada default eksplisit
- tidak ada validation
- tidak ada config inventory
- sulit di-test
- sulit dilacak ownership-nya

Lebih baik:

public record DownstreamClientConfig(
    Duration connectTimeout,
    Duration readTimeout,
    int maxConnections
) {
    public DownstreamClientConfig {
        if (connectTimeout.isNegative() || connectTimeout.isZero()) {
            throw new IllegalArgumentException("connectTimeout must be positive");
        }
        if (readTimeout.isNegative() || readTimeout.isZero()) {
            throw new IllegalArgumentException("readTimeout must be positive");
        }
        if (maxConnections <= 0) {
            throw new IllegalArgumentException("maxConnections must be positive");
        }
    }
}

9. Secret and Credential Checklist

Secret adalah runtime dependency.

Treat it like a dependency with lifecycle.

Checklist:

[ ] Secret tidak ada di source code.
[ ] Secret tidak ada di plain config file yang masuk repo.
[ ] Secret tidak tercetak di startup log.
[ ] Secret source jelas: Kubernetes Secret, external secret, cloud secret manager, vault, etc.
[ ] Rotation behavior dipahami.
[ ] Client dapat recover dari rotated credential jika platform mendukung.
[ ] Secret access diaudit.
[ ] Least privilege diterapkan.
[ ] Local development punya mekanisme aman tanpa copy prod secret.

PR review question:

Kalau secret ini dirotasi saat service berjalan, apa yang terjadi?

Jawaban yang buruk:

Tidak tahu, seharusnya aman.

Jawaban yang lebih baik:

Secret dibaca saat startup saja, jadi rotation butuh rolling restart. Ini sesuai runbook X.

Atau:

Client mengambil credential dari provider yang support refresh. Ada test/integration check untuk expired token.

10. Tenant Composition Checklist

Di enterprise CPQ/order management, tenant sering bukan detail kecil.

Tenant bisa memengaruhi:

- routing
- authorization
- product catalog
- pricing rule
- tax behavior
- data partition
- feature flag
- audit log
- reporting
- external integration endpoint

Checklist:

[ ] Tenant resolution dilakukan di boundary yang jelas.
[ ] Tenant ID divalidasi dan tidak hanya dipercaya dari header mentah.
[ ] Tenant context dipropagasi ke service/repository/integration layer.
[ ] Tenant context tidak disimpan di mutable singleton.
[ ] Tenant-aware logging ada, tetapi tidak melanggar cardinality/PII policy.
[ ] Tenant-specific config punya fallback aman.
[ ] Tenant-specific catalog/pricing tidak bercampur.
[ ] Background job memiliki tenant scope eksplisit.
[ ] Test negative cross-tenant tersedia untuk operasi sensitif.

Failure mode serius:

Tenant A melihat quote/order/customer/product catalog Tenant B.

Ini bukan bug biasa.

Ini security/compliance incident.


11. Feature Flag and Rollout Checklist

Feature flag adalah bagian composition karena menentukan path logic runtime.

Checklist:

[ ] Flag punya owner.
[ ] Flag punya default aman.
[ ] Flag bisa dimatikan cepat jika risk tinggi.
[ ] Flag evaluation tidak tersebar tanpa abstraction.
[ ] Flag state tercatat di log/trace untuk debugging penting.
[ ] Flag tidak membuat API contract berubah secara tidak compatible.
[ ] Flag tidak membuat DB schema dependency yang belum tersedia.
[ ] Stale flag punya cleanup task.
[ ] Tenant-specific enablement diuji.

Bad pattern:

if (featureFlags.isEnabled("new-pricing")) {
    return newPricingEngine.price(request);
}
return oldPricingEngine.price(request);

Ini kelihatan normal.

Yang harus direview:

- apakah old/new engine punya output rounding yang sama?
- apakah audit log mencatat engine mana dipakai?
- apakah fallback bisa terjadi bila new engine timeout?
- apakah schema event berubah?
- apakah customer support bisa mengetahui path yang dipakai?

12. Threading, Executor, and Context Checklist

Threading composition menentukan apakah context hilang.

Checklist:

[ ] Executor yang dipakai jelas dan bounded.
[ ] Tidak membuat thread pool ad hoc di business logic.
[ ] Queue size jelas.
[ ] Rejection policy jelas.
[ ] MDC/correlation context dipropagasi.
[ ] Security context dipropagasi hanya jika aman.
[ ] Tenant context dipropagasi eksplisit.
[ ] ThreadLocal dibersihkan.
[ ] Background task tidak memakai request-scoped object setelah request selesai.

Red flag:

CompletableFuture.runAsync(() -> service.doWork(request));

Masalah:

- pakai ForkJoinPool common pool
- context hilang
- cancellation tidak jelas
- error bisa tidak terobservasi
- request object bisa dipakai setelah lifecycle-nya selesai

Lebih aman:

CompletionStage<Result> result = contextAwareExecutor.submit(
    RequestContext.capture(),
    () -> service.doWork(command)
);

Catatan:

Nama API ini ilustratif. Verifikasi pattern internal yang dipakai di codebase.

13. External Resource Ownership Checklist

Object yang memiliki koneksi eksternal harus jelas owner-nya.

Contoh:

- DataSource / connection pool
- HTTP client
- Kafka producer
- Kafka consumer
- Redis client
- cloud SDK client
- scheduler
- executor
- metrics exporter

Checklist:

[ ] Object mahal dibuat sekali, bukan per request.
[ ] Pool config eksplisit.
[ ] Timeout config eksplisit.
[ ] Lifecycle close/shutdown jelas.
[ ] Health/readiness check mempertimbangkan dependency kritikal.
[ ] Metrics tersedia untuk pool/queue/latency/error.
[ ] Resource leak bisa dideteksi.
[ ] Test tidak memakai production endpoint/credential.

Common bug:

public Response getQuote(String id) {
    Client client = ClientBuilder.newClient();
    Response response = client.target(url).request().get();
    return Response.ok(response.readEntity(String.class)).build();
}

Masalah:

- client dibuat per request
- connection pool tidak dimanfaatkan
- response lifecycle rawan leak
- timeout mungkin default/tidak jelas

14. Shutdown and Graceful Termination Checklist

Production service tidak hanya harus bisa start.

Ia harus bisa stop dengan benar.

Checklist:

[ ] HTTP server berhenti menerima request baru.
[ ] In-flight request diberi waktu selesai.
[ ] Kafka consumer berhenti poll dan commit dengan aman.
[ ] Kafka producer flush/close sesuai timeout.
[ ] DB pool ditutup.
[ ] HTTP client pool ditutup.
[ ] Executor shutdown graceful lalu forced jika perlu.
[ ] Background job diberi cancellation signal.
[ ] Metrics/log exporter flush jika diperlukan.
[ ] Kubernetes terminationGracePeriod cukup untuk cleanup.

Failure mode:

- duplicate event karena shutdown saat commit belum selesai
- lost audit log karena exporter belum flush
- stuck pod karena executor non-daemon tidak shutdown
- 502 spike karena pod menerima traffic saat belum ready

15. Error Handling Composition Checklist

ExceptionMapper global bisa menjadi blessing atau disaster.

Checklist:

[ ] Domain exception mapping jelas.
[ ] Validation exception mapping jelas.
[ ] Auth exception mapping jelas.
[ ] Technical exception mapping tidak membocorkan stack trace.
[ ] Error response punya stable code.
[ ] Retryable vs non-retryable error dibedakan.
[ ] Logging level sesuai severity.
[ ] Correlation ID masuk error response atau response header sesuai policy.
[ ] ExceptionMapper tidak menelan error yang harus alert.

Risk:

@Provider
public class CatchAllExceptionMapper implements ExceptionMapper<Throwable> {
    public Response toResponse(Throwable ex) {
        return Response.status(500).entity("error").build();
    }
}

Masalah:

- semua error terlihat sama
- operator kehilangan signal
- client tidak tahu retry/non-retry
- security incident bisa tersamar sebagai 500 biasa

16. Observability Composition Checklist

Observability bukan fitur tambahan.

Ia harus masuk composition sejak awal.

Checklist:

[ ] Correlation ID filter aktif untuk semua request.
[ ] Request log tidak membocorkan PII/secret.
[ ] Error log memiliki endpoint, method, status, error code, correlation ID.
[ ] Metrics punya latency histogram per endpoint dengan cardinality terkendali.
[ ] Tracing span dibuat untuk inbound HTTP.
[ ] Downstream HTTP/DB/Kafka/Redis call terinstrumentasi.
[ ] Context propagation lintas executor/Kafka jelas.
[ ] Audit log terpisah dari application log jika dibutuhkan.
[ ] Dashboard dan alert merefleksikan path kritikal.

Review question:

Jika endpoint ini lambat di production, signal apa yang akan membuktikan bottleneck-nya?

Kalau jawabannya “lihat log manual”, observability belum cukup.


17. Security Composition Checklist

Security sering tersebar di filter, annotation, service method, repository, dan gateway.

Checklist:

[ ] Authentication terjadi di boundary yang jelas.
[ ] Authorization tidak hanya bergantung pada UI/gateway.
[ ] Object-level authorization ada untuk resource sensitif.
[ ] Tenant boundary diterapkan di semua data access path.
[ ] Secret tidak masuk log/error response.
[ ] Audit trail tersedia untuk operasi penting.
[ ] Token issuer/audience/expiry/clock skew divalidasi.
[ ] Service-to-service identity jelas.
[ ] Default deny untuk endpoint baru.
[ ] Negative security tests tersedia.

Anti-pattern:

Endpoint internal tidak butuh auth karena hanya dipanggil service lain.

Senior response:

Internal network is not a security model. Verify service identity, network policy, token audience, and least privilege.

18. Test Seam Checklist

Composition yang baik mudah dites.

Checklist:

[ ] Dependency eksternal bisa diganti fake/test container.
[ ] Resource dapat dites tanpa full production runtime jika memungkinkan.
[ ] Provider/filter/mapper kritikal punya test.
[ ] Config validation punya test.
[ ] Tenant/feature flag path punya test.
[ ] Startup composition punya smoke test.
[ ] Integration test membuktikan wiring utama.
[ ] Test tidak bergantung pada ordering global yang rapuh.

Useful test categories:

- unit test for pure domain/application service
- resource test for request/response/error shape
- provider/filter test for cross-cutting behavior
- startup smoke test for registration/injection/config
- integration test with PostgreSQL/Kafka/Redis/testcontainers
- contract test for API/event compatibility

19. Release and Rollback Composition Checklist

Composition changes dapat membuat rollback sulit.

Checklist:

[ ] Perubahan API backward-compatible.
[ ] Perubahan DB mengikuti expand-contract.
[ ] Perubahan event schema compatible.
[ ] Feature flag default aman.
[ ] New dependency punya timeout/circuit breaker.
[ ] New config punya safe default dan validation.
[ ] Rollback tidak menyebabkan code lama membaca schema/event baru yang incompatible.
[ ] Deployment strategy jelas: rolling/canary/blue-green.
[ ] Observability signal cukup untuk decide continue/rollback.

Composition PR yang berisiko:

- menambah provider/filter global
- mengganti ObjectMapper global
- mengganti ExceptionMapper catch-all
- mengganti auth filter order
- menambah async executor
- menambah cache global
- mengubah config precedence
- mengubah transaction boundary
- menambah feature flag pada path core

20. Internal Verification Checklist for CSG-like Enterprise Codebase

Karena detail internal tidak boleh diasumsikan, verifikasi dari evidence:

Runtime and bootstrap
[ ] Runtime aktual: Jersey/GlassFish/Grizzly/Tomcat/Jetty/other.
[ ] Entrypoint aplikasi.
[ ] ResourceConfig/Application class.
[ ] Package scanning vs explicit registration.

DI and lifecycle
[ ] DI container: HK2/CDI/manual/other.
[ ] Scope annotation yang digunakan.
[ ] Singleton/provider lifecycle.
[ ] Shutdown hook atau lifecycle manager.

Configuration
[ ] Config source dan precedence.
[ ] Environment/profile model.
[ ] Tenant-specific config model.
[ ] Feature flag system.
[ ] Secret source dan rotation policy.

Cross-cutting
[ ] Auth filter.
[ ] Authorization layer.
[ ] ExceptionMapper hierarchy.
[ ] Logging/correlation filter.
[ ] OpenTelemetry/tracing integration.
[ ] Audit logging pattern.

External resources
[ ] DataSource/connection pool owner.
[ ] HTTP client owner.
[ ] Kafka producer/consumer owner.
[ ] Redis/cloud SDK client owner.
[ ] Executor/thread pool owner.

Testing and operations
[ ] Startup smoke test.
[ ] Integration test pattern.
[ ] Local development setup.
[ ] Runbook/shutdown behavior.
[ ] Deployment/rollback process.

21. PR Review Template

Gunakan template ini untuk PR yang mengubah composition:

## Composition Review

### Bootstrap / registration
- [ ] Resource/provider/filter/mapper registration jelas
- [ ] Tidak bergantung pada scanning tersembunyi untuk behavior kritikal

### Dependency and lifecycle
- [ ] Dependency mandatory eksplisit
- [ ] Scope benar
- [ ] Tidak ada mutable request state di singleton
- [ ] External resource punya owner dan close lifecycle

### Configuration and secret
- [ ] Config source dan precedence jelas
- [ ] Required config divalidasi
- [ ] Secret tidak masuk code/log/error
- [ ] Default aman untuk production

### Context and threading
- [ ] Executor bounded
- [ ] MDC/trace/tenant/security context propagation jelas
- [ ] Cancellation/shutdown behavior jelas

### Observability and security
- [ ] Error/log/metric/trace cukup untuk debug
- [ ] Auth/authz/tenant boundary tidak dilemahkan
- [ ] Audit requirement dipenuhi

### Rollout and rollback
- [ ] Backward compatible
- [ ] Feature flag/kill switch jika risk tinggi
- [ ] Rollback/roll-forward aman

22. Common Composition Smells

Smell list:

- “It works locally” tetapi tidak ada startup smoke test.
- Object dibuat dengan `new` di banyak tempat padahal punya config/secret/pool.
- `System.getenv()` tersebar di business logic.
- `ServiceLocator.getService()` dipanggil dari domain logic.
- Global ObjectMapper diubah tanpa contract test.
- Catch-all exception mapper menelan semua error.
- Static mutable cache tanpa invalidation.
- ThreadLocal tidak dibersihkan.
- Executor dibuat per request.
- Kafka producer dibuat per publish.
- HTTP client dibuat per request.
- Feature flag tanpa owner/cleanup.
- Tenant ID hanya string biasa yang mudah hilang.
- Startup berhasil walau config required kosong.

23. Senior Mental Model

Application composition review mencari tiga hal:

1. Hidden coupling
2. Lifecycle mismatch
3. Unobservable failure

Kalau tiga hal itu terkendali, service biasanya lebih mudah dioperasikan.

Kalau tidak, service mungkin terlihat rapi di code review kecil tetapi rapuh di production.

Senior conclusion:

Good application composition makes the runtime obvious.
Bad application composition makes production behavior surprising.

24. Final Cheat Sheet

Review startup:
- entrypoint
- ResourceConfig/Application
- provider/filter/mapper registration
- fail-fast config validation

Review dependency graph:
- constructor injection
- scope
- state ownership
- external resource owner

Review runtime behavior:
- thread pool
- context propagation
- timeout/cancellation
- graceful shutdown

Review cross-cutting behavior:
- auth
- authorization
- tenant isolation
- exception mapping
- logging/tracing/metrics/audit

Review production safety:
- config/secret
- feature flag
- rollout/rollback
- compatibility
- tests

If you can explain the object graph, lifecycle graph, and failure graph, you understand the service.

If you cannot, the service is still partly a black box.

Lesson Recap

You just completed lesson 45 in build core. Use the series map if you want to review the broader track, or continue directly into the next lesson while the context is still warm.

Continue The Track

Keep the momentum while the lesson is still fresh. Move backward for review or continue forward into the next concept.