草庐IT

javascript - GraphQL 循环依赖

coder 2025-02-16 原文

我是 javascript 的新手,目前正在学习使用 Node.js 实现带有 MongoDB 后端的 graphQL API。我遇到了两种类型之间循环依赖的问题。

基本上,我有一个经典的博客文章/博客作者情况。一篇文章只有一位作者,因此 mongoose 架构包含对该作者的引用。

在我的 graphQL 类型“作者”中,我想添加一个字段“帖子”,它允许我从作者导航到他们写的所有帖子。该引用未在数据库模型中编码,而是通过 Controller 检索。这是我的博文代码。

var graphql = require("graphql");
var AuthorResolvers = require("../resolvers/author");
var PostResolvers = require("../resolvers/post");
var AuthorType = require("./author").AuthorType;

var PostType = new graphql.GraphQLObjectType({
  name: "PostType",
  fields: {
        _id: {
            type: graphql.GraphQLID
        },
        title: {
            type: graphql.GraphQLString
        },
        author: {
            type: AuthorType,
            description: "Author of this post",
            resolve: (post) => AuthorResolvers.retwArgs(post)
        }
    }
});

module.exports = {PostType};

resolvers.js 文件仅导出函数以寻址 Controller 。

我的作者类型定义如下:

var graphql = require ("graphql");
var AuthorResolvers = require("../resolvers/author");
var PostResolvers = require("../resolvers/post");

var AuthorType = new graphql.GraphQLObjectType({
  name: "AuthorType",
  fields: () => {
        var PostType = require("./post");
        return {
            _id: {
                type: graphql.GraphQLID
            },
            name: {
                type: graphql.GraphQLString
            },
            posts: {
                type: new graphql.GraphQLList(PostType),
                description: "Posts written by this author",
                resolve: (author) => PostResolvers.retwArgs(author)
            }
        }
    }
});

这里有两件事我已经尝试过了:

  1. 我使用了一个函数来返回 fields 字段。我认为这称为 thunk 或闭包。
  2. 我需要返回字段的函数中的 PostType。当我需要文件 ./post 和其他需要时,错误已经在文件顶部抛出。

当我尝试运行这个服务器示例时,我收到错误:

Can only create List of a GraphQLType but got: [object Object].

指向直线

type: new graphql.GraphQLList(PostType)

在作者中。

包含上面发布的类型定义的文件也导出这样的查询:

var PostQuery = {
    posts: {
        type: new graphql.GraphQLList(PostType),
        description: "Posts of this Blog",
        resolve: PostResolvers.ret
    }
};

对于帖子和喜欢这个

var AuthorQuery = {
    authors: {
        type: new graphql.GraphQLList(AuthorType),
        description: "The authors working on this Blog",
        resolve: AuthorResolvers.ret
    }
};

分别为作者。所有内容都集中在一个架构文件中,如下所示:

var graphql = require("graphql");
var Author = require("./types/author").AuthorQuery;
var Post = require("./types/post").PostQuery;

var root_query = new graphql.GraphQLObjectType({  
  name: "root_query",
  fields: {
    posts: Post.posts,
    authors: Author.authors
  }
});

module.exports = new graphql.GraphQLSchema({
  query: root_query
});

最后是服务器:

var graphql = require ('graphql').graphql  
var express = require('express')  
var graphQLHTTP = require('express-graphql')
var Schema = require('./api/schema')

var app = express()
  .use("/", graphQLHTTP(
    {
      schema: Schema,
      pretty: true,
      graphiql: true,
    }
  ))
  .listen(4000, function(err) {
    console.log('Running a GraphQL API server at localhost:4000');
  })

我真的看不出有什么办法可以解决这种循环依赖。如果我简单地注释掉 AuthorType 定义中对 PostType 的引用,服务器将毫无问题地启动。此处的任何帮助将不胜感激。

也许是为了更好地理解。目录结构如下所示:

│   package.json
│   server.js
│
├───api
│   │   schema.js
│   │
│   ├───controllers
│   │       author.js
│   │       post.js
│   │
│   ├───models
│   │       author.js
│   │       post.js
│   │
│   ├───resolvers
│   │       author.js
│   │       post.js
│   │
│   └───types
│           author.js
│           post.js
│
└───config
        db.js

最佳答案

piotrbienias 的回复让我找到了正确的话题。我以前读过,但没有完全理解。在你需要类之前定义导出是必要的。就我而言,我能够像这样修复它:

module.exports.AuthorType = new graphql.GraphQLObjectType({
  name: "AuthorType",
  fields: () => {
        var PostType = require("./post").PostType;
        return {
            _id: {
                type: graphql.GraphQLID
            },
            name: {
                type: graphql.GraphQLString
            },
            posts: {
                type: new graphql.GraphQLList(PostType),
                description: "Posts written by this author",
                resolve: (author) => PostResolvers.retwArgs(author)
            }
        }
    }
});

和 PostType 类似。这样,在调用 require 之前定义导出。

非常感谢!

关于javascript - GraphQL 循环依赖,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42531322/

