Fragments
한마디로 Fragments
란 쿼리의 일부분을 재활용 가능한 단위로 나눠놓은것이다.
이 예제에서 우리는 blog-post.js
라고 하는 템플릿 파일을 사용할것이다.
이 템플릿 파일로 블로그의 게시글들을 찍어낼수 있다.
템플릿 파일 안에는 포스트를 불러오기 위한 쿼리와 그걸 보여주기 위한 마크업이 존재한다.
포스트 내용을 불러오기 위한 GraphQL
쿼리는 다음과 같다.
export const query = graphql`
query($id: String!) {
post: postsJson(id: { eq: $id }) {
title
slug
content
publishDate(formatString: "MMMM DD, YYYY")
tags
author {
slug
name
biography
}
}
}
`;
위 쿼리를 살펴보면 post
를 위한 영역과 author
를 위한 영역이 분리되어 있다. 위 쿼리를 다음과 같이 두개의 프래그먼트
로 쪼갤수 있다.
export const query = graphql`
fragment postFields on PostsJson {
slug
title
content
publishDate(formatString: "MMMM DD, YYYY")
tags
}
fragment authorFields on AuthorsJson {
slug
name
biography
}
query($id: String!) {
post: postsJson(id: { eq: $id }) {
...postFields
author {
...authorFields
}
}
}
`;
postFields
와 authorFields
라고 하는 두개의 프래그먼트로 나눴고 쿼리문 안에서 두개의 프래그먼트를 스프레드 연산자를 통해서 뿌려주고 있다.
이제 포스트에 대한 쿼리문 작성은 끝났다.
그런데, 만약에 author
의 정보를 보여주기 위한 쿼리를 또 작성해야 한다고 생각해보자.
이 쿼리문은 post
를 위한 쿼리문과 별로 다를게 없을것이다. 왜냐면 두 쿼리에서 필요한 정보가 거의 비슷할것이기 때문이다.
다음은 blog-author.js
템플릿에서 작성자의 정보를 보여주기 위한 쿼리문이다.
export const query = graphql`
query($id: String!) {
post: authorsJson(id: { eq: $id }) {
slug
name
biography
posts {
title
slug
content
publishDate(formatString: "MMMM DD, YYYY")
tags
}
}
}
`;
Gastby에서 fragments를 내보내기
이 쿼리문에서 프래그먼트로 쿼리를 분리한다고 해도 아까 작성한 post
의 프래그먼트들과 별로 다를것이 없을것이다.
그러니까 author
를 위한 새로운 프래그먼트를 또 만들지 말고 아까 만들어둔 프래그먼트를 가져와서 재사용하자.
gastby
공식문서에 있는 graphql
부분을 보면 fragments
에 대해서 다음과 같이 설명한다.
Fragments are a way to save frequently used queries for re-use. To create a fragment, define it in a query and export it as a named export from any file Gatsby is aware of. A fragment is available for use in any other GraphQL query, regardless of location in the project. Fragments defined in a Gatsby project are global, so names must be unique.
대충 해석해보자.
- 프래그먼트는 쿼리문 안에서 작성되어야 한다.
- 프래그먼트는
named export
방식으로 내보내져야한다. - 프래그먼트는 프로젝트 위치에 상관없이 다른
GraphQL
쿼리문에서 재사용가능하다. - 프래그먼트는
Gastby
프로젝트에서 글로벌로 세팅되기 때문에, 이름이unique
해야한다.
그래서 어디에 프래그먼트를 작성해야 하고, 어떤식으로 써야 하는데??
blog-post.js
와 blog-author.js
라고 하는 두개의 템플릿 파일에서 아까 만든 두개의 프래그먼트를 사용하기위해, src
에 fragments.js
라고 하는 파일을 생성한다.
프래그먼트를 하나의 파일에 집중시킬건지 분산시킬건지는 너의 팀과 프로젝트에 따라 알아서 결정해라.
fragments.js
파일에 다음과 같이 두개의 프래그먼트를 붙여 넣자.
export const postFields = graphql`
fragment postFields on PostsJson {
slug
title
content
publishDate(formatString: "MMMM DD, YYYY")
tags
}
`;
export const authorFields = graphql`
fragment authorFields on AuthorsJson {
slug
name
biography
}
`;
다시 한번 말하지만 프래그먼트의 이름은 유일해야한다.
global
하게 프래그먼트가 export
되기 때문에 프로젝트 내의 어떤 쿼리문 안에서도 이 프래그먼트를 재활용 할 수 있다.
필드가 몇개 없는 부분을 프래그먼트로 만드는건 오히려 가성비가 떨어진다. 수십, 수백개의 필드가 있는 쿼리의 일부를 프래그먼트화 한다면 아주 가성비가 좋은 분리가 될 수 있다.