AWS Lambda에서 query string array 사용하기

leejh3224·2020년 7월 24일
0
post-thumbnail

AWS Lambda 엔드포인트에서 아래 처럼 query string을 통해 array 형태의 값을 전달하게되면 예상과는 달리 맨 마지막 값만 사용됩니다.

클라이언트 요청 GET my-awesome-api?a=1&a=2&a=3
--
실제 요청 GET my-awesome-api?a=3

이러한 사실은 AWS 문서에서도 찾을 수 있습니다.

If you do not enable multi-value header syntax and a header or query parameter has multiple values, 
the load balancer uses the last value that it receives.

그렇기 때문에 우리에게는 두 가지 선택지가 있습니다.

1. event.queryStringParameters 대신에 event.multiValueQueryStringParameters를 참조한다.
2. array를 전달하는 방식을 변경한다.
(a[0]=1&a[1]=2와 같이 전달할 경우 서로 키가 다르기때문에 모든 값이 온전하게 전달된다.)

첫번째 방식으로 변경할 경우, 아무런 wrapper 라이브러리 없이 함수를 직접 작성한 경우 단순히 참조하는 대상만 변경하면 됩니다. 만약 aws-serverless-express 라이브러리를 사용한 경우라면 깃허브 이슈를 참조하시기 바랍니다.

이제 두번째 방식인데, 일반적으로 query string에서 array를 표현하는 방식은 크게 세 가지가 있습니다.

1. 같은 키를 반복하는 형식
url?a=1&a=2&a=3

2. json array notation 사용
url?a[]=1&a[]=2

3. json array notation과 함께 인덱스 사용
url?a[0]=1&a[1]=2

4. ,(콤마)로 구분하는 방식
url?a=1,2,3,4

통상적으로 1번 혹은 2번 방식이 많이 사용되지만 1, 2번 방식을 사용할 경우 array로 전달한 파라미터가 스트링이 되거나 array의 일부만 전달되는 현상이 나타날 수 있습니다.

그렇기 때문에 팀의 규칙 혹은 개인적인 선호에 따라서 3번 혹은 4번 방식을 사용할 수 있습니다.

이제 라이브러리 선택 문제입니다.

node.js 환경에서 query string 파싱/직렬화(serialization)를 위한 라이브러리들 중 가장 유명한 두 라이브러리는 qsquerystring(표준 node.js 라이브러리) 입니다.

두 라이브러리에는 많은 차이점이 있지만 그 중 .stringify 메쏘드를 통한 직렬화 결과에서 그 차이가 두드러집니다.

querystring.stringify({ a: [1, 2, 3] }) --> 'a=1&a=2&a=3' (1번 방식)
__
qs.stringify({ a: [1, 2, 3] }) --> 'a[0]=1&a[1]=2&a[2]=3' (기본 3번 방식)

querystring과 달리 두 번째 인자인 options를 통해 다른 방식으로 직렬화하는 것도 가능합니다.

> qs 라이브러리 README에서 발췌
qs.stringify({ a: ['b', 'c'] }, { arrayFormat: 'indices' })
// 'a[0]=b&a[1]=c'
qs.stringify({ a: ['b', 'c'] }, { arrayFormat: 'brackets' })
// 'a[]=b&a[]=c'
qs.stringify({ a: ['b', 'c'] }, { arrayFormat: 'repeat' })
// 'a=b&a=c'
qs.stringify({ a: ['b', 'c'] }, { arrayFormat: 'comma' })
// 'a=b,c'

개인적으로는 위와 같은 차이 때문에 qs 를 좀 더 선호하지만 저러한 기능이 필요하지 않다면 굳이 qs 를 사용할 필요는 없습니다.

다음은 axios 와의 연동입니다.

axiosget/delete 요청 시 param 을 설정에 넘길 수 있습니다.

axios.get('url', { params: a: [1, 2, 3] })

이 때 아무런 설정을 하지 않았다면 아래와 같이 직렬화됩니다.

url?a[]=1&a[]=2&a[]=3

만약 위의 기본 동작을 변경하고 싶다면 configparamsSerializer 를 사용할 수 있습니다.

axios.get('url', {
  params: {
    a: [1, 2, 3]
  },
  paramsSerializer: params => {
    return qs.stringify(params)
  }
})

이제 qs.stringify 를 직접 사용했을 때와 마찬가지로 'a[0]=1&a[1]=2&a[2]=3' 형태로 직렬화할 수 있습니다.

끝까지 읽어주셔서 감사합니다. 😄

profile
다양한 것들을 시도합니다

0개의 댓글