All Articles

쿼리스트링 파싱 함수

이번 프로젝트에서 검색, 필터, 정렬 기능을 위해 쿼리 파라미터를 사용해 api요청을 한 일이 있었다.

path parameter vs query parameter

이 둘은 모두 동적 라우팅을 위해 사용되지만, 패스 파라미터는 특정 리소스 하나를 지정해서 가져오는 경우에 주로 쓰이고 쿼리 파라미터는 페이지네이션이나 필터처럼 기준에 따라 리소스의 일부를 가져올 때 주로 쓰인다.

패스 파라미터는 match.params의 프로퍼티로 담기기 때문에 각각의 값에 접근이 쉽지만, 지정된 파라미터에 값을 모두 전달하지 않으면 (예를 들어 category/:id/:example -> id와 example에 둘다 값을 전달하지 않으면) 라우팅이 올바르게 되지 않는다. 그래서 필터를 쓸 때는 쿼리 파라미터를 쓰는 것 같다. (필터를 체크할 수도 있고 안할 수도 있고~)

다만 쿼리 파라미터는 location.search에 문자열로 한번에 다 담기기 때문에(‘?key=value&key2=value2…‘) 각각의 값에 접근하기 위해서는 따로 분리를 해줘야한다.


프론트에서는 쿼리스트링을 객체로 변환해서 key값으로 사용하다가, 서버에 보내야 할 때 다시 쿼리스트링 형태(‘?=&~~“)로 보내주면 된다. 그래서 쿼리스트링 -> 객체, 객체 -> 쿼리스트링 으로 변환해주는 함수를 util 함수에 저장해놓고 필요할 때 꺼내쓰면 함수 재사용도 높이고, 추상화를 통해 코드 길이도 줄이고! 아주 편했기에 다시 한 번 정리해보고자 한다.

방법은 1. 직접 함수를 만들거나 2. Web API인 URLSearchParams를 사용하는 방법이 있다.

직접 함수 작성하기

// util.js

export const queryToObj = (query) => {
  const [, q] = query.split("?");
  const obj = {};

  q.split("&").map((el) => {
    const [k, v] = el.split("=");
    return (obj[k] = v);
  });

  return obj;
};

export const objToQuery = (obj) => {
  return (
    "?" +
    Object.entries(obj)
      .map((el) => el.join("="))
      .join("&")
  );
};

프로토타입을 사용해서 메소드로 만들어 사용할 수 있는데 그건 요기 참고
파싱 함수를 사용할 수도 있다는 걸 알려주신, 멘토님의 블로그다.


Web API 사용하기: URLSearchParams

new URLSearchParams(queryString)

  • 쿼리스트링을 인자로 넘겨주면 URLSearchParams 객체 인스턴스 반환
  • 쿼리스트링에 대해 작업할 수 있는 메소드 제공
    각 파라미터의 값을 조회, 수정, 삭제
    문자열로 변환 등등
  • 문자열 앞의 ’?’는 자동으로 제거됨

// url이 아닌 "쿼리스트링"을 인자로 전달해야 한다

const params = new URLSearchParams(location.search);

params.get(_key_); // 조회
params.set(_key_, _value_); // 수정
params.append(_key_, _value_); // 추가
params.toString();

URLSearchParams의 메소드를 사용하면 따로 객체로 변환하는 함수를 만들지 않아도 쉽게 파라미터의 값을 읽고 수정할 수 있다.

하나의 파라미터가 다수의 값을 갖는 경우 모든 값이 보존된다는 점이 좋은 것 같다. 객체는 같은 이름의 파라미터가 중복될 수 없기 때문에