-
GraphQL아주 조금만 살펴보기 - ReactWeb Dev/8. 메모 2021. 6. 5. 00:58728x90
오늘도 좀 쉬는김에 GraphQL쪽을 더 보기로 했다. GraphQL이 페이스북 팀에서 처음 고안됬을때는 UI에서 바로 사용할 수 있는 형태로 데이터를 서버에서 뽑아올려고 했던건데, 지금은 GraphQL은 그보다 훨씬 많은 것들을 하고있다고한다. 오랜 짬이 있는 분은 React에서 GraphQL을 어떻게 쓰고 있는지, 캐슁 전략 등에 대해서 좀 개괄적으로라도 알게되면 좋겠다는 목표를 가지고 세미나를 들었다.
공부 자료
https://frontendmasters.com/courses/client-graphql-react/
- Rick and Morty Playground: https://rickandmortyapi.com/graphql
- rick and morty API https://rickandmortyapi.com/
알게된 내용 간략하게 정리
- operation name을 줄 수가 있다.
이런식. 클라이언트 사이드 Query나 Mutation에 unique name을 주면 이걸로 클라이언트 사이드 캐슁이다, 인덱싱 등을 처리하게 된다. 이름이 없으면 익명함수처럼 동작하는 것.
- 캐쉬처리가 가능하다.
https://www.apollographql.com/docs/react/caching/cache-configuration/
일단 데이터를 query를 하든, mutation을 하고 응답을 받아오든간에 id는 무조건 가지고 있는 것이 좋다. 왜냐하면 기본적으로 Apollo가 graphql쿼리를 인메모리 캐쉬에 저장하기 때문이다. 이때 id기준으로 얘가 업데이트 된걸 처리를 하는데, 어떤 쿼리 결과의 리스트로 pets가 있고, 그 mutation으로 pets을 추가했다면 그건 자동으로 기존의 pets에반영이 안된다. 그부분을 manual하게 정의를 해주어야한다.
const ALL_PETS = gql` query AllPets { pets { id name type img } } `; const NEW_PET = gql` mutation CreateAPet($newPet: NewPetInput!) { addPet(input: $newPet) { id name type img } } `;
이렇게 하나의 쿼리랑 뮤테이션이 있다고 하면,
export default function Pets() { const [modal, setModal] = useState(false); const { data, loading, error } = useQuery(ALL_PETS); const [createPet, newPet] = useMutation(NEW_PET, { update(cache, { data: { addPet } }) { const data = cache.readQuery({ query: ALL_PETS }); cache.writeQuery({ query: ALL_PETS, data: { pets: [addPet, ...data.pets] }, }); }, }); const onSubmit = (input) => { setModal(false); createPet({ variables: { newPet: input } }); };
apollo에서 제공하는 hooks를 통해서 쿼리를 보내고, mutation도 보낼수가 있다(useQuery, useMutation 사용법)
이때 useMutation의 두번째 인자에 옵션을 줄수가 있는데, 여기에 update가 되었을때의 동작을 정의할 수 있다. [상세보기]
위의 방식은 일단 ALL_PETS쿼리로 날려서 가져왔던 데이터를 cache.readQuery로 읽어온뒤, redux에서 immutable하게 변경하는 것처럼, addPet을 붙여주는 것이다. 이건 사용을 좀더 해보면서 익히면 좋을 것 같은데, 캐쉬처리방법이 엄청나게 복잡한건 아닌데, 전략은 잘 잡아야할 것 같다.
- optimisticResponse 설정도 가능하다.
const onSubmit = (input) => { setModal(false); createPet({ variables: { newPet: input }, optimisticResponse: { __typename: "Mutation", addPet: { __typename: "Pet", id: "new-1", name: input.name, type: input.type, img: "http://img.com", }, }, }); };
이런식으로 optimistic ui를 쉽게 구현할 수 있다. 어떤 response가 올지 대강 형태만 맞춰서 정해놓으면 일단 그거부터 ui에 바로 보여준다.
- 로컬 state도 관리할 수 있다
API와 관련된 데이터 외에도 apollo client는 앱에서 발생하는 로컬 state도 관리할 수 있다. Redux에 저장하는걸 여기다 저장할 수 있다는 말. 이때 서버에서 Schema를 작성하는것 처럼, client를 위한 schema를 작성해야한다.
const PETS_FIELDS = gql` fragment PetsFields on Pet { id name type img owner { id age @client } } `; const ALL_PETS = gql` query AllPets { pets { ...PetsFields } } ${PETS_FIELDS} `; const NEW_PET = gql` mutation CreateAPet($newPet: NewPetInput!) { addPet(input: $newPet) { ...PetsFields } } ${PETS_FIELDS} `;
후기
좀 점차 더많이 쓸거같다! 재밌는거같고, 잘만쓰면 편할거같다. 개인적으로 하는 프로젝트위주로 많이 도입을 해보면 좋을 것 같다. directive 쪽은 간단하게만 봤는데, 계속 써봐야할거같다. 그래도 클라이언트의 상태까지 통합해서 관리할 수 있다는 것은 좋은 것 같다. 캐쉬처리도 되는건좋은것 같은데, 꼬이기시작하면 머리가 터질일도 만들어지겠구나 싶긴하다. 다음에는 이걸 적용해서 앱을 한번 만들어봐야겠다.
'Web Dev > 8. 메모' 카테고리의 다른 글
간단 메모 - 렌더 트리, 크리티컬 렌더링 패쓰 (0) 2021.06.14 간단메모 - 리페인트와 리플로우 (0) 2021.06.14 GraphQL아주 조금만 살펴보기 - Node.js (0) 2021.06.03 Json에서 Type 바로뽑아주는 사이트 (0) 2021.06.02 Tailwind css로 초간단 Dropdown 메뉴 구성하기 (0) 2021.06.02