들어가기
subscription부분은 coding에서 가장 어렵고 난해한 부분같으므로,
집중, 또 집중하자.
그리고 subscriptions부분은 항상 공식문서를 참조 할 것.
apollo가 한번씩 바뀌어서 고럼.
https://www.apollographql.com/docs/react/data/subscriptions/
공식문서를 그대로 따라가면 됨,
기본은 link를 httpLink와 wsLink두개로 나누어서 만들어서,
spilt로 상황에 따라 적용되는 link를 choic하게 설정하면 됨.
import {
makeVar,
ApolloClient,
InMemoryCache,
createHttpLink,
split,
} from '@apollo/client'
import { setContext } from '@apollo/client/link/context'
import {
getMainDefinition,
offsetLimitPagination,
} from '@apollo/client/utilities'
import AsyncStorage from '@react-native-async-storage/async-storage'
import { onError } from '@apollo/client/link/error'
import { createUploadLink } from 'apollo-upload-client'
import { GraphQLWsLink } from '@apollo/client/link/subscriptions'
import { createClient } from 'graphql-ws'
export const isLoggedInVar = makeVar(false)
export const tokenVar = makeVar('')
export const TOKEN = 'token'
export const logUserIn = async (token) => {
await AsyncStorage.setItem(TOKEN, token)
isLoggedInVar(true)
tokenVar(token)
}
export const logUserOut = async () => {
await AsyncStorage.removeItem(TOKEN)
tokenVar(null)
isLoggedInVar(false)
}
const uploadHttpLink = createUploadLink({
uri: 'https://9020-182-222-65-111.jp.ngrok.io/graphql',
})
const wsLink = new GraphQLWsLink(
createClient({
url: 'ws://9020-182-222-65-111.jp.ngrok.io/subscriptions',
connectionParams: () => ({
token: tokenVar(),
}),
})
)
///1)wsLink를 만들어줌. url부분은 맨앞, 맨뒤 뺴고는 동일하게 적용시켜 줘야함.
///connectionParams 부분은 반드시 함수로 만들어 주어야 token이 server로 전달됨.
const authLink = setContext((_, { headers }) => {
return {
headers: {
...headers,
token: tokenVar(),
},
}
})
const onErrorLink = onError((graphQLErrors, networkError) => {
if (graphQLErrors) {
console.log('GraphQL Error', graphQLErrors)
}
if (networkError) {
console.log('Network Error', networkError)
}
})
export const cache = new InMemoryCache({
typePolicies: {
Query: {
fields: {
seeFeed: offsetLimitPagination(),
},
},
},
})
const httpLinks = authLink.concat(onErrorLink).concat(uploadHttpLink)
///2)httpLinks에 authLink, onErrorLink, uploadHttpLink를 연결해줌.
const splitLink = split(
({ query }) => {
const definition = getMainDefinition(query)
return (
definition.kind === 'OperationDefinition' &&
definition.operation === 'subscription'
)
},
wsLink,
httpLinks
)
///3)spilt링크 부분은 공식문서에 있는 부분을 그대로 ctrl+v함.
export const client = new ApolloClient({
link: splitLink,
cache,
})
///4)link부분은 splitLink로 대체해 줌.
ws부분의 path부분은 front부분의 apollo.js의 ws path와 맞춰주어야 함.