Rest API路由命名约定

Rest API路由命名约定,rest,api-design,Rest,Api Design,我正在为一个私人项目开发一个API(以及一个SPA),我无法在两个路由命名约定之间做出决定 假设我的数据库中有三个表:用户、产品和订单。如果我希望用户能够订购产品,我应该遵循以下哪种约定 POST/orderswith body{“product”:1} POST/products/{id}/order 注意:在这两种情况下,用户将根据提供的访问令牌进行推断 对我来说,上述两种解决方案的主要区别在于向前端开发人员公开的接口类型:我是公开到资源的路由(解决方案1)还是要执行的操作(解决方案2)?

我正在为一个私人项目开发一个API(以及一个SPA),我无法在两个路由命名约定之间做出决定

假设我的数据库中有三个表:
用户
产品
订单
。如果我希望用户能够订购产品,我应该遵循以下哪种约定

  • POST/orders
    with body
    {“product”:1}
  • POST/products/{id}/order
  • 注意:在这两种情况下,
    用户
    将根据提供的访问令牌进行推断

    对我来说,上述两种解决方案的主要区别在于向前端开发人员公开的接口类型:我是公开到资源的路由(解决方案1)还是要执行的操作(解决方案2)?

    是否存在使用一种方法而不是另一种方法的实际(缺点),或者这只是个人品味的问题

    如果我错了,请纠正我,但据我所知,解决方案1是REST(“创建此资源”),而解决方案2不是(“执行此操作”)

    另外,在解决方案1中,每个路由都会直接映射到数据库中的一个表,有些人说这是个坏主意,因为外部开发人员可以根据API路由推断数据库的模式,但老实说,我不认为这是个问题

    是否存在使用一种方法而不是另一种方法的实际(缺点),或者这只是个人品味的问题

    拼写的选择主要取决于品味和习惯。从客户端的角度来看,这两个都是不透明的URI,可用于遵循您的协议。拼写约定适用于人类读者,并使端点的实现更容易

    如果我错了,请纠正我,但据我所知,解决方案1是REST(“创建此资源”),而解决方案2不是(“执行此操作”)

    不,但这是一个常见的误解

    REST体系结构风格对“客户机如何知道要遵循哪个uri”和“客户机如何知道负载中应该使用什么媒体类型”等问题比拼写更感兴趣

    您可能需要注意的是URI标识您的资源,而不是您的资源与之通信的域模型实体

    另外,在解决方案1中,每个路由都会直接映射到数据库中的一个表,有些人说这是个坏主意,因为外部开发人员可以根据API路由推断数据库的模式,但老实说,我不认为这是个问题

    另一方面,当您想要修改您的模式时,您是否打算重写所有的客户机?或者您打算将客户机与域的实现细节分离

    想想GangofFour中的适配器模式——您为您的客户机提供了一个设计良好、稳定的api,客户机可以与之通信,并为您的资源实现提供了一个新的接口,您可以根据您的模型的当前实现来调整请求

    REST是几十年规模的软件设计:每一个细节都旨在促进软件寿命和独立进化

    记住:如果这些属性对你不重要,如果它们不支持你当前的价值主张,那么你需要用这些约束条件来换取更合适的东西。

    TL;博士 根据我对GitHub和Instagram API端点的研究,对于用户订购产品来说,最有意义的是公开
    POST/users/123/orders{“product”:456}
    而不是
    POST/orders{“product”:456,“user”:123}
    这里的想法是考虑资源的上下文(如果有的话)。

    来源 请注意,我们不需要在URL中使用“update”动词短语 因为我们可以依赖HTTP谓词来通知该操作。只是为了 请澄清,以下资源URL是多余的:

    PUThttp://api.example.com/customers/12345/update

    由于请求中既有PUT,也有update,我们提供了混淆 我们的服务消费者!“更新”是资源吗

    4。为关系使用子资源

    如果一个资源与另一个资源相关,请使用子资源

    GET /cars/711/drivers/ Returns a list of drivers for car 711
    GET /cars/711/drivers/4 Returns driver #4 for car 711
    
    及宣传短片 GitHub和Instagram API似乎也是这样工作的,即在相关资源的上下文中使用

    例如,如果您想使用GitHub的API获取一个文件,您将使用
    get/users/fairyte/orgs
    而不是
    get/orgs{“username”:“fairyte”}


    如果你想喜欢媒体,Instagram的API也是一样:
    POST/media/{media\u id}/likes

    你也可以做一些类似于
    /products/1?action=order