안녕하세요 devport 입니다. 오늘은 Apollo Link 라이브러리를 이용해서 GraphQL로 CRUD시에 매칭되는 로딩 및 완료 팝업 문구를 띄울수 있는 방법에 대해서 알아보도록 하겠습니다.
Apollo Link?
Apollo Link 라이브러리는 Apollo Client와 GraphQL 서버 사이의 데이터 흐름을 사용자가 정의 할 수 있습니다.
GraphQL의 Query 또는 Mutation을 수행할때에 사용자가 정의한 Link가 순차적으로 실행되며 Link를 통해 해당 데이터를 제어할 수 있도록 구현도 할 수 있습니다.
Apollo Client는 기본적으로 사용되는 Apollo Link 중 HttpLink를 통해서 원격서버에 요청 작업을 전달합니다.
HttpLink 뿐만 아니라 다양한 Link들이 존재합니다. Apollo 공식사이트에서 설명하는 방법 및 오픈소스(github)에서 다양한 형식의 Link들을 찾아 볼 수 있습니다.
Apollo Link 라이브러리을 이용해서 에러 및 로딩 처리를 제어하는 부분에 대해서 어떻게 구현하는지 알아보도록 하겠습니다.
Apollo Link 설정
저는 이번 포스팅에서 3개의 Link를 거쳐 Graphql 서버에 전달되는 부분에 대한 처리 로직을 설계하였습니다.
import ApolloClient from 'apollo-client'
// Apollo Link 모듈
import { ApolloLink } from 'apollo-link'
import { HttpLink } from 'apollo-link-http'
import { onError } from 'apollo-link-error'
// 기타 모듈
import _ from 'lodash'
const errorLink = function () {}
const loadingLink = function () {}
const httpLink = new HttpLink({
uri: 'http://localhost:3000/graphql'
})
const link = ApolloLink.from([
errorLink,
loadingLink,
networkLink
])
const apolloClient = new ApolloClient({
link: link,
cache: new InMemoryCache({})
})
Query 및 Mutation이 요청 및 응답시에 errorLink -> loadingLink -> HttpLink가 순차적으로 실행되도록 선언하였습니다. 이제 errorLink와 loadingLink를 어떻게 구현하였는지 살펴 보도록 하겠습니다.
errorLink 구현
errorLink는 apollo-link-error 모듈을 통해 GraphQL 또는 Network에서 발생하는 에러를 처리할 때 사용하도록 구현하였습니다.
const onErrorLink = onError(({ graphQLErrors, networkError }) => {
if (graphQLErrors) {
let msg = ''
graphQLErrors.map(({ message, locations, path }) => {
msg += `${message}\n`
})
window.$notify.error(msg)
}
})
저는 이 Link로 에러가 발생할 경우 GUI 에 출력 될 수 있도록 하였습니다.
loadingLink 구현
loadingLink는 새로운 사용자 정의 Link를 추가 하여 요청 및 응답처리를 각기 다르게 처리 가능하도록 구현하였습니다.
const dictLoading = {
Read: '가져오는 중...',
Create: '등록 중...',
Update: '변경 중...',
Delete: '삭제 중...'
}
const dictMsg = {
Read: '검색 되었습니다.',
Create: '추가 되었습니다.',
Update: '수정 되었습니다.',
Delete: '삭제 되었습니다.'
}
const loadingLink = new ApolloLink((operation, forward) => {
const opName = _.get(operation, 'operationName', '')
if (dictLoading[opName]) window.$loader.show({ state: dictLoading[opName] })
return forward(operation).map((data) => {
if (_.has(data, 'errors')) return data
if (dictMsg[opName]) {
window.$notify.info(dictMsg[opName])
}
window.$loader.hide()
return data
})
})
전송, 응답시에 operation의 이름을 매치하여 로딩 문구가 출력되며 응답이 올 경우 결과 팝업이 출력되도록 구현하였습니다.
forward 함수는 GraphQL 요청에 대한 응답시에 호출 됩니다.
// 조회 Query
gql`
query Read {
allBooks {
id
title
author
}
`
// 추가 Mutation
gql`
mutation Create ($title: String, $author){
createBook(title: $title, author: $author) {
id
title
author
}
}
`
// 수정 Mutation
gql`
mutation UPDATE ($id: String, $input: inputBook) {
updateBook(id: $id, input: $input) {
id
title
author
}
}
`
// 삭제 Mutation
gql`
mutation DELETE ($id: String) {
deleteBook(id: $id) {
id
title
author
}
}
`
operation의 이름은 Query 및 Mutation의 이름이며 CRUD 형식인 정보와 매치 되는 문구가 출력될 수 있도록 처리를 하였습니다.
'개발바닥 > GraphQL' 카테고리의 다른 글
[개발] GraphQL - DataLoader로 최적화 하기 (0) | 2021.11.10 |
---|---|
[개발] GraphQL - 관련 Tools (2) | 2021.11.10 |
[개발] GraphQL - Apollo Client Cache (0) | 2021.11.10 |
[개발] GraphQL - Vue + Apollo + GraphQL (0) | 2021.11.10 |
[개발] GraphQL - Apollo 웹 서버 구축하기 (0) | 2021.11.10 |