bey*_*ode 6 c# rest entity-framework asp.net-web-api
在我们的ASP.net Web API背后,我们有一个代码第一实体框架模型.考虑以下(简化)实体:
public class Form
{
public long Id { get; set; }
public string Identifier { get; set; }
public virtual FormGroup Group { get; set; }
}
public class FormGroup
{
public long Id { get; set; }
public string Identifier { get; set; }
public virtual ICollection<Form> Forms { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
正如您所看到的,FormGroups和Forms之间存在1-Many关系.我的问题是,如何设计一个RESTful API,允许我们更改表单所属的组?
到目前为止,我已经提出了两种可能的方法,每种方法都有利弊:
将关系表示为链接结构:
{
"Id" : 1,
"Identifier" : "Form1",
"link" : {
"rel": "http://myapi/res/formgroup",
"href": "http://myapi/formgroups/1"
}
}
Run Code Online (Sandbox Code Playgroud)
优点:
缺点:
使用PUT将资源链接在一起
data: {
"Id" : 1,
"Identifier" : "Form1"
}
PUT data to http://myapi/formgroups/1/forms
Run Code Online (Sandbox Code Playgroud)
优点:
缺点:
我对这些方法中的任何一种都不是特别满意,因为它们似乎都比正面有更多的缺点.
我知道一个'正确'的解决方案是实现DTO并从我的资源表示中分离我的实体模型,这将允许我添加一个我可以设置的FormGroupId.
像所有优秀的程序员一样,我很想知道这是如何在RESTful API中工作的.我还想要一个解决方案,我可以一般地应用于我的模型中的任何导航属性.
明信片上的答案......这些方法中的任何一种是否有效,或者是否存在我错过的其他方式?
皮特
基于数据模型构建 API 只会限制您的整体设计。我倾向于从我的陈述中进行回溯。
通过完全控制您的表达,您可以随心所欲地表达关系。例如,您可能决定在您的FormGroup陈述中包含您的陈述Form:
GET /api/forms/1
{
"Id" : 1,
"Name" : "Form 1",
"FormGroup" : {
"Id" : 1,
"Name" : "Form Group 1"
}
}
Run Code Online (Sandbox Code Playgroud)
或者在表示中包含表格FormGroup:
GET /api/formgroups/1
{
"Id" : 1,
"Name" : "Form Group 1",
"Forms" : [
{
"Id" : 1,
"Name" : "Form 1"
},
{
"Id" : 2,
"Name" : "Form 2"
}
]
}
Run Code Online (Sandbox Code Playgroud)
事实上你可以两者都做。只需确保每个资源只有一个 URI 标识符即可。
如果您确实想采用 REST 并在 API 响应中包含超媒体链接,我建议您查看超文本应用程序语言(HAL)。HAL 提供了表达资源之间相关链接的约定。例如:
{
"_links" : {
"self" : { "href" : "/api/forms/1" },
"related" : { "href" : "/api/formgroups/1" }
}
"Id" : 1,
"Name" : "Form 1",
"FormGroupId" : 1
}
Run Code Online (Sandbox Code Playgroud)
希望您能够看到,您如何表示资源并不决定您如何管理它们之间的关系。
如何做到这一点在很大程度上取决于您的场景中的逻辑,并且通常可以通过确定谁拥有该关系来提供帮助。
举个典型的Blog Post .* Comments例子。评论本身没有什么意义。如果我要设计一个 API 来管理博客评论,我可能会这样做:
POST /posts/1/comments - Add a comment to post 1
DELETE /posts/1/comments/1 - Remove comment 1 from post 1
Run Code Online (Sandbox Code Playgroud)
请注意,评论确实具有身份,但仅限于博客文章的上下文中。
就你的情况而言(根据我们在 Twitter 上的讨论),你说Forms确实在FormGroup. 您还说您可以拥有孤儿形式 - 那些不属于某个组的形式。
FormGroup考虑到这一点,通过资源管理关系就有意义了Form。FormGroupId最简单的方法是在对表单资源执行 POST 或 PUT 时设置/更新属性。如果(这又取决于您的场景),您需要能够在FormGroup不更新资源上的任何其他属性的情况下进行更改Form,您可能希望发送 PATCH 或创建“子资源”来管理关系:
POST /api/forms/1/group -- set the form group for forms/1
{
"formGroupId" : 10
}
DELETE /api/forms/1/group -- unlink forms/1 from its group
Run Code Online (Sandbox Code Playgroud)
不幸的是,没有“正确的方法”来表示资源之间的关系。我的建议是选择感觉最自然的方式。
| 归档时间: |
|
| 查看次数: |
2149 次 |
| 最近记录: |