{"slug":"business/003-gateway-delegates-composition","title":"ADR-003: Gateway Never Assembles Entities","section":"business","sectionLabel":"Business","status":"unclassified","type":"document","path":"business/003-gateway-delegates-composition.mdx","bytes":1228,"description":null,"updated":null,"source":"integratewise/Integratewise-docs-wiki","content":"\n**Status:** Accepted  \n**Date:** 2026-07-21  \n**Deciders:** Nirmal (Founder)\n\n---\n\n## Context\n\nThe gateway (BFF) previously contained inline composition logic: parallel service binding calls, D1 queries, and response assembly. This duplicated composition logic that should live in the Projection Engine.\n\n## Decision\n\nThe gateway **never constructs SharedWorkbench directly**. It delegates all composition to `ProjectionEngine` methods. The gateway handles only:\n\n1. Authentication and session resolution\n2. Request routing\n3. Response formatting and CORS\n4. Rate limiting\n\n## Consequences\n\n- **Positive:** Gateway is thin and focused. Composition logic is testable in isolation. No duplicate assembly code.\n- **Negative:** Gateway becomes a pass-through for composition requests. Adds one function call layer.\n- **Mitigation:** Performance is acceptable because composition is in-process (same worker), not a network hop.\n\n## Evidence\n\n- `services/gateway/src/projections.ts` — `routeProjectionRequest()` delegates to `ProjectionEngine`\n- Before: inline `Promise.allSettled()` with 4+ service binding calls per endpoint\n- After: single `engine.compose(request)` call per endpoint\n"}