[英]Context not being passed to nested Apollo GraphQL resolver
I am using Apollo Server v2 for my project 我正在为我的项目使用Apollo Server v2
I have added auth like given here https://www.apollographql.com/docs/apollo-server/features/authentication/ 我添加了auth,就像这里给出的https://www.apollographql.com/docs/apollo-server/features/authentication/
I wanted to include nested resolver in my Query
and Mutation
so I did as per https://stackoverflow.com/a/40916089/7584077 我想在我的
Query
和Mutation
包含嵌套的解析器,所以我按照https://stackoverflow.com/a/40916089/7584077进行了操作
The thing is my resolver is a lil bit more complex than the one shown above 事情是我的解析器比上面显示的更复杂
// typeDefs/typeDefs.js
import { gql } from "apollo-server-express";
import issueTracker from "./issueTracker";
const base = gql`
scalar Timestamp
type Query {
ping: String!
}
type Mutation {
ping: String!
}
`;
export default [base, issueTracker];
// typeDefs/issuetracker.js
import { gql } from "apollo-server-express";
export default gql`
type Comment {
id: ID
message: String
commentBy: User
createdAt: Timestamp
updatedAt: Timestamp
version: Int
}
type Issue {
id: ID
requestId: ID
title: String
issueNumber: Int
status: Int
tags: [String]
assignees: [User]
createdBy: User
comments: [Comment]
createdAt: Timestamp
updatedAt: Timestamp
version: Int
}
input CreateIssueRequest {
requestId: ID!
title: String!
createdBy: ID!
message: String!
assignees: [ID]!
}
type IssueTrackerQuery {
ping: String!
}
type IssueTrackerMutation {
createIssue(request: CreateIssueRequest!): Issue
}
extend type Query {
IssueTracker: IssueTrackerQuery
}
extend type Mutation {
IssueTracker: IssueTrackerMutation
}
`;
And a lil modified version of the stackoverflow answer above. 并且上面的一个lil修改版本的stackoverflow回答。 Here is my combined resolver.
这是我的组合解析器。
// resolvers/resolvers.js
import IssueTracker from "./issueTracker";
export default {
Query: {
ping: () => "ping!",
IssueTracker: () => ({
ping: IssueTracker.ping,
}),
},
Mutation: {
ping: () => "ping!",
IssueTracker: () => ({
createIssue: IssueTracker.createIssue,
}),
},
};
This is because I wanted Query & Mutation to be completely separate. 这是因为我希望Query & Mutation完全分开。
Here is my IssueTracker resolver 这是我的IssueTracker解析器
// resolvers/issueTracker.js
export default {
ping: () => "ping",
createIssue: async (parent, args, context) => {
console.log(parent);
console.log(args);
console.log(context);
// create issue as per request and return
}
The thing is here is that, parent
actually is the args
field! 事情就是这样,
parent
实际上是args
领域! And I need userId from context to make sensible data. 我需要来自上下文的userId来制作合理的数据。
Hmm, the SDL first approach can be a bit tricky. 嗯,SDL的第一种方法可能有点棘手。 It's not easy to explain what is wrong here but I will do my best.
解释这里出了什么问题并不容易,但我会尽力而为。 First let me tell you what to need to do to make this work and then I will explain what goes wrong.
首先让我告诉你需要做些什么来完成这项工作然后我会解释出了什么问题。
Create a IssueTrackerMutation
field in the resolver map: 在解析器映射中创建
IssueTrackerMutation
字段:
export default {
Query: {
ping: () => "ping!",
IssueTracker: () => ({ // same here but I will just do the mutation for you
ping: IssueTracker.ping,
}),
},
Mutation: {
ping: () => "ping!",
IssueTracker: () => null, // or whatever you want as a root here
},
IssueTrackerMutation: {
createIssue: IssueTracker.createIssue
}
};
Note the difference between creating a "pure" resolver for the IssueTracker and returning an object for IssueTracker with a createIssue
method. 注意为IssueTracker创建“纯”解析器和使用
createIssue
方法返回IssueTracker的对象之间的createIssue
。
Now the function should be called with the expected parameters. 现在应该使用期望的参数调用该函数。 The reason why the parent argument seems to be missing is the very special implementation of the default resolver.
父参数似乎缺失的原因是默认解析器的非常特殊的实现。 The resolver is intended to work with an object oriented style where fields can be fields or methods.
解析器旨在使用面向对象的样式,其中字段可以是字段或方法。 You can imagine the resolver to work like this:
您可以想象解析器的工作方式如下:
defaultResolver(fieldName, parent, args, context, info) {
if (typeof parent !== 'object') {
throw "Need object to default resolve";
}
if (typeof parent[fieldName] === 'function') {
return parent[fieldName](args, context, info);
}
return parent[fieldName];
}
This would allow you to write your data access objects in the following manner: 这将允许您以下列方式编写数据访问对象:
class IssueTracker {
issues = []
async createIssue(args, ctx, info) {
const issue = await createIssue(args.request);
this.issues.push(issue);
return issue;
}
}
const issueTracker = new IssueTracker();
export default {
// ...
Mutation: {
// ...
IssueTracker: () => issueTracker,
},
IssueTrackerMutation: {
createIssue: IssueTracker.createIssue
}
};
This is not talked about that much but is probably relatively close how GraphQL at Facebook works. 这并没有被讨论太多,但可能相对接近Facebook的GraphQL如何工作。 The community seems to move more logic into the resolvers.
社区似乎将更多的逻辑转移到解析器中。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.