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 :( ');
},
});