首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Falcor -未缓存的深度嵌套引用

Falcor -未缓存的深度嵌套引用
EN

Stack Overflow用户
提问于 2019-02-19 16:24:15
回答 1查看 92关注 0票数 0

当我请求包含嵌套引用的路由时,我在Falcor客户机中看到了一个问题。

下面是一个示例:

考虑以下来自Falcor服务器的model.get调用的model.get响应

代码语言:javascript
复制
{
  "todos": {
    "0": { "$type": "ref", "value": ["todosById", "id_0"] },
    "1": { "$type": "ref", "value": ["todosById", "id_1"] },
    "length": 2
  },
  "todosById": {
    "id_0": {
      "name": "get milk",
      "label": { "$type": "ref", "value": ["labelsById", "lbl_0"] },
      "completed": false
    },
    "id_1": {
      "name": "do the laundry",
      "label": { "$type": "ref", "value": ["labelsById", "lbl_1"] },
      "completed": false
    }
  },
  "labelsById": {
    "lbl_0": { "name": "groceries" },
    "lbl_1": { "name": "home" }
  }
}

当我使用以下路径调用model.get时,所有上述jsonGraph结果都应该在缓存中:

代码语言:javascript
复制
model.get(['todos', {from: 0, to: 1}, ['completed', 'label', 'name']])

但是,手动访问缓存时,我可以看到todostodosById都在缓存中,而不是labelsById

我不确定,但看起来labelsById不在缓存中,因为它是二级引用?

我是在这里遗漏了什么,还是说这是Falcor缓存的一种预期行为?有没有办法强迫labelsById在缓存中,这样就不会提出额外的数据源请求了?

任何帮助都是非常感谢的!

这个问题可以在这个小项目中重现:https://github.com/ardeois/falcor-nested-references-cache-issue

更新

感谢@james回答,通过执行以下model.get可以缓存json图

代码语言:javascript
复制
model.get(
  ['todos', {from: 0, to: 1}, ['completed', 'name']],
  ['todos', {from: 0, to: 1}, 'label', 'name']
);

然而,在服务器端,Falcor路由器将调用两次todos[{integers:indices}]路由。这可能会对您的Falcor服务器所面临的API或数据库调用产生影响。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2019-02-20 14:50:52

在路径集['todos', {from: 0, to: 1}, ['completed', 'label', 'name']]中,以completedname键结尾的路径终止于一个原子。但是以label键结尾的路径在引用时终止。如果您想要真正遵循该引用,则必须将其包含为第二条路径:

代码语言:javascript
复制
[
   ['todos', {from: 0, to: 1}, ['completed', 'name']],
   ['todos', {from: 0, to: 1}, 'label', 'name']
]

一般来说,所有的路径都应该在原子上终止,而不是在引用时终止。我不确定在引用时终止的路径的预期行为是什么,或者即使它定义得很好(正如你的另一个问题所指出的,行为已经从v0变成了v1)。

model.get(...paths)调用可以使用多个pathSet数组,因此重写查询应该像

代码语言:javascript
复制
model.get(
  ['todos', {from: 0, to: 1}, ['completed', 'name']],
  ['todos', {from: 0, to: 1}, 'label', 'name']
);

编辑

正如在下面的注释中所指出的,由于路由器处理程序一次只能解析一个pathSet,所以具有多个pathSets的GET请求可能导致对您的上游支持服务/db的多个请求。一些可能的解决办法:

使用单一路径

使用单路径['todos', range, ['completed', 'name', 'label'], 'name']重写请求。从技术上讲,这个请求要求的是todos.n.completed.nametodos.n.label.name (不存在),以及todos.n.label.name (确实存在)。

但是,如果路由器处理程序返回比匹配路径短的路径的pathValues,则应该将较短的pathValues合并到jsonGraph缓存中。例如,当匹配todos.0.completed.name时,返回{ path: ['todos', 0, 'completed'], value: true },而匹配todos.0.label.name时返回{ path: ['todos', 0, 'label', 'name'], value: 'First TODO' }

这可能是最简单的方法,但意味着您的查询在语义上并不是真正正确的(您是在有意地询问不存在的路径)。

批处理路由器发出的上游请求

在路由器中,批处理对备份服务/db的上游请求。这并不总是简单明了的。一种可能的方法是使用facebook的数据加载器,它是为了解决w/ GraphQL路由器的等价问题而编写的,但不一定与GraphQL绑定。另一种方法可以使用自定义还原函数来组合发出的请求(例如,这里)。

重写您的模式

因此,所有需要同时请求的路径都具有相同的长度。但这并不总是可能的,因此:耸耸肩。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/54770785

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档