【问题标题】:REST endpoint design for retrieving results in many to many relationship用于检索多对多关系结果的 REST 端点设计
【发布时间】:2017-04-25 22:50:38
【问题描述】:

我已经阅读了许多其他关于如何安静地设计多对多关系的帖子;但是,我找不到我想要的答案。

基本上,我在数据库中有 2 个表和另一个连接这 2 个表的多对多表。 为简单起见,我们称它们为:

  • 课程(CourseID, CourseName)
  • 讲师(InstructorID,InstructorName)
  • CourseInstructor(CourseID、InstructorID、lectureRoomName)(多对多)


我有两个问题:

1) 我应该如何获取 CourseInstructor 表中的所有条目。

GET /courses/instructors 正确吗? (或GET /instructors/courses 或两者兼有)

或者我应该有一个名为 /coursesinstructors 的单独端点


2) 我还希望能够通过传入 CourseName 来获取 CourseInstructor 表中的所有行。

如果我正在寻找课程,我想我通常会这样做,/courses?name=coursename。而且,我可能会使用端点/courses/{courseId}/instructors/{instructorId} 在多对多表中搜索特定条目。

因此,我很好奇这样的工作:/courses?name=coursename/instructors(这甚至可能吗?)

另一种选择是使用另一个名为/coursesinstructors 的端点,我可以使用/courseinstructor?name=coursename 来获得结果。

或者我应该通过以下方式拨打 2 次电话以获得结果: - 通过/courses?name=coursename获取id - 并关注courses/{id}/instructors

除了我上面提出的建议和解决方案之外,我对任何其他建议和解决方案持开放态度(无论如何我不确定我的解决方案是否正确)。

【问题讨论】:

    标签: rest api many-to-many relationship restful-url


    【解决方案1】:

    对于第一种情况,这实际上取决于您的用例是什么。 GET /courses/instructors 意味着(仅)检索讲师,所以我个人会选择 GET /coursesembed 讲师。

    至于第二种情况,/courses?name=coursename 应该足够好(加上/courses/{courseId}/instructors/{instructorId} 用于向下钻取到特定条目)。 2 个电话是另一个有效的选项。但是,根据RFC 3986/courses?name=coursename/instructors 这样的 URL 似乎无效。

    【讨论】:

    • 感谢您指出,由于 RFC 3986,我显示的网址无效。
    • 我是设计 REST api 的新手,之前从未嵌入过其他资源。我一定会阅读你所附的文章。所以,现在我知道我可以嵌入讲师,但是如果我想在没有任何额外讲师信息的情况下获得其他课程怎么办。如果我想在某个时候只包含课程信息,那么嵌入的额外讲师信息不会是多余的(如果我只想允许管理员提取有关课程的信息 - 讲师关系,或者未经授权)。
    • 您可以通过标题/参数(类似于/courses?includeInstructors=true)轻松控制它,通过角色(管理员)验证加倍
    【解决方案2】:

    如果您确实需要 (1),所有课程-讲师配对的完整转储,那么我认为您最好的选择是支持

    GET /course-instructors
    GET /course-instructors?courseName=whatever
    

    然后,您可以链接或嵌入课程和讲师。

    {
        "course": "/courses/12",
        "instructor": "/instructors/54"
    }
    
    {
        "course": {
            "name": "Political Science",
            ...
        },
        "instructor": {
            "name": "Hober Mallow",
            ...
        }
    }
    

    您返回的内容取决于客户的需求。也许您返回简短信息加上完整表示的链接,或者也许只返回链接是可以的,因为课程和讲师(应该!)高度可缓存。

    顺便说一句,我认为您最好不要再考虑数据库如何存储数据,而是考虑客户需要您的 API 提供什么。

    【讨论】:

    • 是的,我真的需要放弃所有配对,我开始觉得拥有 /course-instructors 对我来说是最好的。但是,这对我提出了另一个问题;我的 course-instructors m2m 表没有 courseinstructorid,因为主键为 LectureID、courseID、roomName 组合。因此,我不能支持 /course-instructors/3,这会破坏我的宁静设计(无法从端点访问单个资源);不过,我总是可以做 /course-instructors?lectureid=5&courseid=2... 可以吗?
    • 那么支持端点 /course/{courseid}/instructor/{instructorid} 呢?既然我有了端点 /course-instructors,那么保持从其他端点对同一资源的访问是好的,还是应该通过这个 /course-instructors 端点来执行与课程讲师关系相关的所有操作?
    • 作为旁注,正如您所指出的,我试图停止思考数据库如何存储数据并为我的客户需求提供更好的 API。然而,这是我的第一个 API 设计,所以我有点困惑。在我最初的设计中,我的数据库中的每个表都有一个不同的端点;事实上,我试图停止思考数据库如何存储数据。
    • @Perex19 您将输入课程名称,希望是独一无二的。我不支持访问课程下的特定讲师,不。
    猜你喜欢
    • 1970-01-01
    • 2023-03-12
    • 2018-04-06
    • 2014-04-18
    • 1970-01-01
    • 2019-08-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多