如何在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突变中设置多对多关系?的主要内容,如果未能解决你的问题,请参考以下文章