JosephCha의 개발일지

네트워크 Endpoint 본문

iOS

네트워크 Endpoint

JosephCha 2023. 8. 9. 15:49
반응형

네트워크 Endpoint

Endpoint : 서버와 클라이언트 간의 통신을 위한 API 요청이 가능한 주소를 나타내는 특정 URL 또는 URI

BaseURL

  • API Endpoint의 기본 URL. 모든 요청은 baseURL을 기반으로 한다.
  • ex) "https://api.example.com/users" 에서 baseURL은 "https://api.example.com/”

path

  • baseURL 이후에 따라오는 경로를 지정
  • ex) "https://api.example.com/users/1” 에서 path는 /users/1

Header

  • HTTP 본문(body) 및 Request/Response에 대한 정보를 포함함
  • HTTP 헤더는 클라이언트와 서버가 요청 또는 응답으로 부가적인 정보를 전송할 수 있도록 해줌

Method

  • 클라이언트가 웹서버에게 요청하는 목적 및 그 종류를 알리는 수단
  • 종류
    • GET : 리소스 획득, URL(URI) 형식으로 웹서버측 리소스(데이터)를 요청
    • HEAD : 메세지헤더(문서정보) 취득
      • GET과 비슷하나, 실제 문서를 요청하는 것이 아니라, 문서정보를 요청, 이에따라 HTTP 응답 메세지에 본문(Body)이 없이HTTP 헤더정보만을 보냄
    • POST : 내용 전송 (파일 전송도 가능)
      • 요청 데이터를 HTTP Body에 담아 웹서버로 전송함
    • PUT : 내용 갱신 위주(파일 전송도 가능)
      • POST처럼 정보를 서버로 제출하는 것으로 형식은 동일하나, 갱신 위주임
    • DELETE : 파일 삭제
      • 웹 리소스를 제거
    • OPTIONS : 웹서버측 제공 메소드에 대한 질의
    • TRACE : 요청 리소스가 수신되는 경로를 보여줌(거의 사용 안함)
    • CONNET : 프록시 서버와 같은 중간 서버 경유(거의 사용 안함)
    GET, POST 2개 또는 OPTIONS를 포함 3개만을 허용하는 경우가 보안상의 이유로 일반적임

Body

  • 메세지 바디(메세지 본문)를 통해 '표현 데이터' 전달
  • 메세지 본문 = 페이로드
  • '표현' : 요청 & 응답에서 전달할 실제 데이터
  • 표현 헤더는 표현 데이터를 해석할 수 있는 정보 제공

Query String

  • Query String은 지정된 매개 변수에 값을 할당하는 URL의 일부
  • 클라이언트에 의해 기본 URL뒤에 덧붙여서 추가적인 정보를 서버측에 전달하는것. 클라이언트가 어떤 특정 리소스에 접근하고 싶어하는지 추가 정보를 담음
  • 정해진 엔드포인트 주소 이후에 ?를 쓰는것으로 쿼리스트링이 시작함, parameter=value(=로 Key와 Value 구분)로 필요한 파라미터의 값을 적음 (파라미터가 여러개일 경우 &를 붙여 여러개의 파라미터를 넘길 수 있음)

클라이언트 단에서는 이 Endpoint 요소들을 조합하여 request를 만들어서 서버와 HTTP 통신을 할 수 있음

  • 예시
// 참고: <https://velog.io/@isouvezz/Swift-Network-Layer-%EA%B5%AC%EC%84%B1%ED%95%98%EA%B8%B0#network-%EB%A0%88%EC%9D%B4%EC%96%B4-%EC%84%A4%EA%B3%84>

enum HttpMethod: String {
    case get = "GET"case post = "POST"case put = "PUT"case delete = "DELETE"
}

// Endpoint 구성 요소
protocol Requestable {
    var baseURL: String { get }
    var path: String { get }
    var method: HttpMethod { get }
    var queryParameters: Encodable? { get }
    var bodyParameters: Encodable? { get }
    var headers: [String: String]? { get }
    var sampleData: Data? { get }
}

extension Requestable {
    func getUrlRequest() throws -> URLRequest {
        let url = try makeUrl()
        var urlRequest = URLRequest(url: url)
        urlRequest.httpMethod = method.rawValue

        if let bodyParameters = try bodyParameters?.toDicionary() {
            if !bodyParameters.isEmpty {
                urlRequest.httpBody = try? JSONSerialization.data(withJSONObject: bodyParameters)
            }
        }

        headers?.forEach { key,value in
            urlRequest.setValue(value, forHTTPHeaderField: "\\(key)")
        }

        return urlRequest
    }

    func makeUrl() throws -> URL {
        let fullPath = "\\(baseURL)\\(path)"guard var urlComponents = URLComponents(string: fullPath) else { throw NetworkError.componentsError}

        var urlQueryItems = [URLQueryItem]()
        if let queryParameters = try queryParameters?.toDicionary() {
            queryParameters.forEach { key,value in
                urlQueryItems.append(URLQueryItem(name: key, value: "\\(value)"))
            }
        }

        urlComponents.queryItems = urlQueryItems.isEmpty ? nil : urlQueryItems
        guard let url = urlComponents.url else { throw NetworkError.componentsError }
        return url
    }
}

'iOS' 카테고리의 다른 글

iOS MVVM 패턴  (0) 2023.08.09
SOLID 원칙  (0) 2023.08.09
iOS 동작과정  (0) 2023.08.09
UIKit 기본개념  (0) 2023.08.09
객체지향 프로그래밍  (0) 2023.02.08
Comments