Enjoy Programming

[Apollo] Multiple lazy query - 쿼리 요청 여러번 보내기. 본문

GraphQL

[Apollo] Multiple lazy query - 쿼리 요청 여러번 보내기.

LEETAEEON 2022. 12. 10. 20:47

그동안 개발하면서 주로 사용한 fetch api는  주로 apollo의 useQuery, useMutation, useLazyQuery 와
reactQuery 의 useQuery, useMutation, 등이다. 회사가 graphql을 주로 쓰다보니 rest는 주로 공공 api칠때나 뭐 그럴때 빼고는 쓸일이 없다..

 

근데 이번에 회사 사이트의 기능중 좀 큰 scale을 가진 기능들이 api가 대대적으로 변경이 되었다...

기존에는 한페이지에서 bulk api를 통해서 한번에 가져온 후 client에서 해당 데이터를 전처리 및 가공해서 페이지에 그렸는데

이번에 바뀌면서 결국 한페이지에서 많게는 20~30번 사이의 fetch를 하게 되었다..

 

그동안 위 fetch api를 쓰면서 한페이지에서 많아야 4~5개 정도의 api를 호출 했기 때문에

멀티로 쿼리를 날리는 것에 크게 신경쓰지 않았다. 그리고 graphql서버는 병렬 처리 여러개의 쿼리를 날리더라도

병렬 처리를 하기 때문에 크게 신경쓸 것도 없었다..

 

근데.. ㅠㅠ 왜 바뀌어서.. 예를들면 하나의 지수를 보여주는데 많게는 20개의 route별 지수가 있다.

이걸 각각으로 api를 치게 만든것이다...

이런 코드를 20개를 만들어야 하는 것이다.... ㅠㅠ 얼마나 귀찮고 얼마나 가독성 떨어지는 코드인가..... 수정할때 어떤게 어떤 쿼리를 날린건지 어떻게 알것인가...

 

그리고 그걸 차트에 그리려면 전부 가져와서 다시 차트라이브러리에 들어가는 데이터형태에 따라 다시 분리 병합 하는 코드를 짜서 전처리 가공을 해줘야 한다 ㅠㅠ 아무튼 그건 그거고

 

자 머리를 잘 굴려보자 해서 처음에는 useLazyQuery의  인스턴스인 fetch 함수를 promiseAll로 돌려서 20개를 한번에 가져오자 생각했다. 올레! fetch를 한다... 근데... fail인게.. 이상하게 병합하는 과정을 보니 결국 마지막 fetch데이터로 20개가 다 덮어써져 있는것이다..

 

왜일까.. 일단 한두달 정도 지난 일이라 참고한 사이트는 잊었지만 원인은 lazyquery를 뜯어보면 fetch 시 해당 query의 flag를 설정해준다 그리고 client cache에서 해당 flag name을 통해 인식을 하도록한다.

근데 이걸 여러개의 쿼리를 반복적으로 돌려서 fetch 함수를 돌려쓰면 여러번은 돌아가지만 결국 flagname이 뒤에껄로 덮어져서

마지막껄로 쿼리를 기억하게 되고 데이터도 덮어쓰게 되는 것이다. ㅠㅠ 그럼 어찌한다..

그냥 리티럴로 쿼리문 짜서 다보내야하는건가... 그런데 유레카!! client.query라는게 있었다 저걸 쓰면 되는 거였다...

 

말주변이 없기에 간단히 위 코드로 대체한다. 현재 사용중인 fetch hook이다. 수정은 이루어 졌지만 골조는 같다

우선 queryList 객체 배열을 만들어주고 map을 돌려서  fetch를 한다. 이때 useLazyQuery의 fetch instance가 아닌

useApolloClient로 받은 client 객체의 query method를 이용한다. 사용법은 뭐 쉽다 argument로 option들을 넣어주면 된다.

query 와  variables를 넣어주면 된다 상세 내용은

전부 함수로 짜여져 있어서 설명하기 좀 그렇지만 아무튼!!! 이렇게 쓰면 lazyquery의 instance를 사용해서 생겼던 문제가 해결된다.

원리는 말로 설명을 잘 못하고 완벽하게 아직 정확한 해당 method구조를 파악하진 못해서 설명이 힘들지만 

 

아무튼! apollo client를 이용해서 한번에 수십개의 쿼리를 대량으로 날려야할 때 고민이 있는 분이라면 이렇게 사용하는 것도 있다고 말씀드립니다.!