如何在同一个请求中发布两个资源?

时间:2017-04-09 19:11:45

标签: rest

我拥有/companies/users资源。我的业务逻辑阻止了在没有第一个用户的情只有我能想到的方式:

POST /companies
{
  "name": "Harvey's Broiler",
  "user": {
    "firstName": "Jojo",
    "lastName": "Stomopolous",
    "email": "jojostomopolous@harveysbroiler.com",
    "password": "password"
  }
}

响应:

{
  "id": 10001,
  "name": "Harvey's Broiler",
  "user": {
    "id": 10002,
    "firstName": "Jojo",
    "lastName": "Stomopolous",
    "email": "jojostomopolous@harveysbroiler.com"
  }
}

稍后,它们可以通过以下方式访问:

GET /companies/10001

响应:

{
  "id": 10001,
  "name": "Harvey's Broiler"
}

GET /users/10002

GET /companies/10001/users/10002

响应:

{
  "id": 10002,
  "firstName": "Jojo",
  "lastName": "Stomopolous",
  "email": "jojostomopolous@harveysbroiler.com"
}

1 个答案:

答案 0 :(得分:1)

这是开发人员在设计API时遇到的常见问题。

您应该问自己的第一个问题是CompanyUser资源是否为同一公民?按顺序,我的意思是它们具有相同的重要性,它们是您大量操作的资源,并且在您正在构建的系统中具有独立的角色和操作?我的预感是答案是肯定的。如果答案为否,那么User只是表示Company创始人的一种方式,你没有问题,只需将User作为嵌入对象就像你已经那样。

但是,如果我的预感是正确的,您在UserCompany周围有一些业务逻辑,我会这样做,将它们分开,在不同的端点下。

如果您需要User来创建Company,请执行该逻辑。如果尝试使用缺失的Company创建User,则返回错误(HTTP响应400或其他内容)。当然,应该为用户记录。请求是这样的:

POST /companies
{
  "name": "Harvey's Broiler",
  "user": 1234
}

在同一个请求下人为地创建两个对象只会导致问题。现在您需要返回两者的状态(User已创建,但Company失败?),返回两个ID(如果您还需要添加其他信息,税务明细,则会获得第三个ID)等等。

创建UserCompany的唯一有效理由是User经常与Company一起创建,如果不是总是如此,那么需要减少API调用的次数,所以你只需要激活一次,但我不确定是不是这样。

如果您在User没有Company的情况下甚至没有,请查看您是否可以分两步修改要求或创建User / Company。首先触发对User“占位符”的请求(假设UserUser等列表中不可见,它将无效),并在创建后CompanyUser变为有效且可见,并允许其他操作。在此之前,没有User,只有占位符。 Company可以颠倒相同的逻辑。

另一件事,我不会进入这种嵌套:

GET /companies/10001/users/10002

首先,通常很难编程(你得到很多样板),这可能是一个维护噩梦。您可以将案例推断为:

GET /companies/10001/users/10002/accounts/24314/bank/address

获取创建公司的用户银行的银行地址。如果我不需要,我会犹豫是否实施这种方法。

另外,请考虑阅读HATEOAS。如果您需要这种嵌套,它可能会有所帮助。实际上,我总是鼓励在启动新API时至少考虑HATEOAS原则。