在使用Rails + Nuxt + GraphQL创建支持服务器端渲染的单页面应用的情况下,我个人认为的最佳实践是什么
有很多关于各个库的文章,但没有关于如何组合它们以便轻松创建的信息,所以我写了这篇文章。请自行搜索每个库的详细信息。
将在本文介绍的库进行组合,可以实现以下功能。
可以实现的事情
-
- SSR対応のSPA
-
- 各ページ一回のリクエストで描画に必要なデータをすべてもってこれる
-
- N + 1問題を防げる
- つなぎこみのコードが少なくて済む(サーバーのコントローラーやクライアントのストア)
图书馆 (tú shū
-
- rails
-
- graphql-ruby
-
- graphql-batch
-
- search_object
-
- search_object_graphql
-
- nuxt
-
- vuex-orm
-
- vuex-orm graphql plugin
- isomorphic-fetch
GraphQL (图灵程序设计语言)
由于使用了rails,我尝试将ID的类型设置为BigInt,但由于ID变为字符串,我将其改为Float,最多可以达到53位。
GraphQL 批处理
在GraphQL中,类型是通过延迟评估来编写的。可以避免N + 1问题。不仅可以高效地序列化简单的关联字段,还可以计算复杂的列(例如用户拥有的文章数量)。
搜索对象 + 搜寻对象的 GraphQL 插件
可以简单地编写带有筛选器的GraphQL Resolver。
但由于只使用了一小部分,所以对于这个东西是否真的好还不太清楚。
客户端数据管理
在每个页面的asyncData中,获取所有页面所需的数据。
使用GraphQL一次性获取相关数据,以减少请求次数。
Vuex ORM 是一个供开发者使用的库。
真的很舒适。
不再需要写代码并进行每一次搜索。
可以轻松地向模型中添加计算列。
因为每次都导入模型很麻烦。
这个.$store.models.User
就好像我勉強地把models这个变量强行存储到了$store里面。
Rails会在需要的时候自动加载,即使不使用includes。但是,这个东西如果不加上with(相当于includes的东西),就会变成null,所以要注意。我曾经花了一个小时陷入困境。
另一个吸引人的地方是,模型中某些实例方法可能会受到时间限制而无法调用。
-
- ブラウザリロード直後 -> ちゃんと表示される (SSR)
-
- ブラウザリロードして少し後 -> 表示が崩れる (インスタンスメソッドを呼べてない)
- リロードせずに遷移 -> ちゃんと表示される (インスタンスメソッドを呼べている)
Vuex ORM的find等方法只是返回存储的数据。
似乎不需要进行装饰等操作来返回数据。
我认为对于改进Vuex ORM,使用静态方法而不是实例方法来实现Model.myComputedColumn(instance)可能更好。
这里有多少分支?
如果没有任何一个预加载的列,那么将返回原始数据。
假设
-
- リロード直後はSSRで渡されたplain objectがstoreに入っている
-
- vuex orm初期化時にはhydrateされない
-
- 更新時にhydrateされる
-
- 遷移時には更新されるのでhydrateされてplain objectからモデルに変換されるから、遷移時には正しく表示される
- findでも関連がある場合に限りhydrateされる <- こいつを強制すれば良い
修复了 -> 修复了这个问题
还有,这个有没有被双重水化了?
虽然我觉得操作上没有问题,
但是如果采用类似hydrateIfNeeded的机制,会更加清晰。
Vuex ORM GraphQL插件
取得的課程真的很舒適。
-
- 取得クエリがかんたん (vuex ormのモデル定義からクエリ生成)
- ネストしたモデルを自動的にvuex ormに書き込んでくれる
需要对Eager load进行一些调整。
就像Rails中的includes一样,可以在获取数据时调整要包含或不包含的关联数据,但此功能没有,是固定的。
因此,我们采取的方法是在获取数据之前修改模型的eagerLoad设置,然后在获取数据后将其还原。
由于vuex orm graphql插件的mutation要求输入类型与原始模型的类型匹配,所以使用起来不太方便。
我们需要自行编写连接mutation的代码。
如果您知道vuex orm graphql插件的替代方法或者知道如何在vuex orm graphql中有效操作,请告诉我。
使用isomorphic-fetch可以进行服务器端渲染。
服务器错误处理
在rescue_from中,将ActiveRecord的错误等转换为GraphQL::ExecutionError。详细信息请搜索。
服务器上的GraphQL测试
请求规范以前往。写GraphQL时要生写
(就像这个样子 https://selleo.com/blog/testing-graphql-mutations-in-ruby-on-rails-with-rspec)
我原以为会是这样,但是创建查询却出乎意料地麻烦。
以下的方式看起来很不错。
https://medium.com/@RJrobinson/testing-graphql-ruby-mutations-with-rspec-f5c7d02b1e58
硬编码版本:https://graphql-ruby.org/schema/testing.html
如果有更好的方法,请告诉我。