Apollo GraphQL updateQuery to typePolicy

Sep 01 2020

Kafamı duvara vuruyorum. Apollo'nun 3'e güncelledik ve bir göç anlamaya olamaz updateQuerybir etmek typePolicy. Devam etmeye dayalı temel sayfalandırma yapıyorum ve eskiden şu sonuçları birleştirirdim fetchMore:

await fetchMore({
  query: MessagesByThreadIDQuery,
  variables: {
    threadId: threadId,
    limit: Configuration.MessagePageSize,
    continuation: token
  },
  updateQuery: (prev, curr) => {
    // Extract our updated message page.
    const last = prev.messagesByThreadId.messages ?? []
    const next = curr.fetchMoreResult?.messagesByThreadId.messages ?? []

    return {
      messagesByThreadId: {
        __typename: 'MessagesContinuation',
        messages: [...last, ...next],
        continuation: curr.fetchMoreResult?.messagesByThreadId.continuation
      }
    }
  }

merge typePolicyKendimi yazmak için bir girişimde bulundum , ancak sürekli olarak Apollo önbelleğindeki yinelenen tanımlayıcılarla ilgili hatalar yükleyip atıyor. Sorgum için typePolicyaşağıdaki gibi görünüyor.

  typePolicies: {
    Query: {
      fields: {
        messagesByThreadId: {
          keyArgs: false,
          merge: (existing, incoming, args): IMessagesContinuation => {
            const typedExisting: IMessagesContinuation | undefined = existing
            const typedIncoming: IMessagesContinuation | undefined = incoming
            const existingMessages = (typedExisting?.messages ?? [])
            const incomingMessages = (typedIncoming?.messages ?? [])

            const result = existing ? {
              __typename: 'MessageContinuation',
              messages: [...existingMessages, ...incomingMessages],
              continuation: typedIncoming?.continuation
            } : incoming


            return result
          }
        }
      }
    }
  }

Yanıtlar

DylanVester Sep 15 2020 at 14:21

Böylece kullanım durumumu çözebildim. Olması gerekenden çok daha zor görünüyor. Esasen gelenlerle eşleşen mevcut öğeleri bulup üzerine yazmam ve ayrıca önbellekte henüz bulunmayan yeni öğeleri eklemem gerekiyor.

Ayrıca bu mantığı yalnızca bir devamlılık belirteci sağlandıysa uygulamam gerekiyor, çünkü boş veya tanımlanmamışsa, yalnızca gelen değeri kullanmalıyım çünkü bu bir ilk yükleme yaptığımızı gösterir.

Belgem şu şekildedir:

{
  "items": [{ id: string, ...others }],
  "continuation": "some_token_value"
}

Benzer şekle sahip tüm belgelerim için kullanabileceğim genel bir tür politikası oluşturdum. Öğeler özelliğinin adını, önbelleğe almak istediğim anahtar bağımsız değişkenlerin ve graphql türünün adını belirtmeme izin veriyor.

export function ContinuationPolicy(keyArgs: Array<string>, itemPropertyKey: string, typeName: string) {
  return {
    keyArgs,
    merge(existing: any, incoming: any, args: any) {
      if (!!existing && !!args.args?.continuation) {
        const existingItems = (existing ? existing[itemPropertyKey] : [])
        const incomingItems = (incoming ? incoming[itemPropertyKey] : [])
        let items: Array<any> = [...existingItems]

        for (let i = 0; i < incomingItems.length; i++) {
          const current = incomingItems[i] as any
          const found = items.findIndex(m => m.__ref === current.__ref)

          if (found > -1) {
            items[found] === current
          } else {
            items = [...items, current]
          }
        }

        // This new data is a continuation of the last data.
        return {
          __typename: typeName,
          [itemPropertyKey]: items,
          continuation: incoming.continuation
        }
      } else {
        // When we have no existing data in the cache, we'll just use the incoming data.
        return incoming
      }
    }
  }
}