如何在graphql突变中设置多对多关系?

Posted

技术标签:

【中文标题】如何在graphql突变中设置多对多关系?【英文标题】:how to set many-to-many relation in graphql mutation? 【发布时间】:2017-10-09 02:15:57 【问题描述】:

我可能遗漏了一些东西,但在 Apollo 文档上找不到任何关于在创建新条目时设置多对多关系的方式的信息。

当关系是一对多时,就像在多方对象中设置关系的一侧的ID一样简单。

但是让我们假设我正在使用书籍和作者,我将如何编写一个 graphql 查询来为一个(或多个?)作者创建一本书?

【问题讨论】:

【参考方案1】:

这可能发生在 GraphQL 服务器的 API 层(即模式)。对于多对多关系,您应该有一个“连接”类型来表示BookAuthor 多对多关系,然后向该连接类型添加一个条目。

基本上,您将拥有一种称为Book 的类型,另一种称为Author,最后还有一种称为BookAuthor。你可以添加一些突变来管理这种关系。或许……

addToBookAuthorConnection updateBookAuthorConnection removeFromBookAuthorConnection

这是使用符合 Relay 规范的 API 的常规设置。你可以read more about how to structure your API for many-to-many relationships here。

然后,您只需从 Apollo 调用 addToBookAuthorConnection 突变,即可添加到前端的多对多连接。

希望这会有所帮助!

【讨论】:

感谢您的解释!!我应该提到我正在使用 graph.cool 作为后端。在这一点上没有挖掘他们的文档 - 愚弄我。文档在这个主题上似乎很短,但我联系了帮助台。我会在这里更新。 我在 graphiQL 自动完成功能的帮助下找到了关系的名称。非常有用,因为这些名称在我的架构中没有出现...希望对其他人有所帮助。 明白了! GraphiQL 是一个很好的工具,可以深入了解您的 API 并查看存在的内容。希望现在关系更加清晰。如果你有时间,你也应该看看Scaphold!【参考方案2】:

如果您使用具有一对多关系的 apollo 图形服务器,那么将 connector.js、resolvers.js 和 schema.js 文件作为给定格式

schema.js

const typeDefinitions = `



type Author 

  authorId: Int
  firstName: String
  lastName: String
  posts: [Post]



type Post 

  postId: Int
  title: String 
  text: String
  views: Int
  author: Author



input postInput
  title: String 
  text: String
  views: Int



type Query 

  author(firstName: String, lastName: String): [Author]
  posts(postId: Int, title: String, text: String, views: Int): [Post]





type Mutation 

createAuthor(firstName: String, lastName: String, posts:[postInput]): Author

updateAuthor(authorId: Int, firstName: String, lastName: String, posts:[postInput]): String




schema 
  query: Query
  mutation:Mutation

`;

export default [typeDefinitions];

解析器.js

import  Author  from './connectors';
import  Post  from './connectors';


const resolvers = 

  Query: 
    author(_, args) 
      return Author.findAll( where: args );
    ,
    posts(_, args) 
      return Post.findAll( where: args );
    
  ,

  Mutation: 

    createAuthor(_, args) 
      console.log(args)
      return Author.create(args, 
        include: [
          model: Post,
        ]
      );
    ,

    updateAuthor(_, args) 

      var updateProfile =  title: "name here" ;
      console.log(args.authorId)
      var filter = 
        where: 
          authorId: args.authorId
        ,
        include: [
           model: Post 
        ]
      ;
      Author.findOne(filter).then(function (product) 
        Author.update(args,  where:  authorId: args.authorId  ).then(function (result) 
          product.posts[0].updateAttributes(args.posts[0]).then(function (result) 
            //return result;
          )
        );
      )
      return "updated";
    ,

  ,


  Author: 
    posts(author) 
      return author.getPosts();
    ,
  ,
  Post: 
    author(post) 
      return post.getAuthor();
    ,
  ,
;

export default resolvers;

connectors.js

import rp from 'request-promise';
var Sequelize = require('sequelize');
var db = new Sequelize('test', 'postgres', 'postgres', 
  host: '192.168.1.168',
  dialect: 'postgres',

  pool: 
    max: 5,
    min: 0,
    idle: 10000
  

);


const AuthorModel = db.define('author', 
  authorId:  type: Sequelize.INTEGER, primaryKey: true, autoIncrement: true, field: "author_id" ,
  firstName:  type: Sequelize.STRING, field: "first_name" ,
  lastName:  type: Sequelize.STRING, field: "last_name" ,
,
        freezeTableName: false,
        timestamps: false,
        underscored: false,
        tableName: "author"
    );


const PostModel = db.define('post', 
    postId:  type: Sequelize.INTEGER, primaryKey: true, autoIncrement: true, field: "post_id" ,
  text:  type: Sequelize.STRING ,
  title:   type: Sequelize.STRING ,
  views:  type: Sequelize.INTEGER ,
,
        freezeTableName: false,
        timestamps: false,
        underscored: false,
        tableName: "post"
    );


AuthorModel.hasMany(PostModel, 
    foreignKey: 'author_id'
);
PostModel.belongsTo(AuthorModel, 
    foreignKey: 'author_id'
);

const Author = db.models.author;
const Post = db.models.post;

export  Author, Post ;

【讨论】:

明确定义字段和这样做有什么区别? AuthorModel.hasMany(PostModel, through: 'AuthorPosts' ); 我认为这段代码适用于一对多(作者)而不是多对多。

以上是关于如何在graphql突变中设置多对多关系?的主要内容,如果未能解决你的问题,请参考以下文章

GraphQL Apollo 中的多对多关系

如何使用 schema.graphql 在放大数据存储中创建多对多关系

多对多关系中的缓存更新

查询放大graphql多对多关系

具有多对多关系的类型元素的 GraphQL 解析器

GraphQL 中的多对多关系