休息资源分离
Rest resource separation
假设我们有一个 api enpoint 来处理超级英雄资源:
api/superheroes POST
- 创建英雄
api/superheroes/{id} GET
- 获取英雄
资源模型如下:
public class SuperHero
{
public int Id { get; set; }
public string Name { get; set; }
public int Age { get; set; }
}
现在一个产品负责人说他们想介绍超级英雄团队。截至目前,给定的团队有一个名字和至少一个英雄。我可以看到两个选项可以继续。
1) 直截了当
引入新资源:
api/teams POST - creates a team
资源模型如下所示:
public class Team
{
public int Id { get; set; }
public string Name { get; set; }
public IEnumerable<int> SuperHeroes { get; set; }
}
这样 api 用户将发送一个创建团队的请求。超级英雄列表必须指定且非空
2) 重新审视要求
什么是
team has a name and at least one hero attached
究竟是什么意思?
好吧,没有英雄,团队肯定还没有准备好拯救世界。但这是它存在的障碍吗?我们真的需要阻止用户创建一个没有英雄的团队吗?
让我们分别介绍一个团队和附属的超级英雄作为资源和子资源:
api/teams
POST
- 创建一个带有名称和空成员列表的团队
public class Team
{
public string Id { get; set; }
public string Name { get; set; }
//potentially other team properties
}
api/teams/superheroes
POST
- 将英雄加入队伍
public class TeamSuperhero
{
public string SuperheroId { get; set; }
//potentially other properties related to the fact of attach itself
}
我的感觉是第二种方法有助于端点的简单性和责任分离。从性能的角度来看也可能更好,因为获取团队可能并不意味着用户需要关联的超级英雄列表。同时,它迫使 api 消费者使用两个调用而不是一个调用来创建一个准备就绪的团队。
这里应该问哪些额外的问题才能选择正确的选项?
创建团队
创建团队时,您可以允许消费者向其添加英雄:
POST /api/teams HTTP/1.1
Host: example.org
Content-Type: application/json
{
"name": "justice-league",
"heroes": [
"batman",
"superman",
"wonder-woman"
]
}
将英雄附加到团队
要将 英雄 添加到 团队 ,您可以:
POST /api/teams/avengers/heroes HTTP/1.1
Host: example.org
Content-Type: application/json
{
"value": [
"captain-america",
"iron-man"
]
}
在语义上将成员附加到集合的位置。
替换团队的英雄:
PUT /api/teams/avengers/heroes HTTP/1.1
Host: example.org
Content-Type: application/json
{
"value": [
"captain-america",
"iron-man",
"hulk",
"thor"
]
}
你也可以考虑:
PUT /api/heroes/harley-quinn/team HTTP/1.1
Host: example.org
Content-Type: application/json
{
"value": "suicide-squad"
}
在语义上替换 hero 所属的 team。
从团队
分离英雄
要从团队中删除英雄,您可以:
DELETE /api/teams/avengers/heroes/iron-man HTTP/1.1
Host: example.org
甚至:
DELETE /api/heroes/iron-man/team HTTP/1.1
Host: example.org
请记住,您的持久性模型不需要像您的 API 模型。
假设我们有一个 api enpoint 来处理超级英雄资源:
api/superheroes POST
- 创建英雄api/superheroes/{id} GET
- 获取英雄
资源模型如下:
public class SuperHero
{
public int Id { get; set; }
public string Name { get; set; }
public int Age { get; set; }
}
现在一个产品负责人说他们想介绍超级英雄团队。截至目前,给定的团队有一个名字和至少一个英雄。我可以看到两个选项可以继续。
1) 直截了当
引入新资源:
api/teams POST - creates a team
资源模型如下所示:
public class Team
{
public int Id { get; set; }
public string Name { get; set; }
public IEnumerable<int> SuperHeroes { get; set; }
}
这样 api 用户将发送一个创建团队的请求。超级英雄列表必须指定且非空
2) 重新审视要求
什么是
team has a name and at least one hero attached
究竟是什么意思? 好吧,没有英雄,团队肯定还没有准备好拯救世界。但这是它存在的障碍吗?我们真的需要阻止用户创建一个没有英雄的团队吗?
让我们分别介绍一个团队和附属的超级英雄作为资源和子资源:
api/teams
POST
- 创建一个带有名称和空成员列表的团队public class Team { public string Id { get; set; } public string Name { get; set; } //potentially other team properties }
api/teams/superheroes
POST
- 将英雄加入队伍public class TeamSuperhero { public string SuperheroId { get; set; } //potentially other properties related to the fact of attach itself }
我的感觉是第二种方法有助于端点的简单性和责任分离。从性能的角度来看也可能更好,因为获取团队可能并不意味着用户需要关联的超级英雄列表。同时,它迫使 api 消费者使用两个调用而不是一个调用来创建一个准备就绪的团队。
这里应该问哪些额外的问题才能选择正确的选项?
创建团队
创建团队时,您可以允许消费者向其添加英雄:
POST /api/teams HTTP/1.1
Host: example.org
Content-Type: application/json
{
"name": "justice-league",
"heroes": [
"batman",
"superman",
"wonder-woman"
]
}
将英雄附加到团队
要将 英雄 添加到 团队 ,您可以:
POST /api/teams/avengers/heroes HTTP/1.1
Host: example.org
Content-Type: application/json
{
"value": [
"captain-america",
"iron-man"
]
}
在语义上将成员附加到集合的位置。
替换团队的英雄:
PUT /api/teams/avengers/heroes HTTP/1.1
Host: example.org
Content-Type: application/json
{
"value": [
"captain-america",
"iron-man",
"hulk",
"thor"
]
}
你也可以考虑:
PUT /api/heroes/harley-quinn/team HTTP/1.1
Host: example.org
Content-Type: application/json
{
"value": "suicide-squad"
}
在语义上替换 hero 所属的 team。
从团队
分离英雄要从团队中删除英雄,您可以:
DELETE /api/teams/avengers/heroes/iron-man HTTP/1.1
Host: example.org
甚至:
DELETE /api/heroes/iron-man/team HTTP/1.1
Host: example.org
请记住,您的持久性模型不需要像您的 API 模型。