簡體   English   中英

上下文未傳遞給嵌套的Apollo GraphQL解析器

[英]Context not being passed to nested Apollo GraphQL resolver

我正在為我的項目使用Apollo Server v2

我添加了auth,就像這里給出的https://www.apollographql.com/docs/apollo-server/features/authentication/

我想在我的QueryMutation包含嵌套的解析器,所以我按照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,
    }),
  },
};

這是因為我希望QueryMutation完全分開。

這是我的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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM