-
Notifications
You must be signed in to change notification settings - Fork 1
선아_네트워크 Endpoint 분석, Moya 네트워크 예제
sunnyCookie edited this page May 1, 2023
·
2 revisions
- ✅ API가 두 시스템(어플리케이션)이 상호작용(소통) 할 수 있게 하는 프로토콜의 총집합이라면 Endpoint는 API가 서버에서 리소스에 접근가능하게 하는 URI다.
- ex) 지하철 최단 거리 경로를 제공하는 서비스가 있을 때, 사용자는 출발역과 도착역을 설정하고 최단 경로를 찾는 버튼을 터치한다.
이 때 최단경로를 구하는 서비스를 이용하려는 요청 URI가 엔드포인트이다.
-
baseURL
+path
+queryParameters
=>URL
만들고 - 이
URL
에httpBody
,httpMethod
,header
를 사용해 =>URLRequest
를 만들어서 요청
// Endpoint 구현: Requestable, Responsable의 성격을 가지고 있는 클래스
class Endpoint<R>: RequesteResponsable {
// 응답 타입 제네릭 명시
typealias Response = R
var baseURL: String
var path: String
var method: HttpMethod
var queryParameters: Encodable?
var bodyParameters: Encodable?
var headers: [String: String]?
var sampleData: Data?
init(...) {...}
}
- baseURL: endpoint의 root 입니다.
- path: 리소스의 경로. 데이터의 실제 위치를 나타냅니다
- method: 리소스에 접근하는 방법입니다. (ex. GET, POST, DELETE...)
- queryParameters: 물음표로 URL과 구분해서 사용하는 매개변수로 데이터를 정렬, 필터링해줍니다.
- bodyParameters: 해당 request 혹은 response의 실제 메시지 혹은 내용이 담겨 있다.
//bodyParameters json 형식의 예 { "userId": "keepcalm", "message": "hello, world", "status": "noraml" }
- headers: key:value 형태로 돼있으며, 추가 정보를 담고 있는 부분이다. (Host / User-Agent(request) or Server(response) / Connection / Content-Type / Content-Length...)
- 예) body와 header로 완성된 HTTP메세지
POST /userAccount/login HTTP/1.1 // (1) 라인 Host: swiftapi.rubypaper.co.kr:2029. // (2) 헤더 Content-Type: application/x-www-form-urlencoded // (2) 헤더 account=swift%40swift.com&passwd=1234&grant_type=password // (3) 바디
⚙️ Moya 라이브러리
-
URLSession 기반인 Alamofire를 한번 더 추상화한게 Moya다
-
개발자는 Response, Request만 신경쓰면된다.
-
장점
- 깔끔한 네트워크 계층구조를 갖게할 수 있고, 계층을 템플릿화해 재사용성이 높고 가독성이 좋다.
- API Endpoint 가 올바른지 컴파일시 확인해준다
- Enum 연관값 사용으로 다양한 endpoint들에대해 명확한 사용법 정의가 가능하다.
- 유닛테스트가 쉽다.
-
사용예제
- endpoint는 Moya의
TargetType
프로토콜을 채택해 구성할 수 있다.
import Foundation import Moya /* Test IPA 제공 : https://reqres.in/ */ enum TestService: TargetType { case readUserList(page: Int) // https://reqres.in/api/users?page=2 case registerUser(user: User) // https://reqres.in/api/users case updateUser(name: String, id: Int) // https://reqres.in/api/users/2 } extension TestService { var baseURL: URL { guard let url = URL(string: "https://reqres.in") else { fatalError("fatal error, invalid baseURL") } return url } var path: String { switch self { case .readUserList(_), .registerUser: return "/api/users" case .updateUser(_, let id): return "/api/users/\(id)" } } // Http method var method: Moya.Method { switch self { case .readUserList: return .get case .registerUser: return .post case .updateUser: return .put } } var task: Moya.Task { switch self { case .readUserList(let page): return .requestParameters(parameters: ["page": page], encoding: URLEncoding.queryString) case .registerUser, .updateUser: return .requestPlain } // 1. requestPlain : 기본적으로 어떤 값을 넣지 않을 때 사용합니다. (주로 GET) // 2. requestData : Body에 데이터를 담아서 보낼 때 사용합니다. (주로 POST) // 3. requestParameters : 파일을 다운로드 할 때 다운로드 링크를 담습니다. (주로 GET) } var headers: [String : String]? { return nil } }
- endpoint를 이용한 네트워크 통신은 Moya의
MoyaProvider
객체를 생성해 사용한다. 이 때, 요청,응답에 쓰이는 데이터타입을 명시해준다
struct APIManager { private let provider: MoyaProvider = MoyaProvider<TestService>() func requestList(page: Int) { provider.request(.readUserList(page: page)) { result in switch result { ... } } } // ... }
- endpoint는 Moya의
참고문서
iOS-Moya를 이용한 API통신처리
[iOS - swift] Moya를 사용한 network 구조 설계 (무료 API 테스트, REST)
[Moya] Moya프레임 워크 (RESTFul API)
Moya test code 참고: 우아한형제들 기술블로그 - iOS Networking and Testing