Published on

ApolloClient OnError 에 대해서

Authors
  • avatar
    Name
    길재훈
    Twitter

ApolloClient Error Link

newWork 단계에서 error 를 검증하고 handling 하는 API 모음이다.

Error LinkonError 라고 하는 Custom Logic 이 존재한다.

onErrorGraphQL 또는 network error 가 발생할때 작동한다.

onErrorCallback 함수를 하나 받는데, 만약 작업도중 많게는 하나 혹은 여러개의 error 를 반환한다면 이 함수가 실행된다.

onErrorCallback 함수는 다음처럼 생겼다.

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/TypeDescription
opreation: Operation오류를 발생한 GraphQL 의 세부정보
response: ExecutionReulstserver 를 통한 GraphQL 결과이다.
Docs 에서는 chain 을 통해 다음 link 로 타고 내려가 terminating link 에 더 가까운 link 에 의해 전달된다고 되어있다.
해당 내용은 지식이 더 필요할듯 싶다.
response 는 수정이 가능하다고 명시되어 있다!
graphQLErrors: ReadonlyArray < graphQLErrors >만약 에러가 존재한다면, 실행중에 발생한 에러를 Array 객체로 내보낸다.
networkError: Error | serverError | ServerParseError만약 에러가 존재한다면, 작업 실행중 network error 가 발생된것이다.
forward: functionfunction 은 연결되어진 chain 을 타고 내려가 다음 link 를 호출한다.
onError 의 콜백에서 return forward(operation) 를 호출하면,
구독할 upstream link 에 대한 새로운 observable이 반환된다.

지금 이 내용상에서 보면, chain 에 대해서 설명하고 있는것이 눈에 띈다. onError 를 정확히 인지하고 사용하기 위해서는 다음의 몇가지 키워드를 바로 잡아야 한다.

  1. chain
  2. link
  3. operation
  4. forward
  5. observable

Apollo Link 라이브러리는 GrapyQL serverApollo Client 사이의 data 흐름을 custom 하게 도와주는 도구이다.

Apollo Link 를 통해 client network 동작을 순서대로 실행되는 link 가 서로 이어져 있는데 이렇게 이어져 있는 구조를 chain 이라 한다.

아폴로 링크는 다음과 같은 구조로 되어 있다.




ApolloLink




각각의 Link 들은 각 역할을 수행하도록 이어져 있으며, 이전 Linkoperation 을 다음 Link 에 전달한다.

이러한 구조라면, 전송될 data 를 각 역할마다 따로 로직을 구성하여 통합할 수 있어 좋은 구조라는 생각이 든다.

Link 는 사용자가 직접 지정하여 만들수도 있으며, ApolloClient 에서 제공해주는 Link 를 사용하여 만들 수 있다.

이때 가장 마지막에 있는 Linkterminating Link 라고 부르며, GraphQL ServerRequest 하는 역할을 하며, LinkChain 은 종료된다.

Request 가 아닌 Server 로 부터 Response 할때는 위의 다이어그램의 역순으로 Link 가 이어진다.

ApolloClientGraphQL Server 에 보낼때 용어를 Down Chain 이라고 부르며,
GraphQl ServerApolloCient 에 보낼때는 Up Chain 이라고 한다.

Docs 를 보면서 이 용어가 꽤나 자주나온다..

Link 에 대한 자세한 내용은 1페이지 를 할애할 정도로 양이 많은 상황이라, 이부분은 추가적으로 내용을 정리해야 할것 같다.

여기서 중요한 부분은 Apollo Client 에서 GrapyQL Server 사이의 Network 흐름을 처리하기 위해 Link libary 를 사용하며, Link library 는 각 Link(수행할 역할)Chain 형식으로 연결지어 두었는것이다.

operation 과 forward

위의 Link 에 대해 대략적으로 살펴보았다. LinkNetwork 조작을 위해 존재한다고 했으며, onErrorNetwork 상 어떠한 Error 가 발생했을때, Catch 하여 알려준다.

즉, onErrorApollo Client 에서 제공해주는 Link 이다. Link 는 호출내부에 callback 함수를 받는데, 이를 request handler 라고 부른다.

먼저 code 를 살펴보도록 하자.


import { onError } from '@apollo/client/link/error'

  const errorLink = onError(({ graphQLErrors, networkError, operation, foword}) => { ... })

위 코드를 보면 callback 함수의 인자operationforward 가 보일것이다.

request handler 는 다음의 인자를 기본적으로 제공한다.

  1. operation
  2. forward

