-
Notifications
You must be signed in to change notification settings - Fork 0
요셉_네트워크 HTTP통신 기본 요소, Moya 네트워크 예제
- HTTP 본문(body) 및 Request/Response에 대한 정보를 포함함
- HTTP 헤더는 클라이언트와 서버가 요청 또는 응답으로 부가적인 정보를 전송할 수 있도록 해줌
-
클라이언트가 웹서버에게 요청하는 목적 및 그 종류를 알리는 수단
-
종류
- GET : 리소스 획득, URL(URI) 형식으로 웹서버측 리소스(데이터)를 요청
-
HEAD : 메세지헤더(문서정보) 취득
- GET과 비슷하나, 실제 문서를 요청하는 것이 아니라, 문서정보를 요청, 이에따라HTTP 응답 메세지에 본문(Body)이 없이HTTP 헤더정보 만을 보냄
-
POST : 내용 전송 (파일 전송도 가능)
- 요청 데이터를 HTTP Body에 담아 웹서버로 전송함
-
PUT : 내용 갱신 위주(파일 전송도 가능)
- POST처럼 정보를 서버로 제출하는 것으로 형식은 동일하나, 갱신 위주임
-
DELETE : 파일 삭제
- 웹 리소스를 제거
- OPTIONS : 웹서버측 제공 메소드에 대한 질의
- TRACE : 요청 리소스가 수신되는 경로를 보여줌(거의 사용 안함)
- CONNET : 프록시 서버와 같은 중간 서버 경유(거의 사용 안함)
GET, POST 2개 또는 OPTIONS를 포함 3개만을 허용하는 경우가 보안상의 이유로 일반적임
- 메세지 바디(메세지 본문)를 통해 '표현 데이터' 전달
- 메세지 본문 = 페이로드
- '표현' : 요청 & 응답에서 전달할 실제 데이터
- 표현 헤더는 표현 데이터를 해석할 수 있는 정보 제공
- Query String은 지정된 매개 변수에 값을 할당하는 URL의 일부
- 클라이언트에 의해 기본 URL뒤에 덧붙여서 추가적인 정보를 서버측에 전달하는것. 클라이언트가 어떤 특정 리소스에 접근하고 싶어하는지 정보를 담음
- 정해진 엔드포인트 주소 이후에 ?를 쓰는것으로 쿼리스트링이 시작함, parameter=value(=로 Key와 Value 구분)로 필요한 파라미터의 값을 적음 (파라미터가 여러개일 경우 &를 붙여 여러개의 파라미터를 넘길 수 있음)
- Alamofire를 한번 더 추상화해서, 네트워크 계층을 템플릿화하여 재사용성, 가독성을 높여 개발자는 오로지 Response와 Request에만 신경 쓸수 있도록해 생상선을 높일 수 있음
- 기존 구조의 문제점으로 크게 3가지를 제시하고 있음
-
Makes it hard to write new apps (“where do I begin?”)
어디서 부터 시작할지 시작의 어려움
-
Makes it hard to maintain existing apps (“oh my god, this mess…”)
유지보수의 어려움
-
Makes it hard to write unit tests (“how do I do this again?”)
유닛 테스트 작성의 어려움
-
-
Enum을 통해 API 목록 작성
enum UserAPI { case LogIn(oAuthProvider : OAuthProvider, accessToken : String) case refreshToken }
-
TargetType 작성
- 작성한 API목록에 TargetType 프로토콜을 채택해 API별로 Request에 필요한 것들을 지정할 수 있음
baseURL
: Server base URL 지정path
: API Path 지정method
: HTTP Method 지정sampleData
: Mock Data for Testtask
: Parameters for request 지정validationType
: 허용할 response 정의 - [validationType 참고](https://github.com/Moya/Moya/blob/development/Sources/Moya/ValidationType.swift)기존 `Alamofire 의 .validate()처럼
리스폰스의 StatusCode` 에 따라 성공 유무를 판단headers
: HTTP headers 적용: 기존의인터셉터의 Adapter
역할을 할 수 있습니다. (ex. 헤더에 JWT 값 넣기)extension UserAPI : TargetType { var baseURL: URL { URL(string: ServiceAPI.baseURL)! } var path: String { switch self { case .LogIn(oAuthProvider: let type, accessToken: _) : return "/login/oauth/" + type.rawValue case .refreshToken : return "/token" } } var method: Moya.Method { switch self { case .LogIn(oAuthProvider: _, accessToken: _) : return .post case .refreshToken : return .get } } // var sampleData: Data { ... } var task: Task { switch self { case .LogIn(oAuthProvider: _, accessToken: let accessToken) : let params : [String: String] = [ "accessToken" : accessToken ] return .requestParameters(parameters: params, encoding: URLEncoding.default ) case .refreshToken : return .requestPlain } } var headers: [String : String]? { switch self { case .refreshToken : guard let userInfo = UserService.shared.userInfo else { return [ "Content-type": "application/json" ] } return [ "Content-type": "application/json", "X-AUTH-TOKEN" : userInfo.token.tokenType + " " + userInfo.token.accessToken ] case .LogIn(oAuthProvider: _, accessToken: _) : return nil // [ "Content-type": "application/json" ] } } var validationType: ValidationType { .successCodes } }
-
Moya Provider 생성
private let provider = MoyaProvider<UserAPI>()
- 네트워크 요청을 수행할 Moya Provider 인스턴스를 생성
- 제네릭 타입으로 TargetType 프로토콜을 준수하는 Enum(API 목록) 을 받고 있음
-
네트워크 요청 / 처리 -
Moya
- Provider를 통해 Request가 가능한데, Request 메소드의 파라미터로 TargetType를 준수하는 API목록의 case를 전달함
- 반환되는 response 는
Result<Response, MoyaError>
형태
provider.request(.LogIn(oAuthProvider: .Kakao, accessToken: accessToken)) { response in switch response { case .success(let result) : guard let data = try? result.map(DataResponse<OAuthLoginResponse>.self) else { return } print(data) case .failure(let err): print(err.localizedDescription) } }
-
Compile-time checking for correct API endpoint accesses
컴파일시 API 엔드 포인트가 올바른지 체크
-
Lets you define a clear usage of different endpoints with associated enum values.
Enum을 이용해서 언제, 어디에 사용될지 안전하게 (type-safe) 정의
-
Treats test stubs as first-class citizens so unit testing is super-easy.
유닛 테스트를 용이하게 만듦.