强调文本我对GraphQl和多租户有一个相当棘手的问题。
假设有3张桌子, OWNER , HOUSE 和 TENANTS 。我将用Sequelize和GraphQl伪代码来描述它们:
所有者表(有多个房屋和多个租户)
const OWNER = sequelize.define('owner', {
ownerId: type: Sequelize.INTEGER,
name: type: Sequelize.STRING
}
OWNER.associate = models => {
models.owner.hasMany(models.house, {foreignKey: {name: 'ownerId', field: 'ownerId'}})
models.owner.hasMany(models.tenant, {foreignKey: {name: 'ownerId', field: 'ownerId'}})
}
房屋桌子(属于所有者,有多个租户)
const HOUSE = sequelize.define('house', {
houseId: type: Sequelize.INTEGER,
ownerId: type: Sequelize.INTEGER,
name: type: Sequelize.STRING
}
HOUSE.associate = models => {
models.house.belongsTo(models.owner, {foreignKey: {name: 'ownerId', field: 'ownerId'}})
models.house.hasMany(models.tenant, {foreignKey: {name: 'houseId', field: 'houseId'}})
}
租户表(属于所有者和房屋)
const TENANT = sequelize.define('tenant', {
tenantId: type: Sequelize.INTEGER,
ownerId: type: Sequelize.INTEGER,
houseId: type: Sequelize.INTEGER,
name: type: Sequelize.STRING
}
TENANT.associate = models => {
models.tenant.belongsTo(models.owner, {foreignKey: {name: 'ownerId', field: 'ownerId'}})
models.tenant.belongsTo(models.house, {foreignKey: {name: 'houseId', field: 'houseId'}})
}
所有者graphql对象
const OwnerType = new GraphQLObjectType({
name: 'Owner',
fields: () => ({
ownerId: { type: GraphQLInt },
name: { type: GraphQLString },
houses: {
type: GraphQLList(HouseType),
resolve(owner) {
return owner.getHouse()
}
},
houseById: {
type: HouseType,
args: <args is not defined>
resolve(owner) {
return <???>
}
},
})
})
以下是一些简单的GraphQL查询:
ownerById = {
type: OwnerType,
args: {
ownerId: { type: GraphQLInt },
},
resolve(parents, args){
return models.owner.findOne({ where: args })
}
}
houses = {
type: GraphQLList(HouseType),
resolve(parents, args){
return models.house.findAll()
}
}
houseById = {
type: HouseType,
args: {
houseId: { type: GraphQLInt },
},
resolve(parents, args){
return models.house.findOne({ where: args })
}
}
tenants = {
type: GraphQLList(TenantType),
resolve(parents, args){
return models.tenant.findAll()
}
}
这些客户端查询有效:
{
ownerById(ownerId: 1) {
ownerId
name
house {
houseId
name
}
}
}
{
houseById(houseId: 2) {
houseId
name
tenant {
tenantId
name
}
}
}
我需要进行多租户工作是这样的:
{
ownerById(ownerId: 1) {
ownerId
name
houseById(houseId: 2) {
houseId
name
tenant {
tenantId
name
}
}
}
}
是否有办法对此进行存档,或者GraphQl可以超出范围?
如果是,那么graphql对象houseById
的查询将如何?
谢谢。
答案 0 :(得分:1)
除非我丢失了某些内容,否则看来houseById
的解析器与相同类型的houses
字段的解析器没有什么不同。
houseById: {
type: HouseType,
args: {
houseId: { type: GraphQLInt },
},
async resolve(owner, { houseId }) {
const houses = await owner.getHouses({ where: { id: houseId } })
return houses[0]
}
},
对于HasMany
关联,目标模型的getter解析为实例数组。因此,我们需要首先获取该数组,然后仅返回其中的第一项,因为我们的字段表示单个对象而不是列表。如果您不想使用异步/等待,也可以执行以下操作:
return owner.getHouses({ where: { id: houseId } })
.then(houses => houses[0])
值得一提的是,这种模式的模式违反了惯例。与其使用houses
字段,houseById
字段,houseBySomeOtherArg
字段等,不如考虑使用一个或多个参数,例如{{1} },houses
或您要提供的任何过滤条件。然后,您的字段可以根据传入的任何参数对房屋进行过滤,如果没有提供过滤参数,则返回所有结果。