【问题标题】:REST Api Endpoints design for related and nested resources [closed]针对相关和嵌套资源的 REST Api 端点设计 [关闭]
【发布时间】:2023-03-18 02:35:02
【问题描述】:

我正在创建一个 REST API,并且我有,例如,作者和帖子。

所以我可以通过以下方式获取作者发布的帖子:

/authors/123/posts

或者

/posts?authorId=123

我认为构建灵活的 API 可能是更好的选择。要获得作者的帖子,我会这样做:

/posts?authorId=123&published=true&sort=created&expand=tags,category

所以在这种情况下,我会从 authorId=123 获取所有发布的帖子,按创建日期对它们进行排序,并获取每个帖子的标签和类别。

基本上,我创建了一种映射到每个数据库表的查询语言。

然后对于常见的查询,我创建特定的端点:

/posts/recent

将独立于作者返回最近的帖子...

我认为/authors/123/posts 在使用多个级别时可能会变得复杂。

你怎么看?

更新

经过几个回答,我的想法如下:

当帖子和作者是我将拥有的两个资源时(例如帖子):

GET /posts?authorId=123&published=true
POST /posts
PUT /posts
DELETE /posts/123

如果帖子和作者之间存在分层依赖关系,并且我经常需要作者的帖子,我还会添加以下内容:

GET /authors/123/posts&published=true

如果帖子在资源作者之外不存在,则前面的 2 个选项将替换为:

GET /authors/123/posts?published=true
POST /authors/123/posts
PUT /authors/123/posts
DELETE /authors/123/posts/123

你怎么看?

【问题讨论】:

  • 您可以使用属性路由使您的 Web API 变得灵活,请参阅 asp.net/web-api/overview/web-api-routing-and-actions/…asp.net/web-api/overview/web-api-routing-and-actions/…
  • 是的,我正在使用 AttributeRouting。问题是哪种方法更好?或者两者兼而有之?
  • 选择属性路由,因为它使您可以使用单个控制器方法定义更多路由,从而使其灵活。
  • “我认为 /authors/123/posts 在使用多个级别时可能会变得复杂。” /authors/123/posts 是一个资源的唯一标识符(这是某个作者的所有帖子的列表),您不需要更高级别。如果您想进一步过滤结果,您将使用查询参数,即/authors/123/posts?tags=cat,dog 仅显示来自该用户的帖子。 ``/authors/123/posts/tag/cat` 在这种情况下没有多大意义,因为标签不是作者的资源,所以它不会得到任何“更大、更深”等。
  • 至于使用/authors/123/posts vs /posts?authorId=12,这取决于使用情况。如果您正在创建帖子搜索服务(即博客上的搜索框),那么/posts?authorId=12 是有意义的,因为您的意图是查询所有帖子(有或没有用户约束)。但是,如果您有一个用户列表(配置文件)并且想要创建一个显示所有这些使用帖子的链接,您可以使用/authors/123/posts,因为它更能表达它的用法。您可以在您的休息服务中使用这两种服务,一种用于搜索,另一种用于作为其个人资料或用户信息中的链接

标签: angularjs api asp.net-web-api asp.net-core


【解决方案1】:

我们在项目中使用的经验法则:使用 url 路径,例如/authors/123/posts 如果两者之间有明确的层次关系,并且您正在访问的资源不能存在于另一个的上下文之外。例如,在检索订单行时,可以直接使用/orders/123/lines,因为订单行在订单本身的上下文之外没有任何意义。

在您的情况下,帖子显然可以在其作者的上下文之外“存在”。如果您可以按作者、日期、主题……搜索帖子,那么将这些值作为查询字符串传递是有意义的。所以在我看来,/posts?authorId=123 是这里的最佳选择。

【讨论】:

  • 发布具有明确层级关系的内容时,您会做什么。例如:POST /employees/123/degrees 或者你会做 POST /degrees ...我认为对于 GET 你所说的对于 POST 我会去第二个。
  • 按照标准,我总是执行 GET /employees/123/degrees 来获取学位集合,并 POST /employees/123/degrees 来添加新学位。为了便于理解,网址应该相同。
【解决方案2】:

有一个神话,每个资源必须只有一个路径。你的两个例子都是正确的。

你的第一个例子:

/authors/123/posts.

当两者之间存在层次关系时,如果您当前的上下文是author,则访问该作者的帖子没有问题。

你的第二个例子:

/posts?authorId=123&published=true&sort=created&expand=tags,category.

查询分布在多个方面的帖子的整个存储库是有意义的。例如,在您的应用程序中,您可能有一个搜索页面来搜索帖子,这是一个完美的用例。

就模型视图而言。我们的资源就像模型,我们的 url 就像视图。没有什么能阻止我们为同一个模型使用多个视图。您只需要确保使用相同的支持代码来访问您存储的数据。查看数据的方式有多种(视图)。

总结:您可以在项目中使用这两个 url。例如,在您的作者页面上使用/authors/123/posts 列出作者的帖子,并在您的帖子搜索页面上使用/posts?authorId=123&published=true&sort=created&expand=tags,category

您也可以查看此帖子以获得类似的意见:What are best practices for REST nested resources

【讨论】:

    猜你喜欢
    • 2021-09-02
    • 2011-10-29
    • 2019-12-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-12-09
    相关资源
    最近更新 更多