是否有人对GraphQL和Firebase有任何经验?我想一个将firebase调用放置在相关字段的解析器中,并将一些变量从组件的props传递到查询的参数中。
我们如何使用GraphQL在Firebase中插入新数据?
是否有人对GraphQL和Firebase有任何经验?我想一个将firebase调用放置在相关字段的解析器中,并将一些变量从组件的props传递到查询的参数中。
我们如何使用GraphQL在Firebase中插入新数据?
Answers:
要回答您的问题,有三种方法可以解决此问题。
如果您设置使用Firebase,则可以将Firebase的API一对一映射到GraphQL查询和变异。
您当然可以将Firebase API包装到GraphQL解析器中,然后以这种方式进行调用。这是一个很好的例子:
const ref = path => firebase.database().ref(path)
const getValue = path => ref(path).once('value')
const mapSnapshotToEntities = snapshot => snapshot.val().map((value, id) => ({ id, ...value }))
const getEntities = path => getValue(path).then(mapSnapshotToEntities)
const resolvers = {
Author: {
posts(author) {
return getEntities('posts').then(posts => filter(posts, { authorId: author.id }))
},
},
Post: {
author(post) {
return getEntities('authors').then(posts => filter(authors, { id: authorId }))
},
},
};
本质上,您在这里所做的就是将Firebase用作数据库,该数据库可以正常工作,直到您想在解析器中以关系方式查询数据为止。如果无法在数据存储顶部的服务器端执行联接,则您将向解析器中的Firebase发出大量往返请求,以仅满足单个请求。
大多数人使用Firebase的原因在于其实时功能,而不仅仅是主要作为数据存储,因为在这方面的数据关系建模工具相当缺乏。这样,您最好使用其他数据源迁移到GraphQL。
考虑到您可以使用Firebase等BaaS产品,您可以考虑切换到GraphQL BaaS。
如果您愿意使用自己的数据存储切换到自托管解决方案,那么它也有很多好处。以下是一些大人物:
使用自己的数据存储的灵活性,也许可以满足您特定应用程序的需求
自定义查询和变异
本机添加自定义逻辑,而不是通过API中附加到Webhooks的微服务
推出自己的身份验证和许可机制
可能是一种低成本的解决方案
我强烈不同意这里的一些建议。GraphQL可以以关系方式使用,但也可以以NoSQL方式使用。带有RTD(实时数据库)和Firestore的Firebase应该建模为NoSQL数据库,因为它是NoSQL数据库!这种方法需要权衡:
1.优化阅读:
作为NoSQL数据库,应将集合建模为客户端(移动或Web)中的视图,因此,当您进行查询时,所有内容都已合并,并且不必在客户端或Firebase函数中创建计算道具。这种方法使阅读真正非常快。
2.取消优化写入:
这里的主要权衡是,如果您触摸相关数据(例如更新用户名,个人资料图片等),则您有责任更新数据库中的每个文档。在这种情况下,您应该在数据库中找到每个文档(例如,帖子,评论等)并确保原子性。如果您的应用程序的读取操作要比写入操作多(例如,博客,例如7000次读取到1次写入),则建议使用此方法。
3.易于扩展:
由于您的馆藏与其他文档没有严格的关系,因此您可以在一个服务器中拥有一个完整的馆藏,也可以将其拆分给许多服务器。(这就是为什么Firebase像DynamoDB这样的扩展规模便宜的原因。)
GraphQL只是一种查询语言。它应该使您查询事情变得容易,但是它不应该决定如何对数据库建模。您应该指示如何对数据库,查询和变异进行建模。
TL; DR: GraphQL在Firebase不足之处发光。强大的数据建模,灵活高效的查询以及开放的规范都是GraphQL必不可少的组成部分,而Firebase缺少这些功能。
由于其有限的数据建模,Firebase受到了很多批评。基本上,您的数据被构造为一个巨大的JSON,可多次声明相同的数据。起初看起来很方便的结果是,每当您需要更新数据时都会导致客户端代码难以管理,因为您必须手动跟踪对同一数据的所有引用。
另一方面,在GraphQL中使用的数据结构非常直观,而且考虑起来很熟悉,因为它被建模为图形。使用IDL语法,我们可以轻松地描述称为GraphQL模式的数据模型。对于Twitter应用,架构如下所示:
type Tweet {
id: ID!
title: String!
author: User! @relation(name: "Tweets")
}
type User {
id: ID!
name: String!
tweets: [Tweet!]! @relation(name: "Tweets")
}
在这里,我们定义了两种类型Tweet
和User
一些标量性质,也是一个一个一对多的关系之间User
和Tweet
。单个数据项称为节点-用户节点可以连接到许多tweet节点。除了Firebase的JSON方法外,此数据结构既简单又灵活。
GraphQL的灵活查询功能是其主要优点之一。查询是分层的,这意味着您可以指定镜像图结构的数据需求。在我们的Twitter示例中,我们可能有一个查询来获取所有用户及其推文:
query {
allUsers {
id
name
tweets {
title
}
}
}
请注意,我们可以自由地包含或保留要查询的字段,甚至可以查询各种关系。这意味着我们既不需要执行多个查询,也不需要查询不需要的数据,这使得GraphQL查询非常高效。
在混合中添加查询参数,我们可以添加自定义顺序或过滤器之类的功能以获得强大的GraphQL API。
Firebase根本无法实现所有这些功能。
Firebase的实时功能使它如此流行-但是由于GraphQL社区即将就实时性达成共识,因此Firebase的最大优势也被取消了。我建议使用有关GraphQL订阅的视频教程,以更好地理解基本概念
因此,回答您的问题:GraphQL在大多数方面都超过了Firebase,使其成为首选。
如果您对GraphQL感兴趣,我建议您查看Graphcool,它结合了GraphQL的优势和强大的功能,例如内置身份验证以及到AWS Lambda的灵活钩子或其他无服务器功能,以实现自定义业务逻辑。
免责声明:我在Graphcool工作:)
您可以在本地使用graphql和firebase。所有繁重的工作都可以在Webworker中完成,以避免在解决请求时阻塞UI。
关于“解决请求所必需的许多往返”的一句话:如果您不介意传输的数据,那没什么大不了的,因为所有“往返”都合并在同一套接字框架中。但是,如果您确实想避免使用大型框架,则只需dataloader
在Firebase数据库的前面放置一些内容即可。
对于实时更新,您只需要从firebase订阅实时事件并将其发送到Webworker,即可将其转换为可以通过您的模式解决的实际graphql订阅。
您可以在我的中篇文章中找到有关此问题的更多信息:带有Firebase,GraphQL和apollo-client 2.0的“仅客户端”实时Web应用程序
希望能有所帮助!
您必须使用Firebase吗?有些特定于GraphQL的服务可能会提供您想要的东西。https://scaphold.io是一家YC奖学金公司,该公司看起来特别有前途,可为您提供类似Firefire的体验,但它由GraphQL提供支持。