2017-03-01 6 views
2

저는 javascript에 상당히 익숙하며 현재 Node.js를 사용하여 MongoDB 백엔드로 graphQL API를 구현하는 방법을 배우고 있습니다. 두 가지 유형 사이에 순환 종속성 문제가 발생했습니다.GraphQL circular dependency

기본적으로 나는 고전적인 블로그 게시물/블로그 작성자 상황이 있습니다. 게시물에는 한 명의 작성자 만 있으므로 몽구스 스키마에는 해당 작성자에 대한 참조가 있습니다.

내 GraphQL 유형 "작성자"에서 작성자가 작성한 모든 게시물로 이동할 수있는 "게시물"필드를 추가하고 싶습니다. 참조는 데이터베이스 모델에서는 코드화되지 않지만 컨트롤러를 통해 검색됩니다. 여기 내 블로그 게시물 코드가 있습니다.

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 파일은 컨트롤러를 처리하는 기능 만 내 보냅니다.

  1. 내가 필드 필드를 반환하는 함수를 사용 :

    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) 
          } 
         } 
        } 
    }); 
    

    은 이미 시도 여기에 두 가지가있어 다음과 같이

    내 저자 유형이 정의된다. 나는 이것이 썽크 또는 폐쇄라고 생각합니다.

  2. 필드를 반환하는 함수에 PostType이 필요합니다. ./post와 다른 ./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 
+0

'fields :() => ({_id : ..., author : ...})'와 같은 필드를 정의하려고하면 어떻게됩니까? – piotrbienias

+0

그런 다음 파일 상단에'var PostType = require ("./ post");를 넣고 대신 다른 클래스에 오류를 가져와야합니다. 출력은'PostType.author 필드 타입은 출력 타입이어야하지만 got : undefined '이어야하며 이상하게도 GraphQL 스키마 생성을 가리 킵니다. – Bastian

+0

그런 다음 다른 함수를 추가하여 정의 된대로 함수를 사용하여 PostType의 필드를 검색하면 동일한 오류가 발생합니다. – Bastian

답변

4

이 오히려 모듈의 일반적인 문제 순환 종속성 - 당신은이 질문에 How to deal with cyclic dependencies in Node.js를 참조 할 수 있습니다. 이 경우 GraphQL과 아무 관련이 없습니다.

module.exports = { PostType }AuthorType에서 var PostType = require('./post')을 수행 하시겠습니까? var PostType = require('./post').PostType이 아니십니까? 나는 이것이 당신이 얻을 아래 오류의 원인입니다 가정 :

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

때문에 당신의 PostType 지금 { PostType: ... } 아닌 GraphQLObjectType 인스턴스입니다.

+0

고맙습니다. PostType은 실제로 고정 된 유형이었습니다. 그러나 문제는 아니었다. 귀하의 링크는 다음과 같은 정답으로 연결됩니다 : 요구 사항 명세서가 어떤 것을 가져 오기 전에 내보내기가 정의되어 있는지 확인하십시오. (나는 바꿔 말하고있다.) 고마워. – Bastian

3

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입니다. 이렇게하면 요구가 호출되기 전에 내보내기가 정의됩니다.

감사합니다.

+2

이것은 나를위한 해결책입니다 - 열쇠는'fields' 매개 변수에 콜백 함수를 사용하고 그 함수에 require()를 넣는 것입니다. –

+0

이것은 "썽크"로 알려진 패턴입니다. –