Skip to content

CoreNetwork HTTP 인프라 추가 - #9

Merged
gnoes-ios merged 10 commits into
devfrom
feat/core-network
Aug 4, 2026
Merged

CoreNetwork HTTP 인프라 추가#9
gnoes-ios merged 10 commits into
devfrom
feat/core-network

Conversation

@gnoes-ios

Copy link
Copy Markdown
Contributor

📌 변경 요약

  • CoreNetwork 공통 HTTP 인프라 추가
  • plain/authed 클라이언트와 401 refresh 재시도 흐름 구현
  • CoreNetwork 단위 테스트 및 SharedLogger 의존 문서 반영

📌 변경 내용

Tuist / CoreNetwork

  • CoreNetwork 테스트 타겟 활성화
  • SharedLogger 의존 추가
  • Placeholder 제거

CoreNetwork API

  • APIEndpoint, HTTPMethod 요청 계약 추가
  • status 기반 NetworkError 모델 추가
  • NetworkConfiguration, JSON coding 기본값 추가
  • TokenProviding, TokenRefreshing 포트 추가
  • SharedLogger 기반 네트워크 로깅/마스킹 헬퍼 추가

Client

  • NetworkClient 계약 추가
  • DefaultNetworkClient plain/authed factory 추가
  • URLRequest 조립, status 매핑, void/Decodable 요청 경로 구현
  • authed 401 single-flight refresh 및 1회 재시도 구현

Tests

  • URLProtocol 기반 request/error/auth retry 단위 테스트 추가
  • endpoint/token stub 지원 코드 추가

Docs

  • Core 모듈 SharedLogger 의존 규칙 반영
  • CoreNetwork 로깅 경계 문구 추가

@gnoes-ios gnoes-ios added the feat 새로운 기능 label Aug 4, 2026
@gnoes-ios gnoes-ios self-assigned this Aug 4, 2026
@coderabbitai

coderabbitai Bot commented Aug 4, 2026

Copy link
Copy Markdown

Review Change Stack

Warning

Review limit reached

@gnoes-ios, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 23 minutes

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: ed306709-28f5-4658-975f-4e2a38f9195c

📥 Commits

Reviewing files that changed from the base of the PR and between 34b28b6 and b3fbccf.

📒 Files selected for processing (8)
  • .swiftlint.yml
  • Projects/Core/Network/Sources/Client/DefaultNetworkClient.swift
  • Projects/Core/Network/Sources/Error/NetworkError.swift
  • Projects/Core/Network/Sources/Logging/NetworkLog.swift
  • Projects/Core/Network/Tests/DefaultNetworkClientReviewFixTests.swift
  • Projects/Core/Network/Tests/NetworkErrorMappingTests.swift
  • Projects/Core/Network/Tests/NetworkLogTests.swift
  • Projects/Core/Network/Tests/Support/TokenStubs.swift
📝 Walkthrough

Summary by CodeRabbit

  • 새 기능

    • API 요청 생성·전송과 JSON 디코딩을 지원하는 네트워크 클라이언트를 추가했습니다.
    • 인증 토큰 조회·갱신 및 401 응답 시 자동 재시도를 지원합니다.
    • HTTP 메서드, 엔드포인트 구성, 네트워크 설정과 표준 오류 처리를 추가했습니다.
    • UTC 날짜·시간 기반 JSON 인코딩 및 디코딩을 지원합니다.
    • 네트워크 요청·응답과 오류를 기록하며 민감한 인증 정보를 보호합니다.
  • 테스트

    • 요청 구성, 오류 매핑, 인증 갱신 및 동시 요청 시나리오를 검증하는 테스트를 추가했습니다.
  • 문서

    • 네트워크 모듈의 로깅 및 아키텍처 규칙을 문서화했습니다.

Walkthrough

CoreNetwork에 네트워크 요청 계약과 DefaultNetworkClient가 추가되었습니다. 클라이언트는 JSON 처리, 오류 매핑, 로깅, Bearer 인증, 401 토큰 갱신 및 재시도를 지원합니다. 관련 테스트와 SharedLogger 설정도 추가되었습니다.

Changes

CoreNetwork 네트워크 기능

