前言
GraphQL 是一种 API 查询语言,它可以大大减少前端与后端的沟通,提高 API 开发效率。在使用 GraphQL 进行查询时,可能会遇到数据重复的问题,也就是说查询得到的数据在不同的字段中重复出现,这不仅浪费了网络资源,还影响了性能。本篇文章将介绍如何解决 GraphQL 查询中数据重复的问题。
问题分析
在 GraphQL 查询中,一个对象可能被多次引用,而这些引用可能会包含相同的数据。例如以下查询:
// javascriptcn.com 代码示例 query { post(id: 1) { id title author { id name } comments { id content author { id name } } } }
在上述查询中,author
和 comments
均引用了 User
对象,这就可能导致某些用户信息被多次传输,浪费网络资源。
解决方案
使用 alias
使用 alias 可以重命名字段,在查询时可以避免重复。例如,我们可以将上述查询改为:
// javascriptcn.com 代码示例 query { post(id: 1) { id title author { u_id: id u_name: name } comments { id content author { u_id: id u_name: name } } } }
这样可以避免多次传输相同的用户信息,但是增加了开发人员的工作量。
使用 Fragments
使用 Fragments 可以共享查询中的公共部分,减少数据的重复。例如,我们可以将上述查询改为:
// javascriptcn.com 代码示例 query { post(id: 1) { ...postFields author { ...userFields } comments { ...commentFields author { ...userFields } } } } fragment postFields on Post { id title } fragment userFields on User { id name } fragment commentFields on Comment { id content }
在这个示例中,使用了 postFields
,userFields
和 commentFields
这三个 Fragments,减少了数据的重复传输。
使用 DataLoader
当查询中包含多个重复数据时,使用 DataLoader 可以减少数据库查询次数。例如,我们可以将上述查询改为:
// javascriptcn.com 代码示例 query { post(id: 1) { id title author { id name } comments { id content author { id name } } } }
然后使用 DataLoader 对 author
和 comments.author
进行批量查询,减少数据库查询次数。例如,在 Node.js 中可以使用以下方式:
// javascriptcn.com 代码示例 const DataLoader = require('dataloader') const authorLoader = new DataLoader(async keys => { const authors = await db.getAuthors(keys) return keys.map(key => authors.find(author => author.id === key)) }) const commentAuthorLoader = new DataLoader(async keys => { const authors = await db.getAuthors(keys) return keys.map(key => authors.find(author => author.id === key)) }) const resolvers = { Post: { author: (parent, args, context, info) => { return authorLoader.load(parent.authorId) }, comments: (parent, args, context, info) => { return commentLoader.loadMany(parent.commentIds) } }, Comment: { author: (parent, args, context, info) => { return authorLoader.load(parent.authorId) } } }
在这个示例中,我们通过 authorLoader
和 commentAuthorLoader
对 author
和 comments.author
进行批量查询。
总结
在使用 GraphQL 进行查询时,数据重复是一个常见的问题,会对性能和网络资源造成不必要的浪费。本篇文章介绍了使用 alias、Fragments 和 DataLoader 三种方式解决 GraphQL 查询中数据重复的问题,在实际开发中可以根据具体情况选择适合的解决方案。
来源:JavaScript中文网 ,转载请注明来源 本文地址:https://www.javascriptcn.com/post/65444a997d4982a6ebe2be7c