Files
llm-wiki/raw/blog-topics/idempotency-executor-application-layer-clean-architecture-2026-06-09.md

4.9 KiB

title, source_type, status, related_branches, related_projects, tags, created, status_label, target_audience, inspiration_url, archive_url
title source_type status related_branches related_projects tags created status_label target_audience inspiration_url archive_url
blog-topic / idempotency-executor-application-layer-clean-architecture-2026-06-09 blog-topic raw
feature-rate-limit-idempotency-contract
ca-tmpl
blog-topic
ca-tmpl
idempotency
clean-architecture
rate-limit
2026-06-09 ready-for-canonical backend-engineer

blog-topic: 멱등성을 application layer 실행기로 — Clean Architecture에서 rate-limit/idempotency 운영 계약

Layer: raw/blog-topics/ — feature-rate-limit-idempotency-contract 구현에서 나온 글감.

Parent / 부모

글감 / Topic

운영 멱등성과 rate-limit을 "프레임워크 미들웨어"가 아니라 계층 소유권으로 배치한 사례.

글감 / Topic seed

  • 한 문장 요지: idempotency는 application-layer executor가, rate-limit은 presentation interceptor가 소유하도록 나눠 Clean Architecture 경계를 명시한다.
  • 예상 제목 후보:
    • 멱등성을 application layer 실행기로 두기
    • Clean Architecture에서 idempotency와 rate-limit 소유권 나누기

다룰 포인트

  1. owner_layer 분리: idempotency 코드(409/422)는 owner_layer: applicationIdempotencyExecutor 포트 + IdempotencyStore 포트 + DB 어댑터로 application/infra에 둠. rate-limit(429)은 owner_layer: presentation → adapter-web HandlerInterceptor. 같은 "운영 횡단 관심사"라도 코드/응답 소유 계층이 다르다.
  2. filter vs interceptor: rate-limit key가 IP + uri_template(normalized)를 요구 → servlet filter는 handler mapping 이전이라 route template(/v1/worklogs/{id})을 모름. HandlerInterceptor로 옮겨 BEST_MATCHING_PATTERN_ATTRIBUTE를 사용.
  3. 명시적 실행기 vs AOP: KEYED use case를 BeanPostProcessor/AOP로 감싸는 대신 executor.execute(ctx, action, codec) 명시 호출. 호출부가 약간 장황하지만 ArchUnit/테스트 단순성과 스켈레톤 투명성을 얻음.
  4. insert-or-read + unique 제약을 동시성 중재자로: 200ms in-flight wait는 IETF 즉시-409 SHOULD의 "운영 친화적 변형"(표준 그대로 아님). fingerprint(SHA-256) mismatch는 IETF 422 권고 정합.
  5. port-codec 분리로 application의 wire-format 중립성: 실행기는 IdempotentResponseCodec<R>(web JSON 소유)로 직렬화만 위임 → application은 transport/storage 중립.
  6. UNSUPPORTED_IMPL_DECISION 정직성: 200ms·SHA-256·8KB·fixed-window·canonicalization 미적용은 외부 표준이 강제하지 않음을 코드 주석에 명시 — "표준 따름" 과장 금지.

관련

Canonical 전환 후보 / Canonical extraction candidates

  • wiki/projects/ca-tmpl/idempotency-key-design.md 후보:
    • idempotency executor의 application-layer ownership와 rate-limit presentation ownership 분리.
  • 필요한 추가 검증:
    • IdempotencyExecutor, IdempotencyStore, response codec, interceptor 구현 여부.

트리거 / Trigger

핵심 주장 후보 / Claim candidates

  • 사실 후보:
    • idempotency와 rate-limit은 같은 운영 횡단 관심사처럼 보여도 owner layer가 다르다.
    • idempotency executor는 application/use case 실행 경계에 놓고, rate-limit은 route template을 아는 web interceptor가 맡는 구조다.
  • 의견/해석 후보:
    • AOP보다 명시 실행기가 skeleton 투명성과 테스트 용이성을 준다.

Outline seed

  1. owner layer를 application과 presentation으로 나눈다.
  2. filter와 interceptor가 route template을 볼 수 있는 시점 차이를 설명한다.
  3. IdempotencyExecutor와 response codec 분리로 wire format 중립성을 유지한다.

Sources / 근거 후보

미해결 / Unknown

  • 아직 확인해야 할 사실: 현재 ca-tmpl 코드의 executor/storage/interceptor 구현 여부.
  • 과장하면 안 되는 부분: IETF draft 준수와 ca-tmpl의 200ms wait 변형을 섞지 않는다.

Decision / 처리 결정

  • 액션: promote-to-canonical
  • 이유: wiki/projects/ca-tmpl/idempotency-key-design.md 에 application-layer idempotency executor 글감으로 반영했다.
  • 다음 단계: target canonical이 아직 draft 이므로 blogify 전 실제 구현 등급을 재확인한다.