[英]Context not being passed to nested Apollo GraphQL resolver
我正在為我的項目使用Apollo Server v2
我添加了auth,就像這里給出的https://www.apollographql.com/docs/apollo-server/features/authentication/
我想在我的Query
和Mutation
包含嵌套的解析器,所以我按照https://stackoverflow.com/a/40916089/7584077進行了操作
事情是我的解析器比上面顯示的更復雜
// 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
}
`;
並且上面的一個lil修改版本的stackoverflow回答。 這是我的組合解析器。
// resolvers/resolvers.js
import IssueTracker from "./issueTracker";
export default {
Query: {
ping: () => "ping!",
IssueTracker: () => ({
ping: IssueTracker.ping,
}),
},
Mutation: {
ping: () => "ping!",
IssueTracker: () => ({
createIssue: IssueTracker.createIssue,
}),
},
};
這是因為我希望Query & Mutation完全分開。
這是我的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
}
事情就是這樣, parent
實際上是args
領域! 我需要來自上下文的userId來制作合理的數據。
嗯,SDL的第一種方法可能有點棘手。 解釋這里出了什么問題並不容易,但我會盡力而為。 首先讓我告訴你需要做些什么來完成這項工作然后我會解釋出了什么問題。
在解析器映射中創建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
}
};
注意為IssueTracker創建“純”解析器和使用createIssue
方法返回IssueTracker的對象之間的createIssue
。
現在應該使用期望的參數調用該函數。 父參數似乎缺失的原因是默認解析器的非常特殊的實現。 解析器旨在使用面向對象的樣式,其中字段可以是字段或方法。 您可以想象解析器的工作方式如下:
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];
}
這將允許您以下列方式編寫數據訪問對象:
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
}
};
這並沒有被討論太多,但可能相對接近Facebook的GraphQL如何工作。 社區似乎將更多的邏輯轉移到解析器中。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.