- Published on
ApolloClient OnError 에 대해서
- Authors
- Name
- 길재훈
ApolloClient Error Link
newWork 단계에서
error를 검증하고handling하는API모음이다.
Error Link 는 onError 라고 하는 Custom Logic 이 존재한다.
onError 는 GraphQL 또는 network error 가 발생할때 작동한다.
onError 는 Callback 함수를 하나 받는데, 만약 작업도중 많게는 하나 혹은 여러개의 error 를 반환한다면 이 함수가 실행된다.
onError 의 Callback 함수는 다음처럼 생겼다.
import { onError } from '@apollo/client/link/error'
const errorLink = onError(({ graphQLErrors, networkError }) => {
if (graphQLErrors)
graphQLErrors.forEach(({ message, locations, path }) =>
console.log(`[GraphQL error]: Message: ${message}, Location: ${locations}, Path: ${path}`)
)
if (networkError) console.log(`[Network error]: ${networkError}`)
})
onError 를 가져오기 위해서는 @apollo/client 에서 /link/error 에 존재한다.
그리고 structuring assignment(구조분해할당) 을 통해 해당 onError 를 가져온다. 가져온 Callback 에서 다음과 같은 인자를 받는다.
| Name/Type | Description |
|---|---|
| opreation: Operation | 오류를 발생한 GraphQL 의 세부정보 |
| response: ExecutionReulst | server 를 통한 GraphQL 결과이다.Docs 에서는 chain 을 통해 다음 link 로 타고 내려가 terminating link 에 더 가까운 link 에 의해 전달된다고 되어있다.해당 내용은 지식이 더 필요할듯 싶다.response 는 수정이 가능하다고 명시되어 있다! |
| graphQLErrors: ReadonlyArray < graphQLErrors > | 만약 에러가 존재한다면, 실행중에 발생한 에러를 Array 객체로 내보낸다. |
| networkError: Error | serverError | ServerParseError | 만약 에러가 존재한다면, 작업 실행중 network error 가 발생된것이다. |
| forward: function | 이 function 은 연결되어진 chain 을 타고 내려가 다음 link 를 호출한다.onError 의 콜백에서 return forward(operation) 를 호출하면,구독할 upstream link 에 대한 새로운 observable이 반환된다. |
지금 이 내용상에서 보면, chain 에 대해서 설명하고 있는것이 눈에 띈다. onError 를 정확히 인지하고 사용하기 위해서는 다음의 몇가지 키워드를 바로 잡아야 한다.
- chain
- link
- operation
- forward
- observable
chain 과 link
Apollo Link 라이브러리는
GrapyQL server와Apollo Client사이의data흐름을custom하게 도와주는 도구이다.
Apollo Link 를 통해 client network 동작을 순서대로 실행되는 link 가 서로 이어져 있는데 이렇게 이어져 있는 구조를 chain 이라 한다.
아폴로 링크는 다음과 같은 구조로 되어 있다.
각각의 Link 들은 각 역할을 수행하도록 이어져 있으며, 이전 Link 의 operation 을 다음 Link 에 전달한다.
이러한 구조라면, 전송될 data 를 각 역할마다 따로 로직을 구성하여 통합할 수 있어 좋은 구조라는 생각이 든다.
각 Link 는 사용자가 직접 지정하여 만들수도 있으며, ApolloClient 에서 제공해주는 Link 를 사용하여 만들 수 있다.
이때 가장 마지막에 있는 Link 를 terminating Link 라고 부르며, GraphQL Server 에 Request 하는 역할을 하며, Link 의 Chain 은 종료된다.
Request 가 아닌 Server 로 부터 Response 할때는 위의 다이어그램의 역순으로 Link 가 이어진다.
ApolloClient 가 GraphQL Server 에 보낼때 용어를 Down Chain 이라고 부르며,GraphQl Server 가 ApolloCient 에 보낼때는 Up Chain 이라고 한다.
Docs 를 보면서 이 용어가 꽤나 자주나온다..
Link 에 대한 자세한 내용은 1페이지 를 할애할 정도로 양이 많은 상황이라, 이부분은 추가적으로 내용을 정리해야 할것 같다.
여기서 중요한 부분은 Apollo Client 에서 GrapyQL Server 사이의 Network 흐름을 처리하기 위해 Link libary 를 사용하며, Link library 는 각 Link(수행할 역할) 을 Chain 형식으로 연결지어 두었는것이다.
operation 과 forward
위의 Link 에 대해 대략적으로 살펴보았다. Link 는 Network 조작을 위해 존재한다고 했으며, onError 는 Network 상 어떠한 Error 가 발생했을때, Catch 하여 알려준다.
즉, onError는 Apollo Client 에서 제공해주는 Link 이다. Link 는 호출내부에 callback 함수를 받는데, 이를 request handler 라고 부른다.
먼저 code 를 살펴보도록 하자.
import { onError } from '@apollo/client/link/error'
const errorLink = onError(({ graphQLErrors, networkError, operation, foword}) => { ... })
위 코드를 보면 callback 함수의 인자 중 operation 과 forward 가 보일것이다.
request handler 는 다음의 인자를 기본적으로 제공한다.
- operation
- forward
물론, onError 의 callback 은 다른 인자를 갖기도 하지만 Link 이기에, request handler 이기에 위 인자를 사용할 수 있다.
Docs 에서는 위 인자는 다음의 property 를 제공한다.
operation
operation
| Name | Description |
|---|---|
| query | 발생하는 작업을 설명하는 DocumentNode |
| variables | 작업과 함께 전송하는 GraphQL variables 의 map |
| operationName | 만약 이름이 있다면 query 의 이름, 아니면 null |
| extentions | server 로 보낼 확장 data 가 저장된 map |
| getContext | 요청의 context 를 리턴하는 함수이 context 는 수행작업을 정하기 위해 links 에서 사용할 수 있다. |
| setContext | 새로운 context 객체 또는 함수를 가지는 함수, 함수일때 이전 context 를 인자로 가질수 있고 새로운 context 를 return 할 수 있다. |
forword
link 의 request handler가 done 일때 forward를 반환한다.
만약
link가terminating link라면 제외
return forward(operation) 은 link chain 에서 다음의 link에 전달된다.
만약
customLink가return forward(operation)을 반환하지 않으면, 다음 링크가 실행되지 않고terminating link로 인식하여 종료된다. 그러므로 연결된 다른link가 실행되지 않을 수 있으니 주의하자
observable
우리가 사용하고 있는 forward 의 return 타입은 observable 타입이다. 여기서 observable 타입이 무엇인지 알 필요가 있다.
observable 는 데이터를 비동기로 처리해 변화에 유연함을 주는 프로그래밍 패러다임이라고 한다.
이러한 observable 은 reactive programing 을 하는데 사용되는 pattern 중에 하나이다.
reactive programing 이란, 어떠한 데이터가 변화되었을때, 즉각적으로 반응하여 처리하는 프로그램 패러다임을 뜻한다.
reactive programing 이란 무엇인지 조금더 개념을 살펴보아야 겠다.
Reactive Programing 개념
observable 은 RP(reactive programing) 에서 producer 라고 부르며, observable 의 상태를 관찰하고 반응하는 observer 는 consumer 라고 부른다.
이렇게 prodcuer 와 consumer 가 구분되어 처리되는것을 통해 각 상태의 분리가 가능하며, 불변성역시 보장된다 .
producer 가 데이터를 받아 consumer 로 보내는데, 이렇게 보내는 흐름을 stream 이라고 표현한다.
이러한 스트림은 pipe line 을 통해 이어지는데, 여기서 pipe 는 producer 로 부터 받은 원본데이터를 순차적으로 가공하여 consumer 로 보내주는 역할을 한다. 그리고 그 받은 데이터를 consumer 가 소비(데이터를 사용)한다.
즉, producer 는 마치 consumer 가 수신할 알림을 보내는 역할을 한다. consumer 는 producer 로 부터 받은 모든 이벤트에 대해 비동기로 반응하기에, single thead 인 nodejs 에서 동기적으로 멈출일이 없다.
이는 비동기 프로그래밍 에서의 이점을 살리며 처리하는 방식이다.
이러한 비동기 로 인해 RP 는 data fetching 에 이상적으로 작동 가능하다. 이는 대규모 이벤트 처리 가 일어나더라도, 멈추는 일 없이 처리 가능하다는 것이다.
RP 에서의 중요한 부분은, comsumer 가 subscription 하지 않으면 동작하지 않는다는 것이다.
subscription 된 consumer 가 존재한다면, subscription 된 모든 consumer 들이 공통적인 pipe 를 통해 동일한 처리가 이루어진다.
tc39/proposal-observable 에서 javascript 의 observable 이 어떻게 만들어지고 작동하는지 설명해준다.
observable 에 대한 부분을 알기 위해서는 더 많은 공부가 필요할것 같다. 추푸 RxJS 를 추가적으로 공부할 계획이다.
다시 onError 로 돌아와서..
forward: function 에서의 문구를 다시 보자
function은 연결되어진chain을 타고 내려가 다음link를 호출한다.
onError의 콜백에서return forward(operation)를 호출하면,
구독할upstream link에 대한 새로운observable이 반환된다.
이 문구상에서 chain 은 Link 객체가 연결되어진 것을 뜻하며, onError 의 forward 를 통해 다음 Link 에 전달된다.
이때 중요한 것은 OnError는 서버로부터 받은 상태값이기에, Downstream 이 아닌 Upstream 이라는 것이다,
이렇게 반환된 결과값은 forword 에 의해 observable 타입으로 반환되는것을 알수 있게 되었다.