Man*_*iya 7 apollo graphql graphql-js apollo-server
我正在使用apollo-server和apollo-graphql-tools,我有以下架构
type TotalVehicleResponse {
totalCars: Int
totalTrucks: Int
}
type RootQuery {
getTotalVehicals(color: String): TotalVehicleResponse
}
schema {
query: RootQuery
}
Run Code Online (Sandbox Code Playgroud)
和解析器功能是这样的
{
RootQuery: {
getTotalVehicals: async (root, args, context) => {
// args = {color: 'something'}
return {};
},
TotalVehicleResponse: {
totalCars: async (root, args, conext) => {
// args is empty({}) here
.........
.........
},
totalTrucks: async (root, args, conext) => {
// args is empty({}) here
.........
.........
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
我的问题是如何在任何子args解析器中访问root解析器(getTotalVehicals)中可用的?
cYe*_*Yee 12
(客户端)从:
Car(type: $type, materialType: $materialType){
id
material
name
...
}
Run Code Online (Sandbox Code Playgroud)
(客户端)至:
Car(type: $type){
id
material(materialType: $materialType) // moved here
name
...
}
Run Code Online (Sandbox Code Playgroud)
然后,在您的服务器中访问您的参数fieldResolver(material在本例中为字段)。
更长的版本
尽量不要传递您的参数root,除了IDs, arguments that is not from client或a parent object任何其他使用字段级参数的内容 (除非您有充分的理由不这样做)
有几个原因:
紧耦合
来自评论部分的@Bruno Ribeiro:它导致耦合并且很难扩展模式
难以排除故障
一个级别仍然可以,但是当坏习惯失控时,您公司中的某个人找到了一种方法将争论深入到几个级别的根源中,并且消失了,很难找出它消失的地方。不好玩。
向儿童泄露不必要的信息
通过 root 传递参数也意味着传递给其他每个孩子,无论是否需要。
让我们让它变得非常简单:只有两个级别的论证:
假设您想要query一辆可定制的汽车(让我们现在仅限于座椅可定制)
[Root] Car(color:white, type:sedan, seat:leather)
Run Code Online (Sandbox Code Playgroud)
很快你发现自己,需要自定义座椅颜色
[Root] Car(color:white, type:sedan, seat:leather, seatColor:black)
Run Code Online (Sandbox Code Playgroud)
然后,业务增长,现在我们也需要定制轮辋:
[Root] Car(color:white, type:sedan, seat:leather, seatColor:black, rimShape:star,rimColor:makeitshine)
Run Code Online (Sandbox Code Playgroud)
下一个仪表板,排气管,窗户,它永远不会结束。要解决此问题:将其设置为字段级别:
[Root] Car(color:white, type:sedan)
[Field] seat(color: black, texture:fabric)
[Field] rim(shape:star, color: makeitshine)
[Field] window(feature:bulletproof, tint:cantseeme)
......any other thing you want to add
Run Code Online (Sandbox Code Playgroud)
现在每个字段都负责自己的参数并拥有自己的解析器,而不是将所有参数集中到一个根中。
每当您发现自己为该字段创建专用解析器时,请将参数传递给该字段(不是 root,更糟糕的是:info)
结束了漫长的呜呜声。
######################
本节回答主持人提问。
我的问题是如何访问任何子解析器中的根解析器(getTotalVehicals)中可用的参数?
type RootQuery {
getTotalVehicles(color: String): TotalVehicleResponse
}
type TotalVehicleResponse {
totalCars(color: String): Int // <-- added arguments
totalTrucks(offset: Int, limit: Int): Int // <-- added arguments
}
schema {
query: RootQuery
}
Run Code Online (Sandbox Code Playgroud)
然后,您可以在解析器参数字段中访问此参数:
// In your child resolver
TotalVehicleResponse{
totalCars(parent, args, ctx){
const {color} = args // <-- access your client args here
return ....
}
totalTrucks(parent, args, ctx){
const {offset, limit} = args // <-- your args from client query
...do db query
return ....
}
}
Run Code Online (Sandbox Code Playgroud)
在您的客户查询中
不要忘记在嵌套查询字段中添加变量。
getTotalVehicles(color: $color){
totalCars(color: $color) <-- add your variable here
totalTrucks(offset: $offset, limit: $limit) <-- add your variable here
}
Run Code Online (Sandbox Code Playgroud)
imr*_*las 10
args请严格参考该字段查询中提供的参数。如果你想提供给孩子解析器值,你可以简单地从父解析器回报他们。
{
RootQuery: {
getTotalVehicles: async (root, args, context) => {
return { color: args.color };
},
TotalVehicleResponse: {
totalCars: async (root, args, context) => {
// root contains color here
},
totalTrucks: async (root, args, context) => {
// root contains color here
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
如果你知道你正在使用变量,那么除了接受的答案之外,还有另一种方法,使用解析器函数的第四个参数:info.
该info参数包含variableValues其他字段中的字段.此字段不严格包含父级args,但如果使用传递给父级解析程序的变量执行操作,则可以通过所有相关解析程序函数的info.variableValues访问它们.
因此,如果您的操作被调用,例如:
query GetTotalVehicalsOperation($color: String) {
getTotalVehicals(color: $color) {
totalCars
totalTrucks
}
}
Run Code Online (Sandbox Code Playgroud)
...带变量:{color:'something'}
您可以访问其他解析器中的变量:
{
RootQuery: {
getTotalVehicles: async (root, args, context, info) => {
//info.variableValues contains {color: 'something'}
return {};
},
TotalVehicleResponse: {
totalCars: async (root, args, context, info) => {
//same here: info.variableValues contains {color: 'something'}
},
totalTrucks: async (root, args, context, info) => {
//and also here: info.variableValues contains {color: 'something'}
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
3814 次 |
| 最近记录: |