graph ql의 핵심 개념이라고 볼 수 있을 것 같다. 뭔소린가 싶으면 그냥 학부때 배우는 그래프를 생각해도 좋다. 그 개념이 맞고 이해가 잘 된다.
가장 작은 단위의 뭉텅이 데이터를 Node라고 한다. 작은 단위라고 해서 name: String
나 String
(이건 그냥 타입이다) 이런게 아니라 어떤 의미를 가지게 되는 하나의 객체라고 봐도 될 것 같다.
type User {
name: String!
age: Int!
}
이런 노드 타입을 가지는 실제 데이터들이 연결점없이 둥둥 떠다니게 되는데 얘네를 잡을 수 있게 만들어주는 다리같은게 edge다. 이 edge type의 객체를 통하면 해당 data의 정보와 data를 가리키는 cursor라는 정보를 얻을 수 있다.
이렇게 node와 edge가 연결되어있는 애들을 하나로 묶어주는 구심점 같은 것이 connection이다.(아 갑자기 이거 제대로 설명을 못해서 이렇게.....묶여있는......이난리친거 생각나서 잠다깸) 동일 타입 node들을 모아둔 곳의 진입점이라고 할 수 있다. 이 connection에 연결되어있는 edges들을 받아서 내부의 node를 확인해 나가는 것이다.
connection {
...
edges {
node {
#데이터들
name
age
}
cursor
}
}
이런 커넥션에서 아까처럼 cursor에도 접근할 수 있는데 graph ql은 이를 이용해 커서 기반 페이지 네이션을 아주 적극적으로 지원하고 있다. usePaginationFragment
같이 hook도 제공하고 있다.
usePaginationFragment
커서는 node의 식별 정보라고 생각하면 된다. 참조형 데이터가 주소값을 기억하듯이 커서도 똑같다. 그럼 이를 이용해서 페이지 네이션을 한다는 건 뭘까?
일반적으로 내가 익숙한건 페이지 아래에 번호가 있고
페이스북같은 무한 스크롤이 대표적인 예시다. 데이터들의 가장 마지막에 도착했을 때 더보기 버튼을 누르거나 밀어올리면 그 뒤로 데이터들이 더 붙어서 보여지는 형태를 띈다. 이때 가장 마지막에 불러온 커서의 정보를 전달하여 그 뒤로 값을 더 불러온다고 해서 커서 기반 페이지네이션이다. 이전 값을 불러오는 것도 before 와 last를 이용하면 가능하다.
usePaginationFragment
는 useFragment
처럼 fragment와 fregmentRef를 전달하여 데이터를 fetching하고 사용할 수 있게 해주지만 추가로 커서 기반 페이지네이션을 위한 loadNext
, loadPrevious
같은 함수도 같이 반환한다.
const {data, hasNext, isLoadingNext, loadNext} = usePaginationFragment(fragment, fragmentRef)
...
<Button onClick={()=>loadNext(3)}>click</Button>
이를 이용하면 first, last, after: endCursor 같은 것들을 직접 입력하지 않아도 pagination을 할 수 있다.
물론 usePaginationFragment
를 이용하지 않아도 직접 구현할 수 있지만 사용하길 권장하는 잘 만들어진 페이지네이션 훅을 사용하지 않을 이유는 없다.
usePagination
에 들어가는 fragment들은 @refetchable
directive를 포함해야한다. pagination을 위해 상위의 query를 전체 refetch하는 것이 아니라 그 fragment 부분만 query를 새로 만들어서 refetch 하기 때문이다. 정말 페이지네이션을 위해 새로 업데이트 해야하는 정보들에 대해서만 refetch를 진행한다.
이때 넘겨주는 queryName
은 정말 query이름으로 사용되기 때문에 똑같이 유니크하게 작성해야한다.
@connection directive 또한 필요한데 pagination을 한다는 것이 하나의 특정 데이터만 불러와서 관리하는 것이 아니기 때문에 불러온 데이터들을 묶어둘 것이 필요하다. 바로 그게 connection이다. 이 directive를 사용해 edge를 묶어둘 connection key를 지정하게 되고 relay는 새로 불러온 데이터들을 이 key를 가지는 connection에 연결해준다.
// react-relay
fregment SomeComponent_Examples on Examples
@refetchable(queryName: "SomeComponentRefetch") {
examples( ~~ )
@connection(key: "SomeComponent_Examples") {
edge {
node {
...
}
}
}
}
https://www.apollographql.com/blog/graphql/explaining-graphql-connections/