首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >是否可以使用Graphql和Sequelize进行多租户操作?

问是否可以使用Graphql和Sequelize进行多租户操作?
EN

Stack Overflow用户
提问于 2019-04-30 03:16:26
回答 1查看 1.2K关注 0票数 0

关于GraphQl和多租户,我有一个相当棘手的问题。

让我们假设有3个表,OWNER、HOUSE和 there 。我将在Sequelize和GraphQl伪代码中描述它们:

所有者表(有多个房屋和多个租户)

代码语言:javascript
复制
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'}})
}

房屋表(属于业主并有多个租户)

代码语言:javascript
复制
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'}})
}

房客表(属于业主和房屋)

代码语言:javascript
复制
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对象

代码语言:javascript
复制
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查询:

代码语言:javascript
复制
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()
  }
}

这些客户端查询可以工作:

代码语言:javascript
复制
{
  ownerById(ownerId: 1) {
    ownerId
    name
    house {
      houseId
      name
    }
  }
}

{
  houseById(houseId: 2) {
    houseId
    name
    tenant {
      tenantId
      name
    }
  }
}

我需要做的多租户工作是这样的:

代码语言:javascript
复制
{
  ownerById(ownerId: 1) {
    ownerId
    name
    houseById(houseId: 2) {
      houseId
      name
      tenant {
        tenantId
        name
      }
    }
  }
}

是否有一种方法对此进行存档,还是超出了GraphQl的范围?

如果是,graphql对象houseById查询会是什么样子?

提前谢谢。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2019-04-30 12:17:40

除非我遗漏了什么,否则您的houseById解析器似乎与同一类型的houses字段的解析器没有什么不同。

代码语言:javascript
复制
houseById: {
  type: HouseType,
  args: {
    houseId: { type: GraphQLInt },
  },
  async resolve(owner, { houseId }) {
    const houses = await owner.getHouses({ where: { id: houseId } })
    return houses[0]
  }
},

对于HasMany关联,目标模型的getter解析为实例数组。因此,我们需要先获取该数组,然后返回其中的第一项,因为我们的字段表示的是单个对象,而不是列表。如果不想使用异步/等待,也可以这样做:

代码语言:javascript
复制
return owner.getHouses({ where: { id: houseId } })
  .then(houses => houses[0])

还值得一提的是,模式的这种模式不符合约定。与其拥有houses字段、houseById字段、houseBySomeOtherArg字段等,不如考虑公开一个houses字段,其中包含一个或多个参数,如id、name或任何希望提供的筛选条件。然后,您的字段可以根据传入的任何参数过滤房屋,或者如果没有提供筛选参数,则返回所有结果。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/55913500

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档