Query String에 대해 알아보자 !

2 답변 글타래를 보이고 있습니다
  • 글쓴이
    • 쥬트
      참가자
      • 글작성 : 9
      • 답글작성 : 8

      제가 맡은 뷰에서는 서버에서 주어진 조건에 맞는 데이터를 불러올 일이 있었습니다. 예를 들어 제품의 최상위 2개의 제품만을 찾아 온다거나, 필터, 키워드에 따라 다른 검색 결과를 불러오는 상황이였다.

      Alamofire 비동기 통신을 진행할 때 일반적으로 post 메소드는 서버에 데이터를 추가, 변경, 입력할 때 사용하고 이를 위한 데이터를 body에 담아 JSON 타입 인코딩을 통해 통신을 합니다.


      let header : HTTPHeaders = [ “Content-Type” : “application/json”, “token” : “\(token.string(forKey: “token”)!)” ] let body : Parameters = [ "user_name": name, "user_gender": gender, "user_birth": birth ] Alamofire.request(URL, method: .post, parameters: body, encoding: JSONEncoding.default, headers: header) .responseData { response in … }

      그리고 get 메소드는 단순히 필요한 정보를 얻어오기 때문에 body가 필요없이 API 문서에 따른 URL상으로 데이터를 받아 올 수 있습니다.


      let header : HTTPHeaders = [ “Content-Type” : “application/json”, “token” : “\(token.string(forKey: “token”)!)” ] Alamofire.request(URL, method: .get, parameters: nil, encoding: JSONEncoding.default, headers: header) .responseData { response in … }

      그러나 클라이언트의 기능이 점점 추가될 수록 데이터의 가공이 필요하고 모든 데이터를 받아와서 클라이언트 단에서 처리하는 것은 속도가 매우 느려질 수 있습니다. 또한 서버측에서 이런 조건에 따라 모든 API를 작성하는 것은 매우 반복적이고 불필요한 작업이 될 것입니다.

      따라서 이러한 문제점들을 해결해 주는 것이 바로 ‘Query String’입니다.

      Query String 이란, 사용자가 입력 데이터를 전달하는 방법 중의 하나로서 URL 주소에 미리 협의된 데이터를 파라미터를 통해 넘기는 것을 말합니다.

      여기서 사용자 입력이란 사용자가 검색한 키워드가 될 수도 있고 임의로 설정한 필터 조건이 될 수도 있다 그 외에도 클라이언트에서 데이터의 일부분만을 보여주고 싶을 때 표현할 수도 있습니다.

      Query String의 형식은 예를들어 다음과 같이 나타낼 수 있습니다.

      URL + “?query=keyword&filter=product”

      URL 과 조건문 사이의 ‘?’ 구분자를 두고 필요한 파라미터 값을 적습니다. 그리고 파라미터가 여러개일 경우 ‘&’ 를 붙여 여러개의 파라미터를 넘길 수 있습니다.

      이러한 Query String을 Alamofire통신 라이브러리에서 사용하는 방법을 알아보겠습니다.

      제가 작업했던 상황을 위주로 설명하자면,

      먼저 서버 파트를 맡았던 친구들과 협의하여 제품 검색을 위한 API URL을 설정하였습니다. 그 후 사용자가 검색창에 입력한 키워드를 인자로 받는 함수를 작성하였습니다.


      func searchProduct(keyword: String, completion: @escaping (NetworkResult<Any>) -> Void)

      그 후 Parameters 타입의 변수를 선언하여 사용자 검색 키워드와 필터 값을 value로 하는 변수를 정의 하였습니다.


      let parameters: Parameters = [ "query": keyword, "filter" : "product", ]

      마지막으로 Alamofire의 request 함수를 호출하는데, 함수의 인자로 검색 API를 위한 URL, method 타입(get), 미리 선언해 둔 파라미터 변수, 마지막으로 중요한 인코딩 타입을 URLEncoding.queryString 으로 설정합니다.


      Alamofire.request(APIConstants.SearchBaseURL, method: .get, parameters: parameters, encoding: URLEncoding.queryString) .responseData { response in … }

      다음과 같은 방식으로 함수를 호출하면 데이터 정보를 불러오는 URL이 자동으로

      URL + “?query=keyword&amp;filter=product”

      식으로 변환되기 때문에 필요한 정보를 얻을 수 있습니다.

    • 멍단비
      참가자
      • 글작성 : 10
      • 답글작성 : 98

      잘봤습니다~

    • 야곰
      키 마스터
      • 글작성 : 37
      • 답글작성 : 579

      좋은 글 고맙습니다!

      Parameter는 Codable 사용이 불가능한가요? 만약 불가하다면 Parameter의 Key는 하드코딩 하지 않는 것이 실수를 줄일 수 있습니다 🙂

      • 멍단비
        참가자
        • 글작성 : 10
        • 답글작성 : 98

        제가 초보라 좀만 더 추가 설명이 가능하실까요 야곰님 ㅎㅎ

        그 이해가 잘 안되는부분이,, Parameter는 Codable 사용이 불가능한가요? 라는 말이 무슨 뜻인지 모르겠어요. 기초가 없어서..^^;;

        그리고 Parameter의 Key는 하드코딩 하지 않는 것이 말씀은 그러면 요구하는 파라미터별로 enum이나 struct로 따로 만들어서 쓰라는 말씀이신가요 ?


        @yagom

        • 야곰
          키 마스터
          • 글작성 : 37
          • 답글작성 : 579

          1)
          보니까 주고받는 데이터는 JSON 데이터를 사용하는데, Parameter는 그냥 Dictionary를 사용하는 것 같아서요.
          구조체 등으로 매개변수 구조를 미리 구현해두고 Codable로 인코딩해서 매개변수를 붙여주면 하드코딩 하지 않을 수 있어서 더 안전할 것 같아서요.
          애플의 Encoding and Decoding Custom Types 글은 보셨겠지만, 다시 링크 남깁니다.

          2)
          네, 위 이야기에 이어지는 이야기죠. 말씀하신 것처럼 enum 혹은 struct 등으로 미리 만들어두면 타이핑 오류로 인해 문제가 발생할 가능성이 현저히 줄죠.

          • 이 답변은 야곰에 의해 4 years, 7 months 전에 수정됐습니다.
          • 멍단비
            참가자
            • 글작성 : 10
            • 답글작성 : 98

            친절한 답변 감사합니다. 퇴근하고 집에가서 봐볼게요 ~!

        • i참
          참가자
          • 글작성 : 1
          • 답글작성 : 10
          extension Encodable {
            func asParameters() throws -> Parameters? {
              let data = try JSONEncoder().encode(self)
              let params = try JSONSerialization.jsonObject(
                with: data,
                options: .allowFragments) as? Parameters
              return params
            }
          }
          
          ...
          struct FooParameters: Encodable {
          ...
          }
          
          ...
          let parameters = try? fooParameters.asParameters()
          
          ...
          Alamofire.request ....
          

          이런식으로 사용해서 하드코딩을 줄일 수 있겠네요.

          • 이 답변은 i참에 의해 4 years, 7 months 전에 수정됐습니다.
          • 이 답변은 i참에 의해 4 years, 7 months 전에 수정됐습니다.
          • 이 답변은 i참에 의해 4 years, 7 months 전에 수정됐습니다.
          • 이 답변은 i참에 의해 4 years, 7 months 전에 수정됐습니다.
          • 이 답변은 i참에 의해 4 years, 7 months 전에 수정됐습니다.
          • 이 답변은 i참에 의해 4 years, 7 months 전에 수정됐습니다.
          • 이 답변은 i참에 의해 4 years, 7 months 전에 수정됐습니다.
          • 멍단비
            참가자
            • 글작성 : 10
            • 답글작성 : 98

            친절한 예시 감사합니다. 하다가 모르는 것 있으면 더 여쭤볼게요~ 😄

2 답변 글타래를 보이고 있습니다
  • 답변은 로그인 후 가능합니다.

logo landscape small

사업자번호 : 743-81-02195
통신판매업 신고번호 : 제 2022-충북청주-1278 호
고객센터 : 카카오톡채널 @yagom