Apollo GraphQL updateQuery to typePolicy
Tôi đang đập đầu vào tường. Tôi đã cập nhật lên Apollo 3 và không thể tìm ra cách chuyển một updateQuerysang a typePolicy. Tôi đang thực hiện phân trang dựa trên sự tiếp diễn cơ bản và đây là cách tôi đã sử dụng để hợp nhất các kết quả của 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
}
}
}
Tôi đã cố gắng tự viết merge typePolicy, nhưng nó liên tục tải và tạo ra lỗi về các số nhận dạng trùng lặp trong bộ nhớ cache của Apollo. Đây là giao diện của tôi typePolicycho truy vấn của tôi.
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
}
}
}
}
}
Trả lời
Vì vậy, tôi đã có thể giải quyết trường hợp sử dụng của mình. Nó có vẻ khó hơn nó thực sự cần. Về cơ bản, tôi phải cố gắng xác định vị trí các mục hiện có khớp với thư đến và ghi đè chúng, cũng như thêm bất kỳ mục mới nào chưa tồn tại trong bộ nhớ cache.
Tôi cũng phải chỉ áp dụng logic này nếu mã thông báo tiếp tục được cung cấp, bởi vì nếu nó rỗng hoặc không xác định, tôi chỉ nên sử dụng giá trị đến vì điều đó cho biết rằng chúng tôi đang thực hiện tải ban đầu.
Tài liệu của tôi có dạng như sau:
{
"items": [{ id: string, ...others }],
"continuation": "some_token_value"
}
Tôi đã tạo một chính sách loại chung mà tôi có thể sử dụng cho tất cả các tài liệu của mình có hình dạng tương tự. Nó cho phép tôi chỉ định tên của thuộc tính items, các args chính mà tôi muốn lưu vào bộ nhớ cache và tên của loại graphql.
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
}
}
}
}