假设我在API中有两种类型的资源:person
和class
。这两者有很多对多的关系。
因此,我希望能够与以下端点进行交互:
/api/persons/1/classes
- 此人的课程列表/api/classes/1/persons
- 此课程中的人员列表。在我的代码中组织这些内容的最佳方法是什么?
以下是我想到的一些可能的选择,但我可以看到每个选项的缺点。 (使用C#,但我的问题更普遍适用)。
PersonsController.cs
[Route("api/persons/{personId}/classes")]
[AcceptVerbs("GET")]
public List<SchoolClass> ListClassesForPerson(string personId)
{
//return result of PersonsService.ListClassesForPerson(personId)
}
在我的ClassController.cs中反其道而行。
这种方法的缺点是现在我有一个PERSON控制器和PERSON服务返回一个类列表......看起来很蠢。
替代方案可能是:
PersonsController.cs
[Route("api/persons/{personId}/classes")]
[AcceptVerbs("GET")]
public List<SchoolClass> ListClassesForPerson(string personId)
{
//return result of ClassesService.ListClassesForPerson(personId)
}
但现在我从我的PERSON控制器访问CLASS服务,看起来也很icky。
我想我已经确定路由/api/persons/{personId}/classes
实际上应该由ClassController.cs类处理,即使它描述了一个人的资源......但是我仍然不确定这是否是最好的要做的事。
这种情况的最佳做法是什么?我错过了一些明显的东西吗?
答案 0 :(得分:1)
我不会浪费太多时间来尝试构建最漂亮的API。我认为在Person控制器中使用ClassService没有任何问题。如果您打算尝试将自己限制为仅使用与控制器同名的服务,那么您将花费大量时间尝试解决不可避免的问题。
我还认为服务类在处理主题时应该只是一个帮助类。因此,如果您需要获取由特定字段筛选的类列表,那么该逻辑应该在ClassService中。只要您认为其他人不会因为查看您的代码而感到困惑,那么您就可以了。
旁注:
我看到的唯一一个小问题是你的资源名称。我曾经研究过类似主题的API。我最终将 classes 更改为讲座,因为类是大多数面向对象语言中的保留字,我将 person 切换为学生因为复数化可能会有点棘手。