물론, onErrorcallback 은 다른 인자를 갖기도 하지만 Link 이기에, request handler 이기에 위 인자를 사용할 수 있다.

Docs 에서는 위 인자는 다음의 property 를 제공한다.

operation

operation

NameDescription
query발생하는 작업을 설명하는 DocumentNode
variables작업과 함께 전송하는 GraphQL variablesmap
operationName만약 이름이 있다면 query 의 이름, 아니면 null
extentionsserver 로 보낼 확장 data 가 저장된 map
getContext요청의 context 를 리턴하는 함수
context 는 수행작업을 정하기 위해 links 에서 사용할 수 있다.
setContext새로운 context 객체 또는 함수를 가지는 함수, 함수일때 이전 context 를 인자로 가질수 있고 새로운 contextreturn 할 수 있다.

forword

link 의 request handlerdone 일때 forward를 반환한다.

만약 linkterminating link 라면 제외

return forward(operation)link chain 에서 다음의 link에 전달된다.

만약 customLinkreturn forward(operation) 을 반환하지 않으면, 다음 링크가 실행되지 않고 terminating link 로 인식하여 종료된다. 그러므로 연결된 다른 link 가 실행되지 않을 수 있으니 주의하자

observable

우리가 사용하고 있는 forwardreturn 타입은 observable 타입이다. 여기서 observable 타입이 무엇인지 알 필요가 있다.

observable 는 데이터를 비동기로 처리해 변화에 유연함을 주는 프로그래밍 패러다임이라고 한다.

이러한 observablereactive programing 을 하는데 사용되는 pattern 중에 하나이다.

reactive programing 이란, 어떠한 데이터가 변화되었을때, 즉각적으로 반응하여 처리하는 프로그램 패러다임을 뜻한다.

reactive programing 이란 무엇인지 조금더 개념을 살펴보아야 겠다.

Reactive Programing 개념

observableRP(reactive programing) 에서 producer 라고 부르며, observable 의 상태를 관찰하고 반응하는 observerconsumer 라고 부른다.

이렇게 prodcuerconsumer 가 구분되어 처리되는것을 통해 각 상태의 분리가 가능하며, 불변성역시 보장된다 .

producer 가 데이터를 받아 consumer 로 보내는데, 이렇게 보내는 흐름을 stream 이라고 표현한다.

이러한 스트림은 pipe line 을 통해 이어지는데, 여기서 pipeproducer 로 부터 받은 원본데이터를 순차적으로 가공하여 consumer 로 보내주는 역할을 한다. 그리고 그 받은 데이터를 consumer 가 소비(데이터를 사용)한다.

즉, producer 는 마치 consumer 가 수신할 알림을 보내는 역할을 한다. consumerproducer 로 부터 받은 모든 이벤트에 대해 비동기로 반응하기에, single theadnodejs 에서 동기적으로 멈출일이 없다.

이는 비동기 프로그래밍 에서의 이점을 살리며 처리하는 방식이다.

이러한 비동기 로 인해 RPdata fetching 에 이상적으로 작동 가능하다. 이는 대규모 이벤트 처리 가 일어나더라도, 멈추는 일 없이 처리 가능하다는 것이다.

RP 에서의 중요한 부분은, comsumersubscription 하지 않으면 동작하지 않는다는 것이다.

subscriptionconsumer 가 존재한다면, subscription 된 모든 consumer 들이 공통적인 pipe 를 통해 동일한 처리가 이루어진다.

tc39/proposal-observable 에서 javascriptobservable 이 어떻게 만들어지고 작동하는지 설명해준다.

observable 에 대한 부분을 알기 위해서는 더 많은 공부가 필요할것 같다. 추푸 RxJS 를 추가적으로 공부할 계획이다.

다시 onError 로 돌아와서..

forward: function 에서의 문구를 다시 보자

function 은 연결되어진 chain 을 타고 내려가 다음 link 를 호출한다.
onError 의 콜백에서 return forward(operation) 를 호출하면,
구독할 upstream link 에 대한 새로운 observable이 반환된다.

이 문구상에서 chainLink 객체가 연결되어진 것을 뜻하며, onErrorforward 를 통해 다음 Link 에 전달된다.

이때 중요한 것은 OnError는 서버로부터 받은 상태값이기에, Downstream 이 아닌 Upstream 이라는 것이다,

이렇게 반환된 결과값은 forword 에 의해 observable 타입으로 반환되는것을 알수 있게 되었다.