如何在 graphql 突变中设置多对多关系?
how to set many-to-many relation in graphql mutation?
我可能遗漏了一些东西,但在 Apollo 文档中找不到任何关于在创建新条目时设置多对多关系的信息。
当关系是一对多时,只需在多方对象中设置关系一方的 ID 即可。
但让我们假装我正在使用书籍和作者,我将如何编写一个 graphql 查询来为一个(或多个?)作者创建一本书?
这应该可能发生在 GraphQL 服务器的 API 层(即模式)。对于多对多关系,您应该有一个 "join" 类型来表示 BookAuthor
多对多关系,然后向该连接类型添加一个条目。
基本上,您将拥有一个名为 Book
的类型,另一个名为 Author
,最后还有一个名为 BookAuthor
。你可以添加一些突变来管理这种关系。也许...
addToBookAuthorConnection
updateBookAuthorConnection
removeFromBookAuthorConnection
这是使用符合中继规范的常规设置 API。你可以 read more about how to structure your API for many-to-many relationships here.
然后,您只需要从 Apollo 调用 addToBookAuthorConnection
突变,就可以添加到前端的多对多连接。
希望对您有所帮助!
如果您使用具有一对多关系的 apollo 图服务器,则 connectors.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];
resolvers.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 };
我可能遗漏了一些东西,但在 Apollo 文档中找不到任何关于在创建新条目时设置多对多关系的信息。
当关系是一对多时,只需在多方对象中设置关系一方的 ID 即可。
但让我们假装我正在使用书籍和作者,我将如何编写一个 graphql 查询来为一个(或多个?)作者创建一本书?
这应该可能发生在 GraphQL 服务器的 API 层(即模式)。对于多对多关系,您应该有一个 "join" 类型来表示 BookAuthor
多对多关系,然后向该连接类型添加一个条目。
基本上,您将拥有一个名为 Book
的类型,另一个名为 Author
,最后还有一个名为 BookAuthor
。你可以添加一些突变来管理这种关系。也许...
addToBookAuthorConnection
updateBookAuthorConnection
removeFromBookAuthorConnection
这是使用符合中继规范的常规设置 API。你可以 read more about how to structure your API for many-to-many relationships here.
然后,您只需要从 Apollo 调用 addToBookAuthorConnection
突变,就可以添加到前端的多对多连接。
希望对您有所帮助!
如果您使用具有一对多关系的 apollo 图服务器,则 connectors.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];
resolvers.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 };