# adapter:inbound:grpc — inbound gRPC adapter (skeleton machinery) ## Registered identity - Module ID: `adapter-inbound-grpc` - Gradle path: `:adapter:inbound:grpc` - Focused test: `./gradlew :adapter:inbound:grpc:test --console=plain` - Runtime baseline: Java 21; repository framework baseline: Spring Boot 4.0.0. - Registry SSOT: `.harness/project/modules.yaml`. Package root: `dev.caskeleton.adapter.inbound.grpc`. 코드 주석에서 덜어낸 **설계 결정의 근거**는 [README.md](README.md) 가 모아둔다 (이 문서는 모듈 규칙 SSOT). ## Responsibility - gRPC 전송 인프라만: 서버 수명주기(`GrpcServerRunner`), 타입드 설정(`GrpcServerProperties`), 프로토콜 에러 매핑(`GrpcStatusMapper` + `GrpcExceptionHandlingInterceptor`), 그리고 `.proto` 없이도 부팅하는 최소 표면(standard health + reflection). - feature-agnostic: 모든 `io.grpc.BindableService` 빈을 generic 하게 등록한다. **WorkLog 등 구체 기능을 이름으로 알지 않는다.** ## Allowed - `:application-core`, `:domain-core`, `:shared-contract`. - `io.grpc:*` (grpc-netty-shaded / grpc-protobuf / grpc-stub / grpc-services), `spring-boot-starter`. ## Forbidden - outbound 어댑터(`:adapter:outbound:*`)에 대한 직접 의존 — 인바운드는 application 아웃바운드 포트를 통해서만 persistence/messaging/cache/http 에 닿는다 (ArchUnit `INBOUND_ADAPTERS_DO_NOT_DEPEND_ON_OUTBOUND_ADAPTERS`). - 이 스켈레톤 모듈에서의 `com.google.protobuf` 플러그인 / `.proto` — 스키마와 서비스는 feature (sample) 모듈이 소유한다. - 프로덕션 feature RPC 를 스켈레톤에 두는 것 — health/reflection 표면만 (web 의 `HealthcheckController` 와 동일 원칙). ## Config knobs (`ca-skeleton.grpc.*`) 타입드 `@ConfigurationProperties` 만 두고, 값은 composition-root `application.yml` 에 산다 (모듈별 `yml` 없음). | key | default | 의미 | |---|---|---| | `enabled` | `true` | gRPC 서버 기동 여부. 프로덕션 composition root 는 property 로 끌 수 있다 | | `port` | `9090` | 바인딩 TCP 포트. `0` 이면 ephemeral 포트(테스트) | | `reflectionEnabled` | `true` | v1 server reflection 노출(grpcurl/Postman 편의; 프로덕션에선 끄기) | | `shutdownGraceSeconds` | `5` | graceful shutdown 시 in-flight RPC 대기 초 | ## Feature 기여 방법 feature 모듈은 `io.grpc.BindableService` 를 `@Bean` 으로 등록하기만 하면 `GrpcServerRunner` 의 `ObjectProvider` 가 자동으로 인터셉터 뒤에 등록한다. 에러는 `ApiErrorCarrier` 를 구현한 예외(자신의 `ApiErrorCode` 를 실어)로 던지면 `GrpcExceptionHandlingInterceptor` 가 매핑한다. `sample-portfolio` 를 지워도 스켈레톤은 health + reflection 만으로 부팅한다 (disposability). ## Test ```bash cd src ./gradlew :adapter:inbound:grpc:test ```