我应该如何组织端点 RESTful?

How should I organize endpoints to be RESTful?

假设我的 API 中有两种类型的资源:personclass。这两个是多对多的关系。

因此,我希望能够与以下端点交互:

  1. /api/persons/1/classes -- 此人的 classes 列表
  2. /api/classes/1/persons -- class.
  3. 中的人员列表

在我的代码中组织这些内容的最佳方式是什么?

以下是我想到的一些可能的选择,但我可以看到每个选择的缺点。 (使用 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 服务,看起来也很恶心。

我想我已经决定路由 /api/persons/{personId}/classes 实际上应该由 ClassController.cs class 处理,即使它描述的是一个人的资源......但我仍然不确定这是否是最好的做法。

这种情况的最佳做法是什么?我是否漏掉了一些明显的东西?

我不会浪费太多时间尝试构建有史以来最漂亮的 API。我认为在您的 Person 控制器中使用 ClassService 没有任何问题。如果您打算尝试限制自己只使用与您的控制器同名的服务,那么您将花费大量时间来尝试解决一些不可避免的问题。

而且我也认为服务class在处理主题时应该只是一个帮手class。因此,如果您需要获取按特定字段过滤的 classes 的列表,那么该逻辑应该在 ClassService 中。只要你认为别人不会因为看你的代码而感到困惑,那你就没问题。

旁注:

我看到的唯一小问题是您的资源名称。我曾研究过类似主题的 API。我最终将 classes 更改为 lectures,因为 class 是大多数面向对象语言中的保留字,并且我将 person 切换为 student 因为复数化可能会有点棘手。