Layer / File(s) Summary
네트워크 계약과 데이터 형식
Projects/Core/Network/Sources/Auth/*, Sources/Client/NetworkClient.swift, Sources/Config/*, Sources/Endpoint/*, Sources/Error/*
요청, 인증, 설정, JSON 코딩, HTTP 메서드 및 NetworkError 공개 타입을 추가했습니다.
요청 실행과 인증 갱신
Projects/Core/Network/Sources/Client/DefaultNetworkClient.swift, Sources/Logging/NetworkLog.swift
요청 생성과 전송, 응답 디코딩, 오류 매핑, 로깅, Bearer 인증, 401 갱신 및 단일 재시도를 추가했습니다.
네트워크 동작 검증
Projects/Core/Network/Tests/*
URLProtocol 스텁과 테스트용 엔드포인트·토큰 구현을 추가했습니다. 요청 구성, 응답 처리, 오류 매핑, 인증 갱신 및 동시 single-flight 갱신을 검증합니다.
모듈 의존성과 규칙
Projects/Core/Network/Project.swift, docs/ARCHITECTURE.md, docs/CONVENTIONS.md
SharedLogger 의존성과 테스트 포함 설정을 추가했습니다. CoreNetwork 로깅 규칙을 문서화했습니다.

Estimated code review effort: 4 (Complex) | ~45 minutes

Sequence Diagram(s)

sequenceDiagram
  participant Caller
  participant DefaultNetworkClient
  participant TokenProviding
  participant TokenRefreshing
  participant URLSession
  participant SharedLogger
  Caller->>DefaultNetworkClient: request(endpoint)
  DefaultNetworkClient->>TokenProviding: accessToken()
  DefaultNetworkClient->>URLSession: send URLRequest
  URLSession-->>DefaultNetworkClient: 401 response
  DefaultNetworkClient->>TokenRefreshing: refresh()
  TokenRefreshing-->>DefaultNetworkClient: refreshed token state
  DefaultNetworkClient->>TokenProviding: accessToken()
  DefaultNetworkClient->>URLSession: retry request once
  URLSession-->>DefaultNetworkClient: success response
  DefaultNetworkClient->>SharedLogger: log request and response
  DefaultNetworkClient-->>Caller: decoded result
Loading

Possibly related PRs

Suggested labels: test

🚥 Pre-merge checks | ✅ 4
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed 제목은 CoreNetwork 공통 HTTP 인프라 추가라는 주요 변경을 간결하고 명확하게 설명합니다.
Description check ✅ Passed 변경 요약과 세부 내용은 충분하지만 템플릿의 기타 참고 사항 항목은 작성되지 않았습니다.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 5

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@Projects/Core/Network/Sources/Client/DefaultNetworkClient.swift`:
- Around line 185-200: Update mapStatusCode so unrecognized 4xx status codes are
returned as a client-error NetworkError rather than serverError; keep 5xx and
other statuses mapped to serverError. Add mapping coverage for an unregistered
4xx code such as 405, 422, or 429.
- Around line 22-46: Move the live dependency composition out of
DefaultNetworkClient.plain and DefaultNetworkClient.authed into the App layer.
Keep CoreNetwork focused on the network implementation, with URLSession,
TokenProviding, and TokenRefreshing supplied by App-level composition rather
than selected or assembled by these factories, including the URLSession.shared
default.
- Around line 98-101: Update send and refreshSingleFlight to capture the
access-token generation used by each request and compare it with the current
generation when handling a 401. If the token has already changed, retry the
request without starting another refresh; only refresh when the request used the
current token and allowRefresh is enabled. Add a concurrency test covering
delayed 401 responses arriving after the shared refreshTask has been removed,
asserting that only one refresh occurs.
- Around line 169-173: Update the authenticated request flow in
DefaultNetworkClient around tokenProvider.accessToken() to validate the final
request URL’s scheme before setting the Authorization header; reject any
non-HTTPS URL with NetworkError.invalidURL, while preserving unauthenticated
request behavior. Add coverage for an HTTP baseURL with a token provider and
verify the request is rejected.

In `@Projects/Core/Network/Sources/Logging/NetworkLog.swift`:
- Around line 5-16: NetworkLog의 request, response, error 로깅 경로에서
URL.absoluteString 대신 query와 fragment를 제거한 URL을 사용하도록 공통 정규화 로직을 추가하고 적용하세요.
request 경로의 redact(_:)에만 의존하지 말고 모든 메시지에 동일한 정제된 URL을 반영하며, accessToken=secret
같은 값이 로그에 남지 않는 테스트를 추가하세요.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: 908035e3-8f71-4582-802c-9ccae9042826

📥 Commits

Reviewing files that changed from the base of the PR and between d07ba36 and 67e0ffb.

📒 Files selected for processing (21)
  • Projects/Core/Network/Project.swift
  • Projects/Core/Network/Sources/Auth/TokenProviding.swift
  • Projects/Core/Network/Sources/Auth/TokenRefreshing.swift
  • Projects/Core/Network/Sources/Client/DefaultNetworkClient.swift
  • Projects/Core/Network/Sources/Client/NetworkClient.swift
  • Projects/Core/Network/Sources/Config/NetworkConfiguration.swift
  • Projects/Core/Network/Sources/Config/NetworkJSONCoding.swift
  • Projects/Core/Network/Sources/Endpoint/APIEndpoint.swift
  • Projects/Core/Network/Sources/Endpoint/HTTPMethod.swift
  • Projects/Core/Network/Sources/Error/ErrorMessageDTO.swift
  • Projects/Core/Network/Sources/Error/NetworkError.swift
  • Projects/Core/Network/Sources/Logging/NetworkLog.swift
  • Projects/Core/Network/Sources/Placeholder.swift
  • Projects/Core/Network/Tests/DefaultNetworkClientTests.swift
  • Projects/Core/Network/Tests/NetworkErrorMappingTests.swift
  • Projects/Core/Network/Tests/Support/TestEndpoint.swift
  • Projects/Core/Network/Tests/Support/TokenStubs.swift
  • Projects/Core/Network/Tests/Support/URLProtocolStub.swift
  • Projects/Core/Network/Tests/URLRequestBuildingTests.swift
  • docs/ARCHITECTURE.md
  • docs/CONVENTIONS.md
💤 Files with no reviewable changes (1)
  • Projects/Core/Network/Sources/Placeholder.swift

Comment thread Projects/Core/Network/Sources/Client/DefaultNetworkClient.swift
Comment thread Projects/Core/Network/Sources/Client/DefaultNetworkClient.swift
Comment thread Projects/Core/Network/Sources/Client/DefaultNetworkClient.swift
Comment thread Projects/Core/Network/Sources/Client/DefaultNetworkClient.swift
Comment thread Projects/Core/Network/Sources/Logging/NetworkLog.swift

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (1)
Projects/Core/Network/Tests/Support/TokenStubs.swift (1)

29-33: 🎯 Functional Correctness | 🔵 Trivial | ⚡ Quick win

갱신 후 토큰을 사용하는 재시도를 검증하세요.

refresh()는 refresh 횟수, 지연, 오류만 처리합니다. DefaultNetworkClientTests.swift Line 99-136 및 Line 138-186의 401 응답 핸들러는 요청 헤더를 확인하지 않습니다. 따라서 오래된 Authorization 헤더로 재시도해도 테스트가 통과할 수 있습니다.

StubTokenRefresherStubTokenProvider를 연결하거나, 첫 요청과 재시도 요청의 Authorization 값을 각각 기존 토큰과 갱신 토큰으로 검증하세요. TokenProvidingTokenRefreshing 계약도 함께 확인하세요.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@Projects/Core/Network/Tests/Support/TokenStubs.swift` around lines 29 - 33,
Update StubTokenRefresher and StubTokenProvider usage in
DefaultNetworkClientTests so the 401 retry path verifies Authorization headers:
assert the first request uses the existing token and the retry uses the
refreshed token. Ensure the stubs remain connected through the TokenProviding
and TokenRefreshing contracts while preserving the existing refresh-count,
delay, and error assertions.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@Projects/Core/Network/Tests/Support/TokenStubs.swift`:
- Around line 29-33: Update StubTokenRefresher and StubTokenProvider usage in
DefaultNetworkClientTests so the 401 retry path verifies Authorization headers:
assert the first request uses the existing token and the retry uses the
refreshed token. Ensure the stubs remain connected through the TokenProviding
and TokenRefreshing contracts while preserving the existing refresh-count,
delay, and error assertions.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: cfff210b-0509-4675-b23e-a9c85f24bce7

📥 Commits

Reviewing files that changed from the base of the PR and between 67e0ffb and 34b28b6.

📒 Files selected for processing (4)
  • Projects/Core/Network/Sources/Client/DefaultNetworkClient.swift
  • Projects/Core/Network/Tests/DefaultNetworkClientTests.swift
  • Projects/Core/Network/Tests/Support/TokenStubs.swift
  • Projects/Core/Network/Tests/Support/URLProtocolStub.swift
🚧 Files skipped from review as they are similar to previous changes (3)
  • Projects/Core/Network/Tests/DefaultNetworkClientTests.swift
  • Projects/Core/Network/Tests/Support/URLProtocolStub.swift
  • Projects/Core/Network/Sources/Client/DefaultNetworkClient.swift

@gnoes-ios
gnoes-ios merged commit 654df84 into dev Aug 4, 2026
3 checks passed
@gnoes-ios
gnoes-ios deleted the feat/core-network branch August 4, 2026 07:18
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

feat 새로운 기능

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant