GraphQL: 페이스북에서 만든 API 를 위한 쿼리 언어이며, 타입 시스템을 사용하여 쿼리를 실행하는 서버사이드 런타임이다.REST API는 보통 여러 엔드포인트 를 가지며 각각의 엔드포인트가 동일한 응답을 반환 하는 반면,GraphQL은 보통 하나의 엔드포인트 를 가지며 요청할 때 사용하는 쿼리에 따라 다른 응답 즉, 원하는 데이터(response)만 받을 수 있다.
REST API
GraphQL
GraphQL 은 아래의 구조를 가진다. (해당 id를 가진 todo의 id, text, completed 를 조회하겠다는 쿼리)
query ($id: ID!) {
todo(id: $id) {
id
text
completed
}
}
Apollo-Client:GraphQl기반의 라이브러리로,GraphQL을 사용하여 데이터를 관리할 수 있는 상태관리 라이브러리이다. (Redux대체 가능)
아래의 명령어를 통해 설치해준다.
$ yarn add @apollo/client
먼저, 아래의 코드를 통해 Client 를 생성해준다.
import { ApolloClient, InMemoryCache } from "@apollo/client";
const Client = new ApolloClient({
uri: {Server Url},
cache: new InMemoryCache(),
});
export default Client;
App 을 Provider 로 감싼 후 생성한 Client 를 넘겨준다.
// index.tsx
import { ApolloProvider } from "@apollo/client";
...
root.render(
...
<ApolloProvider client={Client}>
<App />
</ApolloProvider>
...
);
서버에서 정의된 스키마를 바탕으로 Apollo-Client hook 에 넣어줄 쿼리들을 먼저 작성한다.
// TodoList 가져오기
export const GET_TODO_LIST = gql`
query {
todoList {
id
content
completed
}
}
`;
// Todo 생성
export const CREATE_TODO = gql`
mutation ($content: String!) {
createTodo(content: $content) {
id
content
completed
}
}
`;
// Todo 상태 변경
export const TOGGLE_TODO = gql`
mutation ($id: ID!) {
toggleTodo(id: $id) {
id
content
completed
}
}
`;
useQuery hook 과 작성한 gql 을 통해 데이터를 받아올 수 있다.
react-query 와 마찬가지로 여러가지 값을 반환한다.
interface TodoItemType {
id: string;
content: string;
completed: boolean;
}
const { data, loading, error } = useQuery<{ todoList: TodoItemType[]}>(
GET_TODO_LIST
);
console.log(data.todoList) // ~~~
만약, hook 을 사용하지 않는다면 아래의 코드처럼 좀 더 복잡하게 작성해야한다.
const client = useApolloClient();
const [todoList,setTodoList] = useState([]);
client.query({
query: gql`
{
todoList {
id
content
completed
}
}
`
}).then(response => setTodoList(response.data.todoList));
역시 hook 이 편리하다.
useMutation hook 과 작성한 gql 을 통해 POST, DELETE, PUT, PATCH 와 같은 역할을 수행할 수 있다.
refetchQueries 를 통해 mutate 후 refetch 할 수 있고, 성공과 실패해 대한 콜백을 지정해줄 수 있다.
const [createTodoMutate] = useMutation(CREATE_TODO, {
refetchQueries: [{ query: GET_TODO_LIST }],
onCompleted: (data) => {
console.log(data, ' Success :) ');
},
onError: (error) => {
console.log(error, ' Error :( ');
},
});