iT邦幫忙

第 12 屆 iThome 鐵人賽

DAY 6
0
Software Development

線上娃娃機-js開發篇系列 第 8

線上娃娃機- apollo client init

  • 分享至 

  • twitterImage
  •  

原本 SSR環境就已經比較複雜了 現在要再加上上傳檔案middleware跟subscriptions的部分 有點小複雜

以下說明一下 如何組合 可以用的 apollo init 說明文字直接寫在 code備註中

import { ApolloClient } from 'apollo-client'
import { setContext } from 'apollo-link-context'
import fetch from 'isomorphic-unfetch'
import { createUploadLink } from 'apollo-upload-client'  //可以使用graph上傳資料
import config from '../config'
import { SubscriptionClient } from 'subscriptions-transport-ws';
import { WebSocketLink } from 'apollo-link-ws';
import { InMemoryCache, NormalizedCacheObject } from 'apollo-cache-inmemory';
import { split } from 'apollo-link';
import { getMainDefinition } from 'apollo-utilities';
import ws from 'ws';

let apolloClient: any = null

const WS_URI = `wss://clawfun.online/graphql`; //設定socket uri

const cache = new InMemoryCache();
if (!process.browser) { global["fetch"] = fetch }  //server端補一個fetch
const ssrMode = (typeof window === 'undefined');  //seever端另外一判方法比照上一行

function create(initialState: any, { getToken }: { getToken: any }) {

  const token = getToken()
  let link: any, linkServer: any, linkClient: any, wsLink: any

  const httpLink = createUploadLink({ uri: `${config.serverURL()}/graphql`, credentials: 'include' }); 
  //因為有上傳檔案的需求使用了 createUploadLink
  
  const authLink = setContext((_, { headers }) => { const token = getToken(); return { headers: { ...headers, authorization: token ? `Bearer ${token}` : '' } } })

//這裏先取得token 如果有token 就夾到 headers 之後打api都會附加上去作為jwt驗證用

  try {

    if (!ssrMode) {  
    //client 建立socket 並要記得設定 reconnect :true 
      wsLink = new SubscriptionClient(WS_URI, { reconnect: true, connectionParams: { headers: { authorization: token ? `Bearer ${token}` : '' } } });

   //這裏是區分query的時候要用哪種模式 wsLink 與 httpLink 由 apollo 提供的 getMainDefinition 去判斷
      linkClient = split(
      ({ query }) => {
        const definition = getMainDefinition(query);
        return (definition.kind === 'OperationDefinition' && definition.operation === 'subscription');
      }, wsLink, httpLink);
      
      console.log('linkClient');

    } else {
      linkServer = authLink.concat(httpLink);      //server部分就不需要建立 socket
    }
  } catch (err) {    console.log('err', err);  }

  const client: ApolloClient<NormalizedCacheObject> = new ApolloClient({
    connectToDevTools: process.browser,
    ssrMode: !process.browser,  
    link: ssrMode ? linkServer : linkClient,  
     cache: new InMemoryCache({ dataIdFromObject: (object: any) => object["key"] || null }).restore(initialState || {})
  })

  return client
}

export default function initApollo(initialState: any, options: any) {
  if (!ssrMode) { return create(initialState, options) }
  if (!apolloClient) { apolloClient = create(initialState, options) }
  return apolloClient
}

在判斷 wsLink與 httpLink 與 SSR 區分 是在設定 apollo init 要特別注意的 ,希望對初次設定的朋友 有幫助


上一篇
線上娃娃機-server machine setup
下一篇
typeorm 與 娃娃機資料庫規劃
系列文
線上娃娃機-js開發篇11
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言