是否可以使用 Graphql 和 Sequelize 进行多租户?
Is it possible to do a multi tenancy with Graphql and Sequelize?
我有一个关于 GraphQl 和多租户的相当棘手的问题。
假设有 3 个 table,OWNER,HOUSE 和 TENANTS.我将在 Sequelize 和 GraphQl 伪代码中描述它们:
业主table(拥有多个房屋和多个租户)
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'}})
}
房子table(属于业主,有多个租户)
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'}})
}
Tenant table(属于业主和房子)
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
查询会是什么样子?
提前致谢。
除非我遗漏了什么,否则您的 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 只是其中的第一项,因为我们的字段代表单个对象而不是列表。如果你不想使用async/await,你也可以这样做:
return owner.getHouses({ where: { id: houseId } })
.then(houses => houses[0])
还值得一提的是,这种模式模式违反了惯例。与其使用 houses
字段、houseById
字段、houseBySomeOtherArg
字段等,不如考虑使用一个或多个参数公开单个 houses
字段,例如 id
、name
或您要提供的任何过滤条件。然后,您的字段可以根据传入的任何参数过滤房屋,如果没有提供过滤参数,则 return 所有结果。
我有一个关于 GraphQl 和多租户的相当棘手的问题。
假设有 3 个 table,OWNER,HOUSE 和 TENANTS.我将在 Sequelize 和 GraphQl 伪代码中描述它们:
业主table(拥有多个房屋和多个租户)
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'}})
}
房子table(属于业主,有多个租户)
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'}})
}
Tenant table(属于业主和房子)
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
查询会是什么样子?
提前致谢。
除非我遗漏了什么,否则您的 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 只是其中的第一项,因为我们的字段代表单个对象而不是列表。如果你不想使用async/await,你也可以这样做:
return owner.getHouses({ where: { id: houseId } })
.then(houses => houses[0])
还值得一提的是,这种模式模式违反了惯例。与其使用 houses
字段、houseById
字段、houseBySomeOtherArg
字段等,不如考虑使用一个或多个参数公开单个 houses
字段,例如 id
、name
或您要提供的任何过滤条件。然后,您的字段可以根据传入的任何参数过滤房屋,如果没有提供过滤参数,则 return 所有结果。