From e8caacb110bc7372743633b752ed4d6232e4675a Mon Sep 17 00:00:00 2001 From: opficdev <162981733+opficdev@users.noreply.github.com> Date: Tue, 25 Aug 2026 10:32:07 +0900 Subject: [PATCH 1/7] =?UTF-8?q?docs:=20API=20client=EC=99=80=20endpoint=20?= =?UTF-8?q?=EC=A3=BC=EC=84=9D=20=EC=9E=AC=EA=B5=AC=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Sources/Public/NXAPIClient.swift | 94 ++++++++++++++++---------------- Sources/Public/NXEndpoint.swift | 22 ++++---- 2 files changed, 58 insertions(+), 58 deletions(-) diff --git a/Sources/Public/NXAPIClient.swift b/Sources/Public/NXAPIClient.swift index 28c5fd3..14f078b 100644 --- a/Sources/Public/NXAPIClient.swift +++ b/Sources/Public/NXAPIClient.swift @@ -7,13 +7,13 @@ import Foundation -/// 단일 클라이언트 설정으로 HTTP 요청을 구성하고 전송하기 위한 공용 진입점입니다. +/// 단일 client 설정 기반 HTTP 요청 구성·전송 공용 진입점 /// /// ## 개요 /// -/// 클라이언트를 한 번 생성한 뒤 상대 경로로 요청을 시작하세요. +/// client 단일 생성 후 상대 경로 기반 요청 시작 /// -/// 캐시를 사용하면 각 `NXAPIClient` 초기화 시 독립적인 인메모리 캐시와 인플라이트 요청 저장소가 생성됩니다. 캐시 응답을 공유하려면 서비스나 의존성 컨테이너에서 하나의 클라이언트를 재사용하세요. 동일 클라이언트 값의 복사본은 같은 저장소를 유지합니다. +/// cache 사용 시 각 `NXAPIClient` 초기화마다 독립 메모리 cache와 진행 중 request store 생성. cache 응답 공유는 서비스 또는 DI 계층에서 client 단일 재사용으로 보장. 동일 client 값 복사본은 동일 store 유지 /// /// ```swift /// import Foundation @@ -35,15 +35,15 @@ import Foundation /// .send(as: User.self) /// ``` /// -/// 모든 직접 요청은 메서드 기반 빌더를 사용하세요. `NXEndpoint`는 소스 호환성을 위해 타입 지정 빌더 구성 계약을 유지합니다. +/// 직접 요청은 method 기반 builder 경로, `NXEndpoint`는 type 지정 builder 구성 contract의 source 호환성 유지 public struct NXAPIClient: Sendable { private let configuration: NXClientConfiguration private let responseCacheStore: NXResponseCacheStore? private let authRefreshCoordinator: NXAuthRefreshCoordinator - /// 모든 요청에 제공된 설정을 사용하는 클라이언트를 생성합니다. + /// 모든 요청 공통 설정 반영 client 생성 /// - /// - Parameter configuration: 기본 URL, 전송 계층, 로거, 인증 공급자 같은 공용 설정입니다. + /// - Parameter configuration: 기본 URL, transport, logger, `NXAuthTokenProvider` 같은 공용 설정 public init(configuration: NXClientConfiguration) { self.init( configuration: configuration, @@ -70,20 +70,20 @@ public struct NXAPIClient: Sendable { } } - /// 지정한 경로에 대한 타입 미지정 `GET` 요청 빌더를 생성합니다. + /// 지정 경로 기준 type 미지정 `GET` request builder 생성 /// - /// - Parameter path: 설정된 기본 URL 기준 상대 경로입니다. - /// - Returns: 전송 전에 추가로 설정할 수 있는 요청 빌더입니다. + /// - Parameter path: 설정된 기본 URL 기준 상대 경로 + /// - Returns: 전송 전 추가 설정 가능한 request builder public func get(_ path: String = "") -> NXRequestBuilder { request(method: .get, path: path) } - /// 지정한 경로에 대한 타입 지정 `GET` 요청 빌더를 생성합니다. + /// 지정 경로 기준 type 지정 `GET` request builder 생성 /// /// - Parameters: - /// - path: 설정된 기본 URL 기준 상대 경로입니다. - /// - type: 요청이 성공했을 때 디코딩할 응답 타입입니다. - /// - Returns: `Response`로 디코딩하는 타입 지정 요청 빌더입니다. + /// - path: 설정된 기본 URL 기준 상대 경로 + /// - type: 성공 응답 decoding 대상 type + /// - Returns: `Response` decoding type 지정 request builder @available(*, deprecated, message: "Use get(_:) followed by send(as:).") public func get( _ path: String = "", @@ -92,94 +92,94 @@ public struct NXAPIClient: Sendable { typedRequest(method: .get, path: path) } - /// 지정한 경로에 대한 타입 미지정 `POST` 요청 빌더를 생성합니다. + /// 지정 경로 기준 type 미지정 `POST` request builder 생성 /// - /// - Parameter path: 설정된 기본 URL 기준 상대 경로입니다. - /// - Returns: 전송 전에 추가로 설정할 수 있는 요청 빌더입니다. + /// - Parameter path: 설정된 기본 URL 기준 상대 경로 + /// - Returns: 전송 전 추가 설정 가능한 request builder public func post(_ path: String) -> NXRequestBuilder { request(method: .post, path: path) } - /// 지정한 경로에 대한 타입 지정 `POST` 요청 빌더를 생성합니다. + /// 지정 경로 기준 type 지정 `POST` request builder 생성 /// /// - Parameters: - /// - path: 설정된 기본 URL 기준 상대 경로입니다. - /// - type: 요청이 성공했을 때 디코딩할 응답 타입입니다. - /// - Returns: `Response`로 디코딩하는 타입 지정 요청 빌더입니다. + /// - path: 설정된 기본 URL 기준 상대 경로 + /// - type: 성공 응답 decoding 대상 type + /// - Returns: `Response` decoding type 지정 request builder @available(*, deprecated, message: "Use post(_:) followed by send(as:).") public func post(_ path: String, as type: Response.Type) -> NXTypedRequestBuilder { typedRequest(method: .post, path: path) } - /// 지정한 경로에 대한 타입 미지정 `PUT` 요청 빌더를 생성합니다. + /// 지정 경로 기준 type 미지정 `PUT` request builder 생성 /// - /// - Parameter path: 설정된 기본 URL 기준 상대 경로입니다. - /// - Returns: 전송 전에 추가로 설정할 수 있는 요청 빌더입니다. + /// - Parameter path: 설정된 기본 URL 기준 상대 경로 + /// - Returns: 전송 전 추가 설정 가능한 request builder public func put(_ path: String) -> NXRequestBuilder { request(method: .put, path: path) } - /// 지정한 경로에 대한 타입 지정 `PUT` 요청 빌더를 생성합니다. + /// 지정 경로 기준 type 지정 `PUT` request builder 생성 /// /// - Parameters: - /// - path: 설정된 기본 URL 기준 상대 경로입니다. - /// - type: 요청이 성공했을 때 디코딩할 응답 타입입니다. - /// - Returns: `Response`로 디코딩하는 타입 지정 요청 빌더입니다. + /// - path: 설정된 기본 URL 기준 상대 경로 + /// - type: 성공 응답 decoding 대상 type + /// - Returns: `Response` decoding type 지정 request builder @available(*, deprecated, message: "Use put(_:) followed by send(as:).") public func put(_ path: String, as type: Response.Type) -> NXTypedRequestBuilder { typedRequest(method: .put, path: path) } - /// 지정한 경로에 대한 타입 미지정 `PATCH` 요청 빌더를 생성합니다. + /// 지정 경로 기준 type 미지정 `PATCH` request builder 생성 /// - /// - Parameter path: 설정된 기본 URL 기준 상대 경로입니다. - /// - Returns: 전송 전에 추가로 설정할 수 있는 요청 빌더입니다. + /// - Parameter path: 설정된 기본 URL 기준 상대 경로 + /// - Returns: 전송 전 추가 설정 가능한 request builder public func patch(_ path: String) -> NXRequestBuilder { request(method: .patch, path: path) } - /// 지정한 경로에 대한 타입 지정 `PATCH` 요청 빌더를 생성합니다. + /// 지정 경로 기준 type 지정 `PATCH` request builder 생성 /// /// - Parameters: - /// - path: 설정된 기본 URL 기준 상대 경로입니다. - /// - type: 요청이 성공했을 때 디코딩할 응답 타입입니다. - /// - Returns: `Response`로 디코딩하는 타입 지정 요청 빌더입니다. + /// - path: 설정된 기본 URL 기준 상대 경로 + /// - type: 성공 응답 decoding 대상 type + /// - Returns: `Response` decoding type 지정 request builder @available(*, deprecated, message: "Use patch(_:) followed by send(as:).") public func patch(_ path: String, as type: Response.Type) -> NXTypedRequestBuilder { typedRequest(method: .patch, path: path) } - /// 지정한 경로에 대한 타입 미지정 `DELETE` 요청 빌더를 생성합니다. + /// 지정 경로 기준 type 미지정 `DELETE` request builder 생성 /// - /// - Parameter path: 설정된 기본 URL 기준 상대 경로입니다. - /// - Returns: 전송 전에 추가로 설정할 수 있는 요청 빌더입니다. + /// - Parameter path: 설정된 기본 URL 기준 상대 경로 + /// - Returns: 전송 전 추가 설정 가능한 request builder public func delete(_ path: String) -> NXRequestBuilder { request(method: .delete, path: path) } - /// 지정한 경로에 대한 타입 지정 `DELETE` 요청 빌더를 생성합니다. + /// 지정 경로 기준 type 지정 `DELETE` request builder 생성 /// /// - Parameters: - /// - path: 설정된 기본 URL 기준 상대 경로입니다. - /// - type: 요청이 성공했을 때 디코딩할 응답 타입입니다. - /// - Returns: `Response`로 디코딩하는 타입 지정 요청 빌더입니다. + /// - path: 설정된 기본 URL 기준 상대 경로 + /// - type: 성공 응답 decoding 대상 type + /// - Returns: `Response` decoding type 지정 request builder @available(*, deprecated, message: "Use delete(_:) followed by send(as:).") public func delete(_ path: String, as type: Response.Type) -> NXTypedRequestBuilder { typedRequest(method: .delete, path: path) } - /// 엔드포인트 값에서 타입 지정 요청을 구성합니다. + /// endpoint에서 type 지정 요청 구성 /// - /// - Parameter endpoint: HTTP 메서드, 경로, 선택적 요청 커스터마이즈를 정의하는 엔드포인트입니다. - /// - Returns: 엔드포인트 기반으로 설정된 타입 지정 요청 빌더입니다. + /// - Parameter endpoint: HTTP method, 경로, 선택적 요청 customization 정의 endpoint + /// - Returns: endpoint 기반 type 지정 request builder public func request(_ endpoint: E) -> NXTypedRequestBuilder { endpoint.configure(typedRequest(method: endpoint.method, path: endpoint.path)) } - /// 엔드포인트 요청을 전송하고 응답을 디코딩합니다. + /// endpoint 요청 전송 및 응답 decoding /// - /// - Parameter endpoint: 요청 동작을 정의한 엔드포인트입니다. - /// - Returns: 엔드포인트에 대한 디코딩된 응답 값입니다. + /// - Parameter endpoint: 요청 동작 정의 endpoint + /// - Returns: endpoint 응답 decoding 결과 public func send(_ endpoint: E) async throws -> E.Response { try await request(endpoint).requestBuilder.send(as: E.Response.self) } diff --git a/Sources/Public/NXEndpoint.swift b/Sources/Public/NXEndpoint.swift index fe5be11..c2d1527 100644 --- a/Sources/Public/NXEndpoint.swift +++ b/Sources/Public/NXEndpoint.swift @@ -7,11 +7,11 @@ import Foundation -/// 고정 응답 타입을 갖는 재사용 가능한 API 엔드포인트를 설명합니다. +/// 고정 응답 type을 갖는 재사용 가능한 API endpoint 설명 /// /// ## 개요 /// -/// 동일한 요청 구조를 반복 사용하면서 응답 타입을 함께 유지해야 할 때 엔드포인트를 사용합니다. +/// 동일 요청 구조 반복 사용 및 응답 type 보존이 필요한 재사용 가능한 endpoint 정의 /// /// ```swift /// import Foundation @@ -36,24 +36,24 @@ import Foundation /// let user = try await client.send(UserEndpoint(identifier: 42)) /// ``` public protocol NXEndpoint { - /// 엔드포인트 요청이 성공했을 때 생성되는 응답 타입입니다. + /// endpoint 요청 성공 시 decoding 대상 응답 type associatedtype Response: Decodable - /// 요청에 사용되는 HTTP 메서드입니다. + /// 요청에 사용되는 HTTP 메서드 var method: NXHTTPMethod { get } - /// 클라이언트 기본 URL 기준 상대 경로입니다. + /// client 기본 URL 기준 상대 경로 var path: String { get } - /// 전송 전에 엔드포인트별 커스터마이즈를 빌더에 적용합니다. + /// 전송 전 endpoint별 customization을 builder에 적용 /// - /// - Parameter builder: `method`와 `path`로 생성한 기본 타입 지정 요청 빌더입니다. - /// - Returns: 커스터마이즈된 타입 지정 요청 빌더입니다. + /// - Parameter builder: `method`와 `path` 기반 기본 type 지정 request builder + /// - Returns: customization 적용 type 지정 request builder func configure(_ builder: NXTypedRequestBuilder) -> NXTypedRequestBuilder } public extension NXEndpoint { - /// 엔드포인트에 추가 커스터마이즈가 필요하지 않으면 빌더를 그대로 반환합니다. + /// endpoint 추가 customization 미필요 시 builder 원본 반환 /// - /// - Parameter builder: `method`와 `path`로 생성한 기본 타입 지정 요청 빌더입니다. - /// - Returns: 동일한 빌더 인스턴스입니다. + /// - Parameter builder: `method`와 `path` 기반 기본 type 지정 request builder + /// - Returns: 동일 builder instance func configure(_ builder: NXTypedRequestBuilder) -> NXTypedRequestBuilder { builder } From ef5b610154e6d3e7830fb18673697853feee4702 Mon Sep 17 00:00:00 2001 From: opficdev <162981733+opficdev@users.noreply.github.com> Date: Tue, 25 Aug 2026 10:32:14 +0900 Subject: [PATCH 2/7] =?UTF-8?q?docs:=20=EC=9A=94=EC=B2=AD=20builder=20?= =?UTF-8?q?=EC=A3=BC=EC=84=9D=20=EC=9E=AC=EA=B5=AC=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Sources/Public/NXRequestBuilder.swift | 114 ++++++++++----------- Sources/Public/NXTypedRequestBuilder.swift | 100 +++++++++--------- 2 files changed, 107 insertions(+), 107 deletions(-) diff --git a/Sources/Public/NXRequestBuilder.swift b/Sources/Public/NXRequestBuilder.swift index ff310c0..feb8502 100644 --- a/Sources/Public/NXRequestBuilder.swift +++ b/Sources/Public/NXRequestBuilder.swift @@ -7,11 +7,11 @@ import Foundation -/// HTTP 요청 구성과 전송을 값 의미론으로 다루는 빌더입니다. +/// HTTP 요청 구성·전송의 값 의미론 builder /// /// ## 개요 /// -/// `NXRequestBuilder`를 사용해 준비된 요청을 확인하고 `send()`로 `NXRawResponse`를 받거나 `send(as:)`로 응답을 디코딩할 수 있습니다. 원시 응답 실행 API는 `send()`뿐입니다. +/// `NXRequestBuilder` 준비 요청 확인, `send()`로 `NXRawResponse` 획득, `send(as:)`로 응답 decoding 지원. `NXRawResponse` 실행 API는 `send()` 단일 노출 /// /// ```swift /// import Foundation @@ -50,73 +50,73 @@ public struct NXRequestBuilder: Sendable { self.requestSpec = requestSpec } - /// 요청 URL에 쿼리 항목을 추가합니다. + /// 요청 URL 쿼리 항목 추가 /// /// - Parameters: - /// - key: 쿼리 항목 이름입니다. - /// - value: `String(describing:)`로 변환한 쿼리 항목 값입니다. - /// - Returns: 업데이트된 요청 빌더입니다. + /// - key: 쿼리 항목 이름 + /// - value: `String(describing:)`로 변환한 쿼리 항목 값 + /// - Returns: 갱신된 request builder public func query(_ key: String, _ value: some CustomStringConvertible) -> Self { modifying { requestSpec in requestSpec.queryItems.append(URLQueryItem(name: key, value: String(describing: value))) } } - /// 단일 HTTP 헤더를 설정하거나 교체합니다. + /// 단일 HTTP header 설정/교체 /// /// - Parameters: - /// - key: 헤더 필드 이름입니다. - /// - value: 헤더 필드 값입니다. - /// - Returns: 업데이트된 요청 빌더입니다. + /// - key: header field 이름 + /// - value: header field 값 + /// - Returns: 갱신된 request builder public func header(_ key: String, _ value: String) -> Self { modifying { requestSpec in requestSpec.headers[key] = value } } - /// 요청에 여러 HTTP 헤더를 병합합니다. + /// 다수 HTTP header 병합 /// - /// - Parameter values: 추가할 헤더 필드 이름/값입니다. 기존 키는 새 값으로 덮어씁니다. - /// - Returns: 업데이트된 요청 빌더입니다. + /// - Parameter values: 추가 header field 이름/값. 키 충돌 시 새 값 우선 + /// - Returns: 갱신된 request builder public func headers(_ values: [String: String]) -> Self { modifying { requestSpec in requestSpec.headers.merge(values) { _, newValue in newValue } } } - /// `Accept` 헤더를 설정합니다. + /// `Accept` header 설정 /// - /// - Parameter value: `Accept` 헤더의 미디어 타입 값입니다. - /// - Returns: 업데이트된 요청 빌더입니다. + /// - Parameter value: `Accept` header media type 값 + /// - Returns: 갱신된 request builder public func accept(_ value: String) -> Self { header("Accept", value) } - /// 설정된 인증 토큰 공급자를 통해 인증이 필요함을 표시합니다. + /// 설정된 `NXAuthTokenProvider`를 통한 인증 필요 표시 /// - /// - Returns: 업데이트된 요청 빌더입니다. + /// - Returns: 갱신된 request builder public func authorized() -> Self { modifying { requestSpec in requestSpec.authRequirement = .required } } - /// 요청별 타임아웃 간격을 설정합니다. + /// 요청별 타임아웃 간격 설정 /// - /// - Parameter seconds: 타임아웃 간격(초). 음수 값은 `0`으로 보정됩니다. - /// - Returns: 업데이트된 요청 빌더입니다. + /// - Parameter seconds: 타임아웃 간격(초). 음수 값은 `0` 보정 + /// - Returns: 갱신된 request builder public func timeout(_ seconds: TimeInterval) -> Self { modifying { requestSpec in requestSpec.timeout = max(0, seconds) } } - /// `Encodable` 값을 JSON으로 인코딩하고 `Content-Type` 헤더를 설정합니다. + /// `Encodable` 값 JSON encoding 및 `Content-Type` header 설정 /// /// - Parameters: - /// - value: 요청 본문에 인코딩할 값입니다. - /// - encoder: 사용할 인코더입니다. 생략하면 클라이언트 설정의 인코더를 사용합니다. - /// - Returns: 업데이트된 요청 빌더입니다. + /// - value: 요청 body encoding 대상 값 + /// - encoder: 사용 encoder. 미지정 시 client 설정 encoder 사용 + /// - Returns: 갱신된 request builder public func json(_ value: T, encoder: JSONEncoder? = nil) throws -> Self { let selectedEncoder = encoder ?? clientConfiguration.encoder let encodedValue = try selectedEncoder.encode(value) @@ -127,36 +127,36 @@ public struct NXRequestBuilder: Sendable { } } - /// 원시 요청 본문 데이터를 설정합니다. + /// 원시 요청 body data 설정 /// - /// - Parameter data: HTTP 본문에 넣을 데이터입니다. - /// - Returns: 업데이트된 요청 빌더입니다. + /// - Parameter data: HTTP body 입력 data + /// - Returns: 갱신된 request builder public func body(_ data: Data) -> Self { modifying { requestSpec in requestSpec.body = .data(data) } } - /// `Content-Type` 헤더를 설정하거나 교체합니다. + /// `Content-Type` header 설정/교체 /// - /// - Parameter value: `Content-Type` 헤더의 미디어 타입 값입니다. - /// - Returns: 업데이트된 요청 빌더입니다. + /// - Parameter value: `Content-Type` header media type 값 + /// - Returns: 갱신된 request builder public func contentType(_ value: String) -> Self { modifying { requestSpec in requestSpec.headers["Content-Type"] = value } } - /// 요청에 재시도 정책을 적용합니다. + /// 요청 retry policy 적용 /// /// - Parameters: - /// - maxAttempts: 초기 요청을 포함한 최대 시도 횟수입니다. 기본값은 `3`입니다. - /// - backoff: 재시도 간 사용되는 지연 전략입니다. - /// - retryableStatusCodes: 재시도를 유발할 상태 코드입니다. - /// - allowing: 기본 멱등 메서드와 함께 재시도를 허용할 추가 HTTP 메서드입니다. - /// - maximumServerDelay: 서버 제공 재시도 지연에 적용되는 상한값입니다. - /// - jitter: 로컬 백오프 지연에 적용되는 무작위화입니다. - /// - Returns: 업데이트된 요청 빌더입니다. + /// - maxAttempts: 초기 요청 포함 최대 시도 횟수(기본 `3`) + /// - backoff: retry 간 지연 전략 + /// - retryableStatusCodes: retry 유발 상태 코드 집합 + /// - allowing: 기본 멱등 메서드와 함께 허용할 추가 HTTP 메서드 + /// - maximumServerDelay: 서버 retry 지연 상한 + /// - jitter: 로컬 backoff 지연 무작위화 설정 + /// - Returns: 갱신된 request builder public func retry( maxAttempts: Int = 3, backoff: NXRetryBackoff = .fixed(0), @@ -177,36 +177,36 @@ public struct NXRequestBuilder: Sendable { } } - /// 요청에 응답 유효성 정책을 적용합니다. + /// 요청 응답 validation policy 적용 /// - /// - Parameter policy: 전송 계층이 응답을 반환한 뒤 적용할 유효성 검사 규칙입니다. - /// - Returns: 업데이트된 요청 빌더입니다. + /// - Parameter policy: transport 응답 반환 후 적용 validation 규칙 + /// - Returns: 갱신된 request builder public func validate(_ policy: NXValidationPolicy) -> Self { modifying { requestSpec in requestSpec.validationPolicy = policy } } - /// 요청 단위 인터셉터를 추가합니다. + /// 요청 단위 interceptor 추가 /// - /// - Parameter interceptor: 전역 인터셉터 뒤에 추가할 인터셉터입니다. - /// - Returns: 업데이트된 요청 빌더입니다. + /// - Parameter interceptor: 전역 interceptor 뒤에 추가할 interceptor + /// - Returns: 갱신된 request builder public func intercept(_ interceptor: any NXHTTPInterceptor) -> Self { modifying { requestSpec in requestSpec.requestInterceptors.append(interceptor) } } - /// 최종 `URLRequest`를 전송하지 않고 조립합니다. + /// 최종 `URLRequest` 조립(전송 제외) /// - /// - Returns: 완전히 준비된 URLRequest입니다. + /// - Returns: 완전 준비된 URLRequest public func preparedURLRequest() async throws -> URLRequest { try NXRequestAssembler.assemble(clientConfiguration: clientConfiguration, requestSpec: requestSpec) } - /// 요청을 전송하고 원시 HTTP 응답을 반환합니다. + /// 요청 전송 및 `NXRawResponse` 반환 /// - /// - Returns: 원시 응답 데이터와 HTTP 메타데이터입니다. + /// - Returns: `NXRawResponse`의 응답 data와 HTTP metadata public func send() async throws -> NXRawResponse { try await NXRequestExecutor.executeRaw( clientConfiguration: clientConfiguration, @@ -216,25 +216,25 @@ public struct NXRequestBuilder: Sendable { ) } - /// 요청을 전송하고 호출 문맥에서 결정된 응답 타입으로 응답을 디코딩합니다. + /// 요청 전송 및 호출 context 결정 응답 type decoding /// - /// - Returns: `Response`에 대한 디코딩된 응답 값입니다. + /// - Returns: `Response` decoding 응답 값 public func send() async throws -> Response { try await send(as: Response.self) } - /// 요청을 전송하고 지정한 응답 타입으로 디코딩합니다. + /// 요청 전송 및 지정 응답 type decoding /// - /// - Parameter type: 요청이 성공했을 때 디코딩할 응답 타입입니다. - /// - Returns: `Response`에 대한 디코딩된 응답 값입니다. + /// - Parameter type: 성공 응답 decoding 대상 type + /// - Returns: `Response` decoding 응답 값 public func send(as type: Response.Type) async throws -> Response { try await decoded(type) } - /// 응답을 디코딩할 타입 지정 빌더로 변환합니다. + /// 응답 decoding용 type 지정 builder 변환 /// - /// - Parameter type: 요청이 성공했을 때 디코딩할 응답 타입입니다. - /// - Returns: `Response`용 타입 지정 요청 빌더입니다. + /// - Parameter type: 성공 응답 decoding 대상 type + /// - Returns: `Response` type 지정 request builder @available(*, deprecated, message: "Use send(as:) or a contextual send().") public func `as`(_ type: Response.Type) -> NXTypedRequestBuilder { NXTypedRequestBuilder(requestBuilder: self) diff --git a/Sources/Public/NXTypedRequestBuilder.swift b/Sources/Public/NXTypedRequestBuilder.swift index b9b69da..e46f461 100644 --- a/Sources/Public/NXTypedRequestBuilder.swift +++ b/Sources/Public/NXTypedRequestBuilder.swift @@ -7,11 +7,11 @@ import Foundation -/// 특정 응답 타입으로 디코딩하는 요청을 구성하는 값 의미론 빌더입니다. +/// 특정 응답 type decoding 요청의 값 의미론 builder /// /// ## 개요 /// -/// `NXTypedRequestBuilder`는 `NXEndpoint` 구성 호환성을 위해 유지됩니다. 원시 응답 실행 API는 제공하지 않습니다. 메서드 기반 요청은 `NXRequestBuilder.send(as:)`를 사용하세요. +/// `NXTypedRequestBuilder`는 `NXEndpoint` 구성 compatibility 목적 유지. `NXRawResponse` 실행 API 미노출. method 기반 요청은 `NXRequestBuilder.send(as:)` 사용 /// /// ```swift /// import Foundation @@ -31,93 +31,93 @@ import Foundation public struct NXTypedRequestBuilder: Sendable where Response: Decodable { let requestBuilder: NXRequestBuilder - /// 요청 URL에 쿼리 항목을 추가합니다. + /// 요청 URL 쿼리 항목 추가 /// /// - Parameters: - /// - key: 쿼리 항목 이름입니다. - /// - value: `String(describing:)`로 변환한 쿼리 항목 값입니다. - /// - Returns: 업데이트된 타입 지정 요청 빌더입니다. + /// - key: 쿼리 항목 이름 + /// - value: `String(describing:)`로 변환한 쿼리 항목 값 + /// - Returns: 갱신된 type 지정 request builder public func query(_ key: String, _ value: some CustomStringConvertible) -> Self { Self(requestBuilder: requestBuilder.query(key, value)) } - /// 단일 HTTP 헤더를 설정하거나 교체합니다. + /// 단일 HTTP header 설정/교체 /// /// - Parameters: - /// - key: 헤더 필드 이름입니다. - /// - value: 헤더 필드 값입니다. - /// - Returns: 업데이트된 타입 지정 요청 빌더입니다. + /// - key: header field 이름 + /// - value: header field 값 + /// - Returns: 갱신된 type 지정 request builder public func header(_ key: String, _ value: String) -> Self { Self(requestBuilder: requestBuilder.header(key, value)) } - /// 요청에 여러 HTTP 헤더를 병합합니다. + /// 다수 HTTP header 병합 /// - /// - Parameter values: 추가할 헤더 필드 이름/값입니다. 기존 키는 새 값으로 덮어씁니다. - /// - Returns: 업데이트된 타입 지정 요청 빌더입니다. + /// - Parameter values: 추가 header field 이름/값. 키 충돌 시 새 값 우선 + /// - Returns: 갱신된 type 지정 request builder public func headers(_ values: [String: String]) -> Self { Self(requestBuilder: requestBuilder.headers(values)) } - /// `Accept` 헤더를 설정합니다. + /// `Accept` header 설정 /// - /// - Parameter value: `Accept` 헤더의 미디어 타입 값입니다. - /// - Returns: 업데이트된 타입 지정 요청 빌더입니다. + /// - Parameter value: `Accept` header media type 값 + /// - Returns: 갱신된 type 지정 request builder public func accept(_ value: String) -> Self { Self(requestBuilder: requestBuilder.accept(value)) } - /// 설정된 인증 토큰 공급자를 통해 인증이 필요함을 표시합니다. + /// 설정된 `NXAuthTokenProvider`를 통한 인증 필요 표시 /// - /// - Returns: 업데이트된 타입 지정 요청 빌더입니다. + /// - Returns: 갱신된 type 지정 request builder public func authorized() -> Self { Self(requestBuilder: requestBuilder.authorized()) } - /// 요청별 타임아웃 간격을 설정합니다. + /// 요청별 타임아웃 간격 설정 /// - /// - Parameter seconds: 타임아웃 간격(초). 음수 값은 `0`으로 보정됩니다. - /// - Returns: 업데이트된 타입 지정 요청 빌더입니다. + /// - Parameter seconds: 타임아웃 간격(초). 음수 값은 `0` 보정 + /// - Returns: 갱신된 type 지정 request builder public func timeout(_ seconds: TimeInterval) -> Self { Self(requestBuilder: requestBuilder.timeout(seconds)) } - /// `Encodable` 값을 JSON으로 인코딩하고 `Content-Type` 헤더를 설정합니다. + /// `Encodable` 값 JSON encoding 및 `Content-Type` header 설정 /// /// - Parameters: - /// - value: 요청 본문에 인코딩할 값입니다. - /// - encoder: 사용할 인코더입니다. 생략하면 클라이언트 설정의 인코더를 사용합니다. - /// - Returns: 업데이트된 타입 지정 요청 빌더입니다. + /// - value: 요청 body encoding 대상 값 + /// - encoder: 사용 encoder. 미지정 시 client 설정 encoder 사용 + /// - Returns: 갱신된 type 지정 request builder public func json(_ value: T, encoder: JSONEncoder? = nil) throws -> Self { try Self(requestBuilder: requestBuilder.json(value, encoder: encoder)) } - /// 원시 요청 본문 데이터를 설정합니다. + /// 원시 요청 body data 설정 /// - /// - Parameter data: HTTP 본문에 넣을 데이터입니다. - /// - Returns: 업데이트된 타입 지정 요청 빌더입니다. + /// - Parameter data: HTTP body 입력 data + /// - Returns: 갱신된 type 지정 request builder public func body(_ data: Data) -> Self { Self(requestBuilder: requestBuilder.body(data)) } - /// `Content-Type` 헤더를 설정하거나 교체합니다. + /// `Content-Type` header 설정/교체 /// - /// - Parameter value: `Content-Type` 헤더의 미디어 타입 값입니다. - /// - Returns: 업데이트된 타입 지정 요청 빌더입니다. + /// - Parameter value: `Content-Type` header media type 값 + /// - Returns: 갱신된 type 지정 request builder public func contentType(_ value: String) -> Self { Self(requestBuilder: requestBuilder.contentType(value)) } - /// 요청에 재시도 정책을 적용합니다. + /// 요청 retry policy 적용 /// /// - Parameters: - /// - maxAttempts: 초기 요청을 포함한 최대 시도 횟수입니다. 기본값은 `3`입니다. - /// - backoff: 재시도 간 사용되는 지연 전략입니다. - /// - retryableStatusCodes: 재시도를 유발할 상태 코드입니다. - /// - allowing: 기본 멱등 메서드와 함께 재시도를 허용할 추가 HTTP 메서드입니다. - /// - maximumServerDelay: 서버 제공 재시도 지연에 적용되는 상한값입니다. - /// - jitter: 로컬 백오프 지연에 적용되는 무작위화입니다. - /// - Returns: 업데이트된 타입 지정 요청 빌더입니다. + /// - maxAttempts: 초기 요청 포함 최대 시도 횟수(기본 `3`) + /// - backoff: retry 간 지연 전략 + /// - retryableStatusCodes: retry 유발 상태 코드 집합 + /// - allowing: 기본 멱등 메서드와 함께 허용할 추가 HTTP 메서드 + /// - maximumServerDelay: 서버 retry 지연 상한 + /// - jitter: 로컬 backoff 지연 무작위화 설정 + /// - Returns: 갱신된 type 지정 request builder public func retry( maxAttempts: Int = 3, backoff: NXRetryBackoff = .fixed(0), @@ -136,33 +136,33 @@ public struct NXTypedRequestBuilder: Sendable where Response: Decodabl )) } - /// 요청에 응답 유효성 정책을 적용합니다. + /// 요청 응답 validation policy 적용 /// - /// - Parameter policy: 전송 계층이 응답을 반환한 뒤 적용할 유효성 검사 규칙입니다. - /// - Returns: 업데이트된 타입 지정 요청 빌더입니다. + /// - Parameter policy: transport 응답 반환 후 적용 validation 규칙 + /// - Returns: 갱신된 type 지정 request builder public func validate(_ policy: NXValidationPolicy) -> Self { Self(requestBuilder: requestBuilder.validate(policy)) } - /// 요청 단위 인터셉터를 추가합니다. + /// 요청 단위 interceptor 추가 /// - /// - Parameter interceptor: 전역 인터셉터 뒤에 추가할 인터셉터입니다. - /// - Returns: 업데이트된 타입 지정 요청 빌더입니다. + /// - Parameter interceptor: 전역 interceptor 뒤에 추가할 interceptor + /// - Returns: 갱신된 type 지정 request builder public func intercept(_ interceptor: any NXHTTPInterceptor) -> Self { Self(requestBuilder: requestBuilder.intercept(interceptor)) } - /// 최종 `URLRequest`를 전송하지 않고 조립합니다. + /// 최종 `URLRequest` 조립(전송 제외) /// - /// - Returns: 완전히 준비된 URLRequest입니다. + /// - Returns: 완전 준비된 URLRequest public func preparedURLRequest() async throws -> URLRequest { try await requestBuilder.preparedURLRequest() } - /// 요청을 전송하고 `Response`로 응답을 디코딩합니다. + /// 요청 전송 및 `Response` 응답 decoding /// - /// - Returns: 디코딩된 응답 값입니다. - /// - Throws: 요청 실패 또는 디코딩 실패 시 `NXError`가 발생합니다. + /// - Returns: 응답 decoding 결과 + /// - Throws: 요청 실패/decoding 실패 시 `NXError` 발생 public func send() async throws -> Response { try await requestBuilder.send(as: Response.self) } From 77f759587121a3d04e834d332dbc5d33124b2644 Mon Sep 17 00:00:00 2001 From: opficdev <162981733+opficdev@users.noreply.github.com> Date: Tue, 25 Aug 2026 10:32:19 +0900 Subject: [PATCH 3/7] =?UTF-8?q?docs:=20interceptor=EC=99=80=20transport=20?= =?UTF-8?q?=EC=A3=BC=EC=84=9D=20=EC=9E=AC=EA=B5=AC=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Sources/Core/NXProtocols.swift | 24 ++++++++-------- Sources/Public/NXHTTPInterceptor.swift | 32 ++++++++++----------- Sources/Runtime/NXURLSessionTransport.swift | 18 ++++++------ 3 files changed, 37 insertions(+), 37 deletions(-) diff --git a/Sources/Core/NXProtocols.swift b/Sources/Core/NXProtocols.swift index 1f0a223..915c2d4 100644 --- a/Sources/Core/NXProtocols.swift +++ b/Sources/Core/NXProtocols.swift @@ -7,38 +7,38 @@ import Foundation -/// `URLRequest` 값을 실행하는 네트워크 전송 계층의 추상화입니다. +/// `URLRequest` 실행 네트워크 transport 추상화 /// /// ## 개요 /// -/// 테스트에서 네트워크 응답을 스텁 처리하거나 기본 `URLSession` 전송 계층을 교체하려면 `NXHTTPTransport`를 채택하세요. +/// 테스트에서 네트워크 응답 stub 처리 또는 기본 `URLSession` transport 교체 시 `NXHTTPTransport` 채택 public protocol NXHTTPTransport: Sendable { - /// 준비된 요청을 전송하고 원시 HTTP 응답을 반환합니다. + /// 준비된 요청 transport 및 `NXRawResponse` 반환 func send(_ request: URLRequest) async throws -> NXRawResponse } -/// 실패한 서버 응답을 도메인별 오류로 디코딩합니다. +/// 실패한 서버 응답의 도메인별 오류 decoding public protocol NXServerErrorDecoder: Sendable { - /// 실패한 HTTP 응답에서 커스텀 오류를 디코딩하려고 시도합니다. + /// 실패한 HTTP 응답 기반 사용자 정의 오류 decoding 시도 func decodeServerError(data: Data, response: HTTPURLResponse, decoder: JSONDecoder) -> (any Error)? } -/// 커스텀 오류를 생성하지 않는 기본 서버 오류 디코더입니다. +/// 사용자 정의 오류 미생성 기본 서버 오류 decoder public struct NXDefaultServerErrorDecoder: NXServerErrorDecoder { - /// 기본 서버 오류 디코더를 생성합니다. + /// 기본 서버 오류 decoder initialization public init() {} - /// 항상 `nil`을 반환합니다. + /// 항상 `nil` 반환 public func decodeServerError(data: Data, response: HTTPURLResponse, decoder: JSONDecoder) -> (any Error)? { nil } } -/// 인증 요청과 토큰 갱신을 위한 베어러 토큰을 제공합니다. +/// 인증 요청·토큰 갱신용 베어러 token provider /// /// ## 개요 /// -/// 요청이 `.authorized()`를 사용할 때는 인증 토큰 공급자를 구성하세요. +/// `.authorized()` 사용 시 `NXAuthTokenProvider` 구성 point /// /// ```swift /// import Nexa @@ -54,8 +54,8 @@ public struct NXDefaultServerErrorDecoder: NXServerErrorDecoder { /// } /// ``` public protocol NXAuthTokenProvider: Sendable { - /// 사용 가능한 현재 액세스 토큰을 반환합니다. + /// 사용 가능한 현재 액세스 토큰 반환 func currentAccessToken() async throws -> String? - /// 액세스 토큰을 갱신하고 갱신에 성공하면 새 값을 반환합니다. + /// 액세스 토큰 갱신 및 갱신 성공 시 새 값 반환 func refreshAccessToken() async throws -> String? } diff --git a/Sources/Public/NXHTTPInterceptor.swift b/Sources/Public/NXHTTPInterceptor.swift index 1d07e7c..1852c7a 100644 --- a/Sources/Public/NXHTTPInterceptor.swift +++ b/Sources/Public/NXHTTPInterceptor.swift @@ -7,11 +7,11 @@ import Foundation -/// 요청 실행 단계 하나를 가로채 체인의 진행 방식을 결정합니다. +/// 요청 실행 단계 가로채기와 체인 진행 방식 결정 /// /// ## 개요 /// -/// 추적, 커스텀 헤더, 응답 관찰 같은 횡단 관심사가 필요할 때 인터셉터를 구현하세요. 인터셉터는 요청 URL, 헤더, 바디를 바꿀 수 있으나 설정된 HTTP 메서드는 유지해야 합니다. +/// 추적, 사용자 정의 header, 응답 관찰 같은 횡단 관심사 처리용 interceptor 구현. 요청 URL/header/body 변경 허용, 설정된 HTTP method 보존 /// /// ```swift /// import Foundation @@ -29,41 +29,41 @@ import Foundation /// } /// ``` public protocol NXHTTPInterceptor: Sendable { - /// 요청 실행 단계 하나를 처리합니다. + /// 요청 실행 단계 단위 처리 /// /// - Parameters: - /// - context: 현재 요청 실행 상태입니다. - /// - next: 인터셉터 체인을 이어주는 클로저입니다. - /// - Returns: 현재 인터셉터 또는 이후 단계에서 생성된 원시 HTTP 응답입니다. + /// - context: 현재 요청 실행 상태 + /// - next: interceptor chain 연결 closure + /// - Returns: 현재 interceptor 또는 이후 단계 생성 `NXRawResponse` func intercept( context: NXRequestExecutionContext, next: @escaping @Sendable (NXRequestExecutionContext) async throws -> NXRawResponse ) async throws -> NXRawResponse } -/// 인터셉터에게 노출되는 현재 요청 실행 상태의 스냅샷입니다. +/// interceptor 노출용 현재 요청 실행 상태 snapshot /// -/// `NXRequestExecutionContext`는 준비된 요청, 요청 식별자, 재시도 시도 번호, 커스텀 메타데이터를 인터셉터에서 조회할 수 있게 합니다. +/// `NXRequestExecutionContext`의 준비된 요청, 요청 식별자, retry 시도 번호, 사용자 정의 metadata를 interceptor에서 조회 가능 public struct NXRequestExecutionContext: Sendable { - /// 현재 실행 중인 요청입니다. + /// 현재 실행 중인 요청 public let request: URLRequest - /// 동일한 논리적 요청의 모든 시도에서 공유되는 안정적인 식별자입니다. + /// 동일 논리 요청 전체 시도에서 공유되는 안정적 식별자 public let requestIdentifier: UUID - /// 현재 시도 번호(`1`부터 시작)입니다. + /// 현재 시도 번호(`1`부터 시작) public let attemptNumber: Int - /// 요청에 붙는 커스텀 문자열 메타데이터입니다. + /// 요청 바인딩용 사용자 정의 문자열 metadata 값 public let userInfo: [String: String] let specification: RequestSpec let clientConfiguration: NXClientConfiguration let authRefreshCoordinator: NXAuthRefreshCoordinator - /// 다른 요청 값으로 만든 컨텍스트 사본을 반환합니다. + /// 대체 요청 기반 context 사본 생성 /// - /// - Parameter request: 이후 체인에서 사용할 대체 요청입니다. `httpMethod`는 설정된 요청 메서드와 같아야 합니다. - /// - Returns: 업데이트된 요청을 담은 새 실행 컨텍스트입니다. + /// - Parameter request: 이후 chain에서 사용할 대체 요청(`httpMethod`는 설정된 요청 method와 동일) + /// - Returns: 갱신된 요청 포함 신규 실행 context /// - /// 다른 값이거나 누락된 `httpMethod`를 가진 요청을 전달하면, 이후 인터셉터/로깅/캐시/트랜스포트 전에 ``NXError/invalidRequest(_:)``로 실행이 종료됩니다. + /// `httpMethod` 값 불일치 또는 누락 요청 전달 시, 이후 interceptor/logging/cache/transport 이전 ``NXError/invalidRequest(_:)`` 실행 종료 public func replacingRequest(_ request: URLRequest) -> Self { Self( request: request, diff --git a/Sources/Runtime/NXURLSessionTransport.swift b/Sources/Runtime/NXURLSessionTransport.swift index 14d407e..562e890 100644 --- a/Sources/Runtime/NXURLSessionTransport.swift +++ b/Sources/Runtime/NXURLSessionTransport.swift @@ -7,23 +7,23 @@ import Foundation -/// `URLSession` 기반 기본 HTTP 전송 계층입니다. +/// `URLSession` 기반 기본 HTTP transport public struct NXURLSessionTransport: NXHTTPTransport, Sendable { let urlSession: URLSession let metricsObserver: (any NXNetworkMetricsObserver)? - /// 메트릭을 수집하지 않고 `URLSession`으로 요청을 전송하는 전송 계층을 생성합니다. + /// `URLSession` transport만 수행하는 metrics 비수집 transport 생성 /// - /// - Parameter urlSession: 요청을 실행할 세션입니다. + /// - Parameter urlSession: 요청 실행 세션 public init(urlSession: URLSession = .shared) { self.urlSession = urlSession metricsObserver = nil } - /// `URLSession`으로 요청을 전송하고 메트릭 스냅샷을 기록하는 전송 계층을 생성합니다. + /// `URLSession` transport 및 metrics snapshot 기록 지원 transport 생성 /// - /// - Parameter urlSession: 요청을 실행할 세션입니다. - /// - Parameter metricsObserver: `URLSession` 메트릭 스냅샷을 수신하는 옵저버입니다. + /// - Parameter urlSession: 요청 실행 세션 + /// - Parameter metricsObserver: `URLSession` metrics snapshot 수신 observer public init( urlSession: URLSession = .shared, metricsObserver: any NXNetworkMetricsObserver @@ -32,10 +32,10 @@ public struct NXURLSessionTransport: NXHTTPTransport, Sendable { self.metricsObserver = metricsObserver } - /// 준비된 요청을 내부 `URLSession`으로 전송합니다. + /// 준비된 요청 내부 `URLSession` transport /// - /// - Parameter request: 실행할 준비된 요청입니다. - /// - Returns: 원시 응답 데이터와 HTTP 메타데이터입니다. + /// - Parameter request: 실행 준비 요청 + /// - Returns: `NXRawResponse`의 응답 data와 HTTP metadata public func send(_ request: URLRequest) async throws -> NXRawResponse { let metricsDelegate = metricsObserver.map(NXURLSessionTaskMetricsDelegate.init) let (data, response) = try await urlSession.data(for: request, delegate: metricsDelegate) From 4a922a1d205bcb21dc18a2dbc575c8c6da204615 Mon Sep 17 00:00:00 2001 From: opficdev <162981733+opficdev@users.noreply.github.com> Date: Tue, 25 Aug 2026 10:32:27 +0900 Subject: [PATCH 4/7] =?UTF-8?q?docs:=20=ED=95=B5=EC=8B=AC=20=EB=AA=A8?= =?UTF-8?q?=EB=8D=B8=20=EC=A3=BC=EC=84=9D=20=EC=9E=AC=EA=B5=AC=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Sources/Core/NXClientConfiguration.swift | 46 ++++++++++++------------ Sources/Core/NXError.swift | 22 ++++++------ Sources/Core/NXHTTPMethod.swift | 2 +- Sources/Core/NXRawResponse.swift | 8 ++--- Sources/Core/NXRequestBody.swift | 2 +- Sources/Core/NXValidationPolicy.swift | 8 ++--- 6 files changed, 44 insertions(+), 44 deletions(-) diff --git a/Sources/Core/NXClientConfiguration.swift b/Sources/Core/NXClientConfiguration.swift index 0a06ce5..15ea6d0 100644 --- a/Sources/Core/NXClientConfiguration.swift +++ b/Sources/Core/NXClientConfiguration.swift @@ -7,11 +7,11 @@ import Foundation -/// API 클라이언트가 생성하는 모든 요청에 적용되는 공통 설정입니다. +/// API client가 생성하는 모든 요청의 공통 설정 /// /// ## 개요 /// -/// 공통 네트워킹 동작을 한 곳에 정의하고 `NXAPIClient`를 통해 재사용하세요. +/// 공통 네트워크 동작의 단일 정의 지점, `NXAPIClient` 통한 재사용 /// /// ```swift /// import Foundation @@ -30,40 +30,40 @@ import Foundation /// let client = NXAPIClient(configuration: configuration) /// ``` public struct NXClientConfiguration: Sendable { - /// 상대 경로 요청을 해석할 때 사용하는 기본 URL입니다. + /// 상대 경로 요청 해석 기본 URL public let baseURL: URL - /// 모든 요청에 추가되는 헤더입니다. 키가 겹치면 요청 단위 헤더가 이 헤더를 덮어씁니다. + /// 모든 요청 공통 header(키 충돌 시 요청 단위 header 우선 적용) public let headers: [String: String] - /// 조립된 `URLRequest` 실행에 사용하는 전송 계층입니다. + /// 조립된 `URLRequest` 실행 transport public let transport: any NXHTTPTransport - /// 요청 라이프사이클 이벤트를 수신하는 로거입니다. + /// 요청 lifecycle event 수신 logger public let logger: any NXLogger - /// 모든 요청에 적용되는 인터셉터입니다. + /// 요청별 적용 interceptor public let interceptors: [any NXHTTPInterceptor] - /// 성공한 GET 응답과 진행 중인 동일 요청에 대한 캐시 동작입니다. + /// 성공한 GET 응답 및 진행 중 동일 요청의 cache 동작 public let cache: NXCache - /// 타입 지정 요청에서 응답 본문을 디코딩할 때 사용하는 디코더입니다. + /// type 지정 요청 응답 body decoder public let decoder: JSONDecoder - /// `json(_:encoder:)`에 인코더가 전달되지 않을 때 JSON 요청 본문을 만드는 인코더입니다. + /// `json(_:encoder:)` 미전달 시 사용 JSON 요청 body encoder public let encoder: JSONEncoder - /// 실패한 서버 응답을 도메인 전용 오류로 매핑할 수 있는 디코더입니다. + /// 실패한 서버 응답을 도메인 전용 오류로 mapping하는 decoder public let serverErrorDecoder: any NXServerErrorDecoder - /// 인증 요청에서 베어러 토큰을 조회하고 갱신하는 데 사용하는 공급자입니다. + /// 인증 요청에서 베어러 토큰 조회 및 갱신 provider public let authTokenProvider: (any NXAuthTokenProvider)? - /// 클라이언트 구성을 생성합니다. + /// client 구성 initialization /// /// - Parameters: - /// - baseURL: 상대 경로 요청을 해석할 때 사용하는 기본 URL입니다. - /// - headers: 모든 요청에 추가되는 헤더입니다. - /// - transport: 요청 실행을 담당하는 전송 계층입니다. - /// - logger: 요청 라이프사이클 이벤트를 받는 로거입니다. - /// - interceptors: 모든 요청에 적용되는 인터셉터 목록입니다. - /// - cache: 성공한 GET 응답 및 진행 중인 동일 요청에 대한 캐시 동작입니다. - /// - decoder: 타입 지정 응답 디코딩에 사용하는 디코더입니다. - /// - encoder: JSON 요청 본문 인코딩에 사용하는 인코더입니다. - /// - serverErrorDecoder: 실패 응답을 커스텀 오류로 매핑하는 디코더입니다. - /// - authTokenProvider: 인증 요청에 사용되는 공급자입니다. + /// - baseURL: 상대 경로 요청 해석 기본 URL + /// - headers: 모든 요청 공통 header(키 충돌 시 요청 단위 header 우선 적용) + /// - transport: 요청 실행 transport + /// - logger: 요청 lifecycle event 수신 logger + /// - interceptors: 요청 적용 interceptor 목록 + /// - cache: 성공한 GET 응답 및 진행 중 동일 요청의 cache 동작 + /// - decoder: type 지정 응답 decoding decoder + /// - encoder: JSON 요청 body encoder + /// - serverErrorDecoder: 실패 응답 사용자 정의 오류 mapping decoder + /// - authTokenProvider: 인증 요청용 token provider public init( baseURL: URL, headers: [String: String] = [:], diff --git a/Sources/Core/NXError.swift b/Sources/Core/NXError.swift index 08be4c0..7801f20 100644 --- a/Sources/Core/NXError.swift +++ b/Sources/Core/NXError.swift @@ -7,26 +7,26 @@ import Foundation -/// Nexa가 요청 조립, 전송, 유효성 검사, 디코딩 과정에서 발생시키는 오류입니다. +/// Nexa 요청 조립·transport·validation·decoding 과정 오류 public enum NXError: Error, Sendable { - /// 입력으로 유효한 HTTP 요청을 만들 수 없어 요청 조립이 실패했습니다. + /// 입력으로 유효한 HTTP 요청 생성 실패 case invalidRequest(String) - /// 요청에 인증이 필요했지만 사용 가능한 토큰이 없습니다. + /// 인증 필요 요청에서 사용 가능한 토큰 미보유 case authenticationRequired - /// 요청에 인증이 필요했지만 인증 토큰 공급자가 설정되지 않았습니다. + /// 인증 필요 요청에서 `NXAuthTokenProvider` 미설정 case authProviderUnavailable - /// 전송 계층에서 `URLError`가 발생했습니다. + /// transport `URLError` 발생 case transport(URLError) - /// 요청이 시간 초과되었습니다. + /// 요청 타임아웃 case timeout - /// 요청이 취소되었습니다. + /// 요청 취소 case cancelled - /// 수신한 상태 코드에 대한 응답 유효성 검사가 실패했습니다. + /// 수신 상태 코드 응답 validation 실패 case invalidStatus(statusCode: Int, data: Data?) - /// 서버가 실패 상태 코드를 반환했고 사용자 정의 서버 오류로 디코딩되었습니다. + /// 실패 상태 코드 응답의 사용자 정의 서버 오류 decoding case server(statusCode: Int, data: Data?, underlying: any Error) - /// 성공한 요청의 응답 디코딩이 실패했습니다. + /// 성공 요청 응답 decoding 실패 case decoding(any Error, data: Data?) - /// 분류되지 않은 오류가 발생했습니다. + /// 분류되지 않은 오류 case unknown(any Error) } diff --git a/Sources/Core/NXHTTPMethod.swift b/Sources/Core/NXHTTPMethod.swift index 43a71d4..fbaa158 100644 --- a/Sources/Core/NXHTTPMethod.swift +++ b/Sources/Core/NXHTTPMethod.swift @@ -7,7 +7,7 @@ import Foundation -/// Nexa 요청 빌더가 지원하는 HTTP 메서드입니다. +/// Nexa request builder 지원 HTTP method public enum NXHTTPMethod: String, Sendable, Hashable { case get = "GET" case post = "POST" diff --git a/Sources/Core/NXRawResponse.swift b/Sources/Core/NXRawResponse.swift index d4e81f8..7b35758 100644 --- a/Sources/Core/NXRawResponse.swift +++ b/Sources/Core/NXRawResponse.swift @@ -7,14 +7,14 @@ import Foundation -/// Nexa에서 디코딩 전 반환하는 원시 HTTP 응답입니다. +/// decoding 전 반환용 HTTP 응답 container public struct NXRawResponse: Sendable { - /// 원시 응답 본문 데이터입니다. + /// 응답 body data public var data: Data - /// 응답 본문과 연결된 HTTP 응답입니다. + /// body 연계 HTTP 응답 public var response: HTTPURLResponse - /// 원시 응답 컨테이너를 생성합니다. + /// HTTP 응답 container 생성 public init(data: Data, response: HTTPURLResponse) { self.data = data self.response = response diff --git a/Sources/Core/NXRequestBody.swift b/Sources/Core/NXRequestBody.swift index 150b077..b15e9f9 100644 --- a/Sources/Core/NXRequestBody.swift +++ b/Sources/Core/NXRequestBody.swift @@ -7,7 +7,7 @@ import Foundation -/// Nexa가 지원하는 요청 본문 표현 방식입니다. +/// Nexa 요청 body 표현 방식 public enum NXRequestBody: Sendable { case data(Data) diff --git a/Sources/Core/NXValidationPolicy.swift b/Sources/Core/NXValidationPolicy.swift index eb84e7d..f7759d4 100644 --- a/Sources/Core/NXValidationPolicy.swift +++ b/Sources/Core/NXValidationPolicy.swift @@ -7,13 +7,13 @@ import Foundation -/// 응답 상태 코드의 성공 판정 규칙입니다. +/// 응답 상태 코드 성공 validation 규칙 public enum NXValidationPolicy: Sendable { - /// 상태 코드 유효성 검사를 비활성화합니다. + /// 상태 코드 validation 비활성화 case none - /// `200..<300` 범위의 상태 코드만 허용합니다. + /// `200..<300` 범위 상태 코드만 허용 case successStatusCode - /// 지정한 상태 코드 집합만 허용합니다. + /// 지정 상태 코드 집합 허용 case statusCodes(Set) func allows(statusCode: Int) -> Bool { From 988edf56a9419b9c5a6a6f3d30173c9e78eac206 Mon Sep 17 00:00:00 2001 From: opficdev <162981733+opficdev@users.noreply.github.com> Date: Tue, 25 Aug 2026 10:32:32 +0900 Subject: [PATCH 5/7] =?UTF-8?q?docs:=20cache=EC=99=80=20retry=20=EC=A3=BC?= =?UTF-8?q?=EC=84=9D=20=EC=9E=AC=EA=B5=AC=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Sources/Core/NXCache.swift | 10 +++++----- Sources/Core/NXRetryBackoff.swift | 6 +++--- Sources/Core/NXRetryJitter.swift | 6 +++--- 3 files changed, 11 insertions(+), 11 deletions(-) diff --git a/Sources/Core/NXCache.swift b/Sources/Core/NXCache.swift index a598a54..977d320 100644 --- a/Sources/Core/NXCache.swift +++ b/Sources/Core/NXCache.swift @@ -7,14 +7,14 @@ import Foundation -/// 성공한 GET 응답과 진행 중인 동일 요청에 대한 응답 캐시 동작입니다. +/// 성공한 GET 응답과 진행 중인 동일 요청의 cache 동작 public enum NXCache: Sendable, Equatable { - /// 응답을 캐시하지 않고 동일한 요청을 각각 별도로 실행합니다. + /// 동일한 요청 cache 미적용, 개별 실행 case disabled - /// 지정된 TTL 동안 성공한 GET 응답을 메모리에 저장하고, 검증자 재검증 없이 진행 중인 동일 GET 요청 결과를 재사용합니다. + /// 지정된 TTL 동안 성공한 GET 응답 메모리 저장, validator 재검증 없음, 진행 중 동일 GET 요청 결과 재사용 case memory(ttl: TimeInterval) - /// 지정된 TTL 동안 성공한 GET 응답을 메모리에 저장하고, 만료된 검증자 기반 `200` 응답을 재검증합니다. + /// 지정된 TTL 동안 성공한 GET 응답 메모리 저장, 만료된 validator 기반 `200` 응답 재검증 /// - /// 캐시는 이 정책을 받는 `NXAPIClient` 인스턴스에 속합니다. 클라이언트를 다시 생성하면 독립적인 캐시가 생깁니다. + /// cache 소유권은 정책 적용 `NXAPIClient` instance 단위, client 재생성 시 독립 cache 생성 case revalidatingMemory(ttl: TimeInterval) } diff --git a/Sources/Core/NXRetryBackoff.swift b/Sources/Core/NXRetryBackoff.swift index 236406d..2c9332d 100644 --- a/Sources/Core/NXRetryBackoff.swift +++ b/Sources/Core/NXRetryBackoff.swift @@ -7,11 +7,11 @@ import Foundation -/// 재시도 간격에 사용되는 지연 전략입니다. +/// retry 간격 delay 전략 public enum NXRetryBackoff: Sendable { - /// 매 재시도마다 고정 지연을 사용합니다. + /// retry 시 고정 delay 사용 case fixed(TimeInterval) - /// 매 시도마다 지연을 두 배로 늘려 최대 지연에 도달할 때까지 반복합니다. + /// 최대 delay 도달 시까지 시도별 두 배 delay 증가 case exponential(base: TimeInterval, maxDelay: TimeInterval) func delay(forAttempt attemptNumber: Int) -> TimeInterval { diff --git a/Sources/Core/NXRetryJitter.swift b/Sources/Core/NXRetryJitter.swift index 8ddbdcb..ad4f504 100644 --- a/Sources/Core/NXRetryJitter.swift +++ b/Sources/Core/NXRetryJitter.swift @@ -5,10 +5,10 @@ // Created by opfic on 8/23/26. // -/// 로컬 재시도 백오프 지연에 적용하는 무작위화입니다. +/// 로컬 retry backoff delay 무작위화 public enum NXRetryJitter: Sendable, Equatable { - /// 로컬 백오프 지연을 변경하지 않습니다. + /// 로컬 backoff delay 비변경 case none - /// 로컬 백오프 지연 범위 내의 임의 값을 사용합니다. + /// 로컬 backoff delay 범위 임의값 사용 case full } From 0d14e691d5259be791d6e7d48428d88d8e947f9b Mon Sep 17 00:00:00 2001 From: opficdev <162981733+opficdev@users.noreply.github.com> Date: Tue, 25 Aug 2026 10:32:39 +0900 Subject: [PATCH 6/7] =?UTF-8?q?docs:=20logging=EA=B3=BC=20metrics=20?= =?UTF-8?q?=EC=A3=BC=EC=84=9D=20=EC=9E=AC=EA=B5=AC=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Sources/Core/NXLogging.swift | 72 ++++++++++----------- Sources/Core/NXNetworkMetrics.swift | 30 ++++----- Sources/Core/NXNetworkMetricsObserver.swift | 6 +- 3 files changed, 54 insertions(+), 54 deletions(-) diff --git a/Sources/Core/NXLogging.swift b/Sources/Core/NXLogging.swift index 0f94c51..b0c5e22 100644 --- a/Sources/Core/NXLogging.swift +++ b/Sources/Core/NXLogging.swift @@ -7,7 +7,7 @@ import Foundation -/// Nexa 로거가 내보내는 요청 라이프사이클 이벤트입니다. +/// Nexa logger가 내보내는 요청 lifecycle event public enum NXLogEvent: Sendable { case requestStart(NXRequestStartLog) case requestEnd(NXRequestEndLog) @@ -16,20 +16,20 @@ public enum NXLogEvent: Sendable { case authRefresh(NXAuthRefreshLog) } -/// 요청 시도 시작 시점에 출력되는 구조화된 페이로드입니다. +/// 요청 시도 시작 시점 구조화 payload public struct NXRequestStartLog: Sendable { - /// 동일한 논리 요청의 모든 시도에서 공유되는 안정적 식별자입니다. + /// 동일한 논리 요청 시도 간 공유 안정적 식별자 public let requestIdentifier: UUID - /// 현재 시도 번호(`1`부터 시작)입니다. + /// 현재 시도 번호(`1`부터 시작) public let attemptNumber: Int - /// 전송할 요청의 HTTP 메서드 문자열입니다. + /// 전송 HTTP 메서드 문자열 public let method: String - /// 완전히 해석된 요청 URL 문자열입니다. + /// 완전 해석된 요청 URL 문자열 public let url: String - /// 요청에 포함된 최종 헤더입니다. + /// 요청 최종 header public let headers: [String: String] - /// 요청 시작 로그 페이로드를 생성합니다. + /// 요청 시작 log payload 생성 public init( requestIdentifier: UUID, attemptNumber: Int, @@ -45,20 +45,20 @@ public struct NXRequestStartLog: Sendable { } } -/// 요청 시도가 성공적으로 끝났을 때 출력되는 구조화된 페이로드입니다. +/// 요청 성공 종료 시점 구조화 payload public struct NXRequestEndLog: Sendable { - /// 동일한 논리 요청의 모든 시도에서 공유되는 안정적인 식별자입니다. + /// 동일한 논리 요청 시도 간 공유 안정적 식별자 public let requestIdentifier: UUID - /// 현재 시도 번호(`1`부터 시작)입니다. + /// 현재 시도 번호(`1`부터 시작) public let attemptNumber: Int - /// 서버가 반환한 HTTP 상태 코드입니다. + /// 서버 반환 HTTP 상태 코드 public let statusCode: Int - /// 시도의 실제 경과 시간입니다. + /// 시도 실제 경과 시간 public let elapsedTime: TimeInterval - /// 응답 페이로드 크기(바이트)입니다. + /// 응답 payload 크기(byte) public let payloadSize: Int - /// 요청 완료 로그 페이로드를 생성합니다. + /// 요청 완료 log payload 생성 public init( requestIdentifier: UUID, attemptNumber: Int, @@ -74,18 +74,18 @@ public struct NXRequestEndLog: Sendable { } } -/// 요청 시도가 실패했을 때 출력되는 구조화된 페이로드입니다. +/// 요청 실패 시점 구조화 payload public struct NXRequestFailureLog: Sendable { - /// 동일한 논리 요청의 모든 시도에서 공유되는 안정적인 식별자입니다. + /// 동일한 논리 요청 시도 간 공유 안정적 식별자 public let requestIdentifier: UUID - /// 현재 시도 번호(`1`부터 시작)입니다. + /// 현재 시도 번호(`1`부터 시작) public let attemptNumber: Int - /// 시도의 실제 경과 시간입니다. + /// 시도 실제 경과 시간 public let elapsedTime: TimeInterval - /// 사람이 읽기 쉬운 실패 설명입니다. + /// 사람이 읽기 쉬운 실패 설명 public let errorDescription: String - /// 요청 실패 로그 페이로드를 생성합니다. + /// 요청 실패 log payload 생성 public init( requestIdentifier: UUID, attemptNumber: Int, @@ -99,16 +99,16 @@ public struct NXRequestFailureLog: Sendable { } } -/// Nexa가 다음 재시도를 예약할 때 출력되는 구조화된 페이로드입니다. +/// Nexa 다음 retry 예약 시 출력 구조화 payload public struct NXRetryLog: Sendable { - /// 동일한 논리 요청의 모든 시도에서 공유되는 안정적인 식별자입니다. + /// 동일한 논리 요청 시도 간 공유 안정적 식별자 public let requestIdentifier: UUID - /// 다음에 실행될 시도 번호입니다. + /// 다음 실행 시도 번호 public let nextAttemptNumber: Int - /// 다음 시도 시작 전 대기 시간입니다. + /// 다음 시도 시작 전 대기 시간 public let delay: TimeInterval - /// 재시도 로그 페이로드를 생성합니다. + /// retry log payload 생성 public init(requestIdentifier: UUID, nextAttemptNumber: Int, delay: TimeInterval) { self.requestIdentifier = requestIdentifier self.nextAttemptNumber = nextAttemptNumber @@ -116,35 +116,35 @@ public struct NXRetryLog: Sendable { } } -/// 인증 토큰 갱신 시도 종료 후 출력되는 구조화된 페이로드입니다. +/// 인증 토큰 갱신 시도 종료 후 출력 구조화 payload public struct NXAuthRefreshLog: Sendable { - /// 갱신을 시작한 요청의 식별자입니다. + /// 갱신 시작 요청 식별자 public let requestIdentifier: UUID - /// 갱신 시도 성공 여부입니다. + /// 갱신 시도 성공 여부 public let succeeded: Bool - /// 인증 갱신 로그 페이로드를 생성합니다. + /// 인증 갱신 log payload 생성 public init(requestIdentifier: UUID, succeeded: Bool) { self.requestIdentifier = requestIdentifier self.succeeded = succeeded } } -/// Nexa의 구조화된 요청 라이프사이클 이벤트를 수신합니다. +/// Nexa의 구조화된 요청 lifecycle event 수신 /// /// ## 개요 /// -/// 요청 라이프사이클 이벤트를 자체 로깅 또는 분석 파이프라인으로 전달하려면 `NXLogger`를 채택하세요. +/// 요청 lifecycle event의 자체 logging 또는 analytics pipeline 전달 대상 `NXLogger` 채택 public protocol NXLogger: Sendable { - /// Nexa가 발행한 로그 이벤트 한 건을 처리합니다. + /// Nexa 발행 log event 단건 처리 func log(_ event: NXLogEvent) async } -/// 발생한 모든 이벤트를 무시하는 로거입니다. +/// 발생 event 전체 무시 logger public struct NXNoopLogger: NXLogger { - /// 아무 작업도 수행하지 않는 로거를 생성합니다. + /// 무동작 logger 생성 public init() {} - /// 전달된 로그 이벤트를 무시합니다. + /// 전달 log event 무시 public func log(_ event: NXLogEvent) async {} } diff --git a/Sources/Core/NXNetworkMetrics.swift b/Sources/Core/NXNetworkMetrics.swift index 3f45b90..a54cbb9 100644 --- a/Sources/Core/NXNetworkMetrics.swift +++ b/Sources/Core/NXNetworkMetrics.swift @@ -7,21 +7,21 @@ import Foundation -/// 하나의 `URLSession` 작업에서 발생한 네트워크 활동의 값 스냅샷입니다. +/// `URLSession` task 기반 네트워크 활동 값 snapshot /// -/// `NXURLSessionTransport`는 이 값을 `NXNetworkMetricsObserver`에 전달하기 전에 생성합니다. -/// 사용자 정의 `NXHTTPTransport` 구현은 이 값을 생성하지 않습니다. +/// `NXURLSessionTransport`는 `NXNetworkMetricsObserver` 전달 전 snapshot 생성 +/// 사용자 정의 `NXHTTPTransport` 구현은 snapshot 미생성 public struct NXNetworkMetrics: Sendable, Equatable { - /// URL 로딩 작업의 총 소요 시간입니다. + /// URL loading task 총 소요 시간 public let taskDuration: TimeInterval? - /// URL 로딩 작업이 따라간 리다이렉트 횟수입니다. + /// URL loading task redirect 횟수 public let redirectCount: Int - /// URL 로딩 작업에서 수집한 트랜잭션 개수입니다. + /// URL loading task 수집 transaction 개수 public let transactionCount: Int - /// `URLSession`이 보고한 순서를 보존한 트랜잭션 스냅샷입니다. + /// `URLSession` 보고 순서 보존 transaction snapshot public let transactions: [NXNetworkTransactionMetrics] - /// 네트워크 메트릭 스냅샷을 생성합니다. + /// 네트워크 metrics snapshot 생성 public init( taskDuration: TimeInterval?, redirectCount: Int, @@ -35,20 +35,20 @@ public struct NXNetworkMetrics: Sendable, Equatable { } } -/// 하나의 URL 로딩 트랜잭션에 대한 값 스냅샷입니다. +/// 단일 URL loading transaction 값 snapshot public struct NXNetworkTransactionMetrics: Sendable, Equatable { - /// URLSession이 두 타임스탬프를 모두 보고한 경우의 DNS 조회 시간입니다. + /// `URLSession` 시작·종료 timestamp 제공 시 DNS 조회 시간 public let domainLookupDuration: TimeInterval? - /// URLSession이 두 타임스탬프를 모두 보고한 경우 연결 시작부터 종료까지의 시간입니다. + /// `URLSession` 시작·종료 timestamp 제공 시 연결 시작부터 종료까지의 시간 public let connectionDuration: TimeInterval? - /// URLSession이 두 타임스탬프를 모두 보고한 경우 TLS 협상 시간입니다. + /// `URLSession` 시작·종료 timestamp 제공 시 TLS 협상 시간 public let secureConnectionDuration: TimeInterval? - /// URLSession이 두 타임스탬프를 모두 보고한 경우 요청 시작부터 첫 바이트 응답 수신까지의 시간입니다. + /// `URLSession` 시작·종료 timestamp 제공 시 요청 시작부터 첫 응답 byte 수신까지의 시간 public let timeToFirstByte: TimeInterval? - /// URLSession이 기존 연결을 재사용했는지 여부입니다. + /// 기존 연결 재사용 여부 public let isConnectionReused: Bool - /// 트랜잭션 메트릭 스냅샷을 생성합니다. + /// transaction metrics snapshot 생성 public init( domainLookupDuration: TimeInterval?, connectionDuration: TimeInterval?, diff --git a/Sources/Core/NXNetworkMetricsObserver.swift b/Sources/Core/NXNetworkMetricsObserver.swift index 0182339..2f70b13 100644 --- a/Sources/Core/NXNetworkMetricsObserver.swift +++ b/Sources/Core/NXNetworkMetricsObserver.swift @@ -5,10 +5,10 @@ // Created by opfic on 8/23/26. // -/// `NXURLSessionTransport`에서 수집한 메트릭 스냅샷을 수신합니다. +/// `NXURLSessionTransport` 수집 metrics snapshot 수신 대상 /// -/// 메트릭 전달은 요청 완료와 로거 이벤트 순서와 독립적으로 수행됩니다. +/// 요청 완료 및 logger event 순서와 독립적 metrics 전달 public protocol NXNetworkMetricsObserver: Sendable { - /// 네트워크 메트릭 스냅샷을 한 건 기록합니다. + /// 네트워크 metrics snapshot 단건 기록 func record(_ metrics: NXNetworkMetrics) async } From db874e61c400423a843bc6a2bd7911c8580eb519 Mon Sep 17 00:00:00 2001 From: opficdev <162981733+opficdev@users.noreply.github.com> Date: Tue, 25 Aug 2026 10:32:46 +0900 Subject: [PATCH 7/7] =?UTF-8?q?docs:=20Runtime=20=EC=A3=BC=EC=84=9D=20?= =?UTF-8?q?=EC=98=81=EB=AC=B8=20=EC=9A=A9=EC=96=B4=20=EB=B3=B5=EC=9B=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Sources/Runtime/NXAuthRefreshCoordinator.swift | 8 ++++---- Sources/Runtime/NXLoggerInterceptor.swift | 2 +- Sources/Runtime/NXRequestExecutor.swift | 4 ++-- Sources/Runtime/NXResponseCacheInterceptor.swift | 6 +++--- Sources/Runtime/NXResponseCacheStore.swift | 6 +++--- Sources/Runtime/NXRetryInterceptor.swift | 2 +- Sources/Runtime/NXURLSessionTaskMetricsDelegate.swift | 6 +++--- 7 files changed, 17 insertions(+), 17 deletions(-) diff --git a/Sources/Runtime/NXAuthRefreshCoordinator.swift b/Sources/Runtime/NXAuthRefreshCoordinator.swift index 9327871..d1deb1b 100644 --- a/Sources/Runtime/NXAuthRefreshCoordinator.swift +++ b/Sources/Runtime/NXAuthRefreshCoordinator.swift @@ -8,9 +8,9 @@ import Foundation actor NXAuthRefreshCoordinator { - // 현재 client에서 공유하는 진행 중 access token 갱신 작업 + // 현재 client에서 공유하는 진행 중 access token 갱신 task private var inFlightRefresh: InFlightRefresh? - // 갱신 작업별 결과 대기 continuation을 보관하는 저장소 + // 갱신 task별 결과 대기 continuation 보관 store private var waiters: [UUID: [UUID: CheckedContinuation]] = [:] private let onWaiterRegistered: (@Sendable () -> Void)? private let onRefreshCompleted: (@Sendable () -> Void)? @@ -23,7 +23,7 @@ actor NXAuthRefreshCoordinator { self.onRefreshCompleted = onRefreshCompleted } - // access token 갱신 작업을 공유하는 메서드 + // access token 갱신 task 공유 메서드 func refreshAccessToken( using provider: any NXAuthTokenProvider, logger: any NXLogger, @@ -139,7 +139,7 @@ actor NXAuthRefreshCoordinator { } self.inFlightRefresh = nil - // 완료된 갱신 작업의 결과 대기 continuation 목록 + // 완료된 갱신 task의 결과 대기 continuation 목록 let continuations = waiters.removeValue(forKey: inFlightRefresh.identifier).map { Array($0.values) } ?? [] diff --git a/Sources/Runtime/NXLoggerInterceptor.swift b/Sources/Runtime/NXLoggerInterceptor.swift index 6d0c87d..aec5cc3 100644 --- a/Sources/Runtime/NXLoggerInterceptor.swift +++ b/Sources/Runtime/NXLoggerInterceptor.swift @@ -8,7 +8,7 @@ import Foundation struct NXLoggerInterceptor: NXHTTPInterceptor { - // 요청 생명주기 로그를 기록하는 interceptor + // 요청 lifecycle log 기록 interceptor func intercept( context: NXRequestExecutionContext, next: @escaping @Sendable (NXRequestExecutionContext) async throws -> NXRawResponse diff --git a/Sources/Runtime/NXRequestExecutor.swift b/Sources/Runtime/NXRequestExecutor.swift index da81e89..339feb4 100644 --- a/Sources/Runtime/NXRequestExecutor.swift +++ b/Sources/Runtime/NXRequestExecutor.swift @@ -8,7 +8,7 @@ import Foundation enum NXRequestExecutor { - // 요청을 조립하고 원시 응답을 검증하는 실행 경계 + // 요청 조립과 `NXRawResponse` validation 실행 경계 static func executeRaw( clientConfiguration: NXClientConfiguration, responseCacheStore: NXResponseCacheStore?, @@ -53,7 +53,7 @@ enum NXRequestExecutor { } } - // 원시 응답을 지정한 타입으로 디코딩하는 실행 경계 + // `NXRawResponse`의 지정 type decoding 실행 경계 static func executeDecode( clientConfiguration: NXClientConfiguration, responseCacheStore: NXResponseCacheStore?, diff --git a/Sources/Runtime/NXResponseCacheInterceptor.swift b/Sources/Runtime/NXResponseCacheInterceptor.swift index 1900f8b..b78de32 100644 --- a/Sources/Runtime/NXResponseCacheInterceptor.swift +++ b/Sources/Runtime/NXResponseCacheInterceptor.swift @@ -11,12 +11,12 @@ struct NXResponseCacheInterceptor: NXHTTPInterceptor { let cache: NXCache let store: NXResponseCacheStore - // cache 적용과 저장소 호출 조정 역할 + // cache 적용과 store 호출 조정 역할 func intercept( context: NXRequestExecutionContext, next: @escaping @Sendable (NXRequestExecutionContext) async throws -> NXRawResponse ) async throws -> NXRawResponse { - // cache 저장소에 전달할 만료 시간과 재검증 여부 + // cache store 전달용 만료 시간과 재검증 여부 let cachePolicy: (ttl: TimeInterval, revalidatesExpiredResponse: Bool)? = switch cache { case let .memory(ttl): (ttl, false) @@ -65,7 +65,7 @@ struct NXResponseCacheInterceptor: NXHTTPInterceptor { ) } - // 재검증 결과로 반환할 원시 응답 구성 역할 + // 재검증 결과 반환용 `NXRawResponse` 구성 역할 private static func revalidatedResponse( rawResponse: NXRawResponse, revalidationContext: NXCacheRevalidationContext? diff --git a/Sources/Runtime/NXResponseCacheStore.swift b/Sources/Runtime/NXResponseCacheStore.swift index 32bba24..1baa7f2 100644 --- a/Sources/Runtime/NXResponseCacheStore.swift +++ b/Sources/Runtime/NXResponseCacheStore.swift @@ -30,9 +30,9 @@ struct NXCacheRevalidationContext: Sendable { } actor NXResponseCacheStore { - // cache 키별 응답과 만료 시각을 보관하는 저장소 + // cache key별 응답과 만료 시각 보관 store private var responses: [NXRequestCacheKey: CachedResponse] = [:] - // cache 키별 진행 중 요청 작업을 보관하는 저장소 + // cache key별 진행 중 요청 task 보관 store private var inFlightTasks: [NXRequestCacheKey: Task] = [:] // cache 조회와 저장을 조정하는 메서드 @@ -44,7 +44,7 @@ actor NXResponseCacheStore { load: @escaping @Sendable (NXCacheRevalidationContext?) async throws -> NXRawResponse ) async throws -> NXRawResponse { let now = Date() - // 만료 응답과 validator를 전달하는 재검증 문맥 + // 만료 응답과 validator 전달 revalidation context var revalidationContext: NXCacheRevalidationContext? if let cachedResponse = responses[key] { diff --git a/Sources/Runtime/NXRetryInterceptor.swift b/Sources/Runtime/NXRetryInterceptor.swift index 4191966..61f3cf3 100644 --- a/Sources/Runtime/NXRetryInterceptor.swift +++ b/Sources/Runtime/NXRetryInterceptor.swift @@ -14,7 +14,7 @@ struct NXRetryInterceptor: NXHTTPInterceptor { self.dependencies = dependencies } - // 재시도 정책에 따라 요청 실행을 조정하는 interceptor + // retry policy에 따라 요청 실행을 조정하는 interceptor func intercept( context: NXRequestExecutionContext, next: @escaping @Sendable (NXRequestExecutionContext) async throws -> NXRawResponse diff --git a/Sources/Runtime/NXURLSessionTaskMetricsDelegate.swift b/Sources/Runtime/NXURLSessionTaskMetricsDelegate.swift index 466631d..79ab607 100644 --- a/Sources/Runtime/NXURLSessionTaskMetricsDelegate.swift +++ b/Sources/Runtime/NXURLSessionTaskMetricsDelegate.swift @@ -14,7 +14,7 @@ final class NXURLSessionTaskMetricsDelegate: NSObject, URLSessionTaskDelegate { self.metricsObserver = metricsObserver } - // URLSession task 측정값을 Nexa snapshot으로 전달하는 delegate 메서드 + // URLSession task metrics를 Nexa snapshot으로 전달하는 delegate 메서드 func urlSession( _ session: URLSession, task: URLSessionTask, @@ -34,7 +34,7 @@ private struct NXURLSessionTaskMetricsSource: NXNetworkMetricsSource { let redirectCount: Int let transactions: [NXURLSessionTaskTransactionMetricsSource] - // URLSession task 측정값에서 전송 snapshot source를 구성하는 initializer + // URLSession task metrics에서 transport snapshot source 구성 initializer init(metrics: URLSessionTaskMetrics) { taskInterval = metrics.taskInterval redirectCount = metrics.redirectCount @@ -53,7 +53,7 @@ private struct NXURLSessionTaskTransactionMetricsSource: NXNetworkTransactionMet let responseStartDate: Date? let isConnectionReused: Bool - // URLSession transaction 측정값에서 transaction snapshot source를 구성하는 initializer + // URLSession transaction metrics에서 transaction snapshot source 구성 initializer init(metrics: URLSessionTaskTransactionMetrics) { domainLookupStartDate = metrics.domainLookupStartDate domainLookupEndDate = metrics.domainLookupEndDate