有关javascript - GraphQL 循环依赖的更多相关文章

  1. ruby - 树顶语法无限循环 - 2

    我脑子里浮现出一些关于一种新编程语言的想法,所以我想我会尝试实现它。一位friend建议我尝试使用Treetop(Rubygem)来创建一个解析器。Treetop的文档很少,我以前从未做过这种事情。我的解析器表现得好像有一个无限循环,但没有堆栈跟踪;事实证明很难追踪到。有人可以指出入门级解析/AST指南的方向吗?我真的需要一些列出规则、常见用法等的东西来使用像Treetop这样的工具。我的语法分析器在GitHub上,以防有人希望帮助我改进它。class{initialize=lambda(name){receiver.name=name}greet=lambda{IO.puts("He

  2. ruby-on-rails - 在 Ruby 中循环遍历多个数组 - 2

    我有多个ActiveRecord子类Item的实例数组,我需要根据最早的事件循环打印。在这种情况下,我需要打印付款和维护日期,如下所示:ItemAmaintenancerequiredin5daysItemBpaymentrequiredin6daysItemApaymentrequiredin7daysItemBmaintenancerequiredin8days我目前有两个查询,用于查找maintenance和payment项目(非排他性查询),并输出如下内容:paymentrequiredin...maintenancerequiredin...有什么方法可以改善上述(丑陋的)代

  3. ruby-on-rails - 在 ruby​​ .gemspec 文件中,如何指定依赖项的多个版本? - 2

    我正在尝试修改当前依赖于定义为activeresource的gem:s.add_dependency"activeresource","~>3.0"为了让gem与Rails4一起工作,我需要扩展依赖关系以与activeresource的版本3或4一起工作。我不想简单地添加以下内容,因为它可能会在以后引起问题:s.add_dependency"activeresource",">=3.0"有没有办法指定可接受版本的列表?~>3.0还是~>4.0? 最佳答案 根据thedocumentation,如果你想要3到4之间的所有版本,你可以这

  4. ruby - RuntimeError(自动加载常量 Apps 多线程时检测到循环依赖 - 2

    我收到这个错误:RuntimeError(自动加载常量Apps时检测到循环依赖当我使用多线程时。下面是我的代码。为什么会这样?我尝试多线程的原因是因为我正在编写一个HTML抓取应用程序。对Nokogiri::HTML(open())的调用是一个同步阻塞调用,需要1秒才能返回,我有100,000多个页面要访问,所以我试图运行多个线程来解决这个问题。有更好的方法吗?classToolsController0)app.website=array.join(',')putsapp.websiteelseapp.website="NONE"endapp.saveapps=Apps.order("

  5. ruby - Ruby 中的闭包和 for 循环 - 2

    我是Ruby的新手,有些闭包逻辑让我感到困惑。考虑这段代码:array=[]foriin(1..5)array[5,5,5,5,5]这对我来说很有意义,因为i被绑定(bind)在循环之外,所以每次循环都会捕获相同的变量。使用每个block可以解决这个问题对我来说也很有意义:array=[](1..5).each{|i|array[1,2,3,4,5]...因为现在每次通过时都单独声明i。但现在我迷路了:为什么我不能通过引入一个中间变量来修复它?array=[]foriin1..5j=iarray[5,5,5,5,5]因为j每次循环都是新的,我认为每次循环都会捕获不同的变量。例如,这绝对

  6. ruby-on-rails - 使用 javascript 更改数据方法不会更改 ajax 调用用户的什么方法? - 2

    我遇到了一个非常奇怪的问题,我很难解决。在我看来,我有一个与data-remote="true"和data-method="delete"的链接。当我单击该链接时,我可以看到对我的Rails服务器的DELETE请求。返回的JS代码会更改此链接的属性,其中包括href和data-method。再次单击此链接后,我的服务器收到了对新href的请求,但使用的是旧的data-method,即使我已将其从DELETE到POST(它仍然发送一个DELETE请求)。但是,如果我刷新页面,HTML与"new"HTML相同(随返回的JS发生变化),但它实际上发送了正确的请求类型。这就是这个问题令我困惑的

  7. ruby - 有什么方法可以告诉 sidekiq 一项工作依赖于另一项工作 - 2

    有什么方法可以告诉sidekiq一项工作依赖于另一项工作,并且在后者完成之前无法开始? 最佳答案 仅使用Sidekiq;答案是否定的。正如DickieBoy所建议的那样,您应该能够在依赖作业完成时将其启动。像这样。#app/workers/hard_worker.rbclassHardWorkerincludeSidekiq::Workerdefperform()puts'Doinghardwork'LazyWorker.perform_async()endend#app/workers/lazy_worker.rbclassLaz

  8. Ruby:数组中的下一个/上一个值,循环数组,数组位置 - 2

    假设我有一个没有特定顺序的随机数数组。假设这些是参加马拉松比赛的人的ID#,他们按照完成的顺序添加到数组中,例如:race1=[8,102,67,58,91,16,27]race2=[51,31,7,15,99,58,22]这是一个简化且有些做作的示例,但我认为它传达了基本思想。现在有几个问题:首先,我如何获得特定条目之前和之后的ID?假设我正在查看运行者58,我想知道谁在他之前和之后完成了比赛。race1,runner58:previousfinisher=67,nextfinisher=91race2,runner58:previousfinisher=99,nextfinishe

  9. ruby - 在 Mechanize 中使用 JavaScript 单击链接 - 2

    我有这个:AccountSummary我想单击该链接,但在使用link_to时出现错误。我试过:bot.click(page.link_with(:href=>/menu_home/))bot.click(page.link_with(:class=>'top_level_active'))bot.click(page.link_with(:href=>/AccountSummary/))我得到的错误是:NoMethodError:nil:NilClass的未定义方法“[]” 最佳答案 那是一个javascript链接。Mechan

  10. ruby - 奇怪的 ruby​​ for 循环行为(为什么这样做有效) - 2

    defreverse(ary)result=[]forresult[0,0]inaryendresultendassert_equal["baz","bar","foo"],reverse(["foo","bar","baz"])这行得通,我想了解原因。有什么解释吗? 最佳答案 如果我使用each而不是for/in重写它,它看起来像这样:defreverse(ary)result=[]#forresult[0,0]inaryary.eachdo|item|result[0,0]=itemendresultendforainb基本上就

随机推荐