# adapter:inbound:graphql — inbound GraphQL adapter (skeleton machinery) ## Registered identity - Module ID: `adapter-inbound-graphql` - Gradle path: `:adapter:inbound:graphql` - Focused test (derived from Gradle path): `./gradlew :adapter:inbound:graphql:test --console=plain` - Runtime baseline: Java 21; repository framework baseline: Spring Boot 4.0.0. - Registry SSOT: `src/config/architecture/modules.json`. Package root: `dev.caskeleton.adapter.inbound.graphql`. 코드 주석에서 덜어낸 **설계 결정의 근거**는 [README.md](README.md) 가 모아둔다 (이 문서는 모듈 규칙 SSOT). ## Responsibility - GraphQL 전송 인프라만: 최소 health 스키마(`skeleton.graphqls`) + `HealthGraphqlController`, 프로토콜 에러 매핑(`GraphqlExceptionResolver`). Spring for GraphQL 이 스키마와 컨트롤러를 자동 합성/바인딩하도록 얹는 얇은 계층이다. - feature-agnostic: `classpath:graphql/**` 스키마와 모든 `@Controller` `@QueryMapping`/ `@MutationMapping` 을 generic 하게 합성한다. **WorkLog 등 구체 기능을 이름으로 알지 않는다.** ## Allowed - `:application-core`, `:domain-core`, `:shared-contract`. - `spring-boot-starter-graphql`, `spring-boot-starter-web`, `jackson-datatype-jsr310` (전부 Spring Boot BOM 관리 — 버전 명시 없음). ## Forbidden - outbound 어댑터(`:adapter:outbound:*`)에 대한 직접 의존 — 인바운드는 application 아웃바운드 포트를 통해서만 persistence/messaging/cache/http 에 닿는다 (ArchUnit `INBOUND_ADAPTERS_DO_NOT_DEPEND_ON_OUTBOUND_ADAPTERS`, 일반 `..adapter.inbound..` 규칙이 이 모듈을 자동 커버 — per-module 규칙 추가 불필요). - 프로덕션 feature 쿼리/뮤테이션을 스켈레톤에 두는 것 — health 표면만 (web 의 `HealthcheckController` 와 동일 원칙). feature 스키마/컨트롤러/매퍼는 sample 모듈이 소유한다. - 모듈별 `yml` — 설정은 프레임워크 `spring.graphql.*` 로 composition-root `application.yml` 에 산다. ## Error mapping (`Category → ErrorType`) feature 는 `ApiErrorCarrier` 를 구현한 예외(자신의 `ApiErrorCode` 를 실어)를 던지면 `GraphqlExceptionResolver` 가 `GraphQLError`(ErrorType + `extensions{code, category}`)로 매핑한다. 비-`ApiErrorCarrier` 예외는 `null` 반환 → 다른 resolver / Spring 기본 처리. 표는 [README.md](README.md). ## Feature 기여 방법 - **스키마**: `src/main/resources/graphql/*.graphqls` 를 두면 `classpath:graphql/**` 병합으로 합쳐진다. - **핸들러**: `@Controller` + `@QueryMapping`/`@MutationMapping` 빈을 등록하면 자동 바인딩된다. - **도메인 예외 매핑**: sample 이 자신의 `DataFetcherExceptionResolver` 를 추가해 도메인 예외를 `PortfolioErrorCode` 로 매핑한다(스켈레톤 resolver 보다 앞 순서). 스켈레톤은 `ApiErrorCarrier` 만 처리. `sample-portfolio` 를 지워도 스켈레톤은 health 스키마만으로 부팅한다 (disposability). ## Test ```bash cd src ./gradlew :adapter:inbound:graphql:test ```