max*_*son 2 optimization graphql apollo-server
我公司具有面向服务的架构。因此,我的应用程序的 GraphQL 服务器必须调用其他服务来完成来自前端的数据请求。
让我们想象一下我的 GraphQL 模式定义了 type User。此类型的数据来自两个来源:
username,age和friends。User仅与我的应用程序相关的相关数据的 SQL 数据库:favoriteFood, favoriteSport.让我们假设用户帐户服务的端点自动返回usernameand age,但您必须传递查询参数friends=true才能检索friends数据,因为这是一项昂贵的操作。
鉴于此背景,以下查询在getUser解析器中提出了一些优化挑战:
query GetUser {
getUser {
username
favoriteFood
}
}
Run Code Online (Sandbox Code Playgroud)
挑战 #1
当getUser解析器向用户帐户服务发出请求时,它如何知道是否也需要请求friends数据?
挑战 #2 当解析器查询我的应用程序的数据库以获取其他用户数据时,它如何知道要从数据库中检索哪些字段?
对于这两个挑战,我能找到的唯一解决方案是通过info解析器接收到的第四个参数检查解析器中的查询。这将允许它找出是否friends应该在对用户帐户服务的 REST 调用中请求,并且它将能够构建正确的SELECT查询以从我的应用程序的数据库中检索所需的数据。
这是正确的方法吗?这似乎是 GraphQL 实现必须一直运行的用例,因此我希望遇到一个被广泛接受的解决方案。但是,我没有找到很多解决这个问题的文章,也没有广泛使用的 NPM 模块似乎存在(graphql-parse-resolve-info是 PostGraphile 的一部分,但每周只有大约 12k 的下载量,而graphql-fields有大约 18.5 k 每周下载)。
因此,我担心我遗漏了一些关于如何做到这一点的基本知识。我是吗?还是检查info论证是解决这些优化挑战的正确方法?万一重要,我正在使用 Apollo Server。
如果您想根据请求的选择集修改解析器,实际上只有一种方法可以做到这一点,那就是解析请求查询的 AST。根据我的经验,graphql-parse-resolve-info是使解析不那么痛苦的最完整的解决方案。
我想这并不像您想象的那么普遍,因为我想大多数人都属于以下两种群体之一:
在后一种情况下,表示关联的字段有自己的解析器,因此除非实际请求,否则不会触发对数据库的后续调用。然后使用Data Loader帮助批处理所有这些对数据库的额外调用。对于最终调用其他数据源(如 REST API)的字段也是如此。
在这种特殊情况下,Data Loader 对您没有多大帮助。最好的方法是使用单个解析器getUser从数据库和 REST 端点获取用户详细信息。然后,您可以按照您的计划,根据请求的字段调整这些调用(或完全跳过它们)。这可能很麻烦,但会按预期工作。
这种方法的替代方法是简单地获取所有内容,但使用缓存来减少对数据库和 REST API 的调用次数。这样,您每次都会获取完整的用户,但除非缓存失效或过期,否则您将从内存中获取。这会占用更多内存,并且缓存失效总是很棘手,但它可以显着简化您的解析器逻辑。
| 归档时间: |
|
| 查看次数: |
737 次 |
| 最近记录: |