Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/132.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
REST URI约定-创建资源时资源的单数或复数名称_Rest_Resources_Naming Conventions_Uri - Fatal编程技术网

REST URI约定-创建资源时资源的单数或复数名称

REST URI约定-创建资源时资源的单数或复数名称,rest,resources,naming-conventions,uri,Rest,Resources,Naming Conventions,Uri,我是REST新手,我观察到在一些RESTful服务中,它们使用不同的资源URI进行更新/获取/删除和创建。比如 创建-使用/resources和POST方法(遵守复数)在某些地方使用/resource(单数) 更新-使用PUT方法使用/resource/123 Get-使用带有Get方法的/resource/123 我对这个URI命名约定有点困惑。我们应该用复数还是单数来创造资源?当决定使用时,标准应该是什么?使用/resources的前提是它代表“所有”资源。如果执行GET/resourc

我是REST新手,我观察到在一些RESTful服务中,它们使用不同的资源URI进行更新/获取/删除和创建。比如

  • 创建-使用/resources和POST方法(遵守复数)在某些地方使用/resource(单数)
  • 更新-使用PUT方法使用/resource/123
  • Get-使用带有Get方法的/resource/123

我对这个URI命名约定有点困惑。我们应该用复数还是单数来创造资源?当决定使用时,标准应该是什么?

使用
/resources
的前提是它代表“所有”资源。如果执行
GET/resources
,可能会返回整个集合。通过发布到
/resources
,您将添加到集合中

但是,单个资源可在/resource处获得。如果执行
GET/resource
,可能会出错,因为此请求没有任何意义,而
/resource/123
则完全有意义

使用
/resource
而不是
/resources
类似于使用文件系统和文件集合时的操作方式,
/resource
是包含单个
123
456
文件的“目录”


这两种方法都不是对的,也不是错的,选择你最喜欢的方法。

我也不认为这样做有什么意义,我认为这不是最好的URI设计。作为RESTful服务的用户,我希望列表资源具有相同的名称,无论我是访问列表还是访问列表中的特定资源。无论是使用列表资源还是特定资源,都应该使用相同的标识符。

尽管最流行的做法是使用复数的RESTful api,例如
/api/resources/123
,但有一种特殊情况,我发现使用单数名称比复数名称更合适/更具表达力。这是一对一关系的情况。特别是如果目标项是一个值对象(在域驱动的设计范例中)


让我们假设每个资源都有一对一的
accessLog
,它可以建模为一个值对象,即不是一个实体,因此没有ID。它可以表示为
/api/resources/123/accessLog
。常用动词(POST、PUT、DELETE、GET)可以恰当地表达意图,以及这种关系确实是一对一的事实。

为什么不遵循数据库表名的流行趋势,在这种趋势中,单数形式被普遍接受?在那里,做了,让我们重复使用


对我来说,最好有一个可以直接映射到代码的模式(易于自动化),主要是因为代码是两端的内容

GET  /orders          <---> orders 
POST /orders          <---> orders.push(data)
GET  /orders/1        <---> orders[1]
PUT  /orders/1        <---> orders[1] = data
GET  /orders/1/lines  <---> orders[1].lines
POST /orders/1/lines  <---> orders[1].lines.push(data) 
GET/orders
发布/订单.推送(数据)
获取/订单/1订单[1]
下单/订单/1订单[1]=数据
获取/orders/1/行订单[1]。行
POST/orders/1/行订单[1]。行。推送(数据)

从API使用者的角度来看,端点应该是可预测的,因此

理想情况下

  • GET/resources
    应返回资源列表
  • GET/resource
    应返回400级状态代码
  • GET/resources/id/{resourceId}
    应返回包含一个资源的集合
  • GET/resource/id/{resourceId}
    应返回资源对象
  • POST/resources
    应批量创建资源
  • POST/resource
    应创建一个资源
  • PUT/resource
    应更新资源对象
  • PATCH/resource
    应仅通过发布更改的属性来更新资源
  • PATCH/resources
    应该批量更新资源,只发布更改的属性
  • DELETE/resources
    应删除所有资源;开玩笑吧:400状态码
  • DELETE/resource/id/{resourceId}
  • 这种方法是最灵活和功能最丰富的,但也是最耗时的开发方法。因此,如果您赶时间(软件开发总是如此),只需将端点命名为
    resource
    或复数形式
    resources
    。我更喜欢单数形式,因为它让您可以选择以编程方式进行反思和评估,因为并非所有复数形式都以“s”结尾

    话虽如此,无论出于何种原因,开发人员最常用的实践选择是使用复数形式。这就是我最终选择的路线,如果你看看流行的API,比如
    github
    twitter
    ,它们就是这么做的

    决定的一些标准可以是:

  • 我的时间限制是什么
  • 我将允许我的消费者执行哪些操作
  • 请求和结果负载是什么样子的
  • 我是否希望能够在代码中使用反射和解析URI

  • 所以这取决于你。无论你做什么,都要保持一致。

    我的两分钱:那些花时间从复数改为单数或反之的方法是对CPU周期的浪费。我可能是老派,但在我的时代,事情都被称为一样的。我如何查找有关人员的方法?没有定期的表达将涵盖个人和没有不良副作用的人


    英文复数可以是非常任意的,它们不必要地妨碍了代码。坚持一个命名约定。计算机语言应该是数学上的清晰,而不是模仿自然语言。

    复数

    • 简单-所有URL都以相同的前缀开头
    • 逻辑-
      订单/
      获取订单的索引列表
    • 标准——最广泛采用的标准
      /shoe/23
      
      Ends with -fe   Change f to v then Add -s   
          knife   knives 
          life   lives 
          wife   wives
      Ends with -f    Change f to v then Add -es  
          half   halves 
          wolf   wolves
          loaf   loaves
      Ends with -o    Add -es 
          potato   potatoes
          tomato   tomatoes
          volcano   volcanoes
      Ends with -us   Change -us to -i    
          cactus   cacti
          nucleus   nuclei
          focus   foci
      Ends with -is   Change -is to -es   
          analysis   analyses
          crisis   crises
          thesis   theses
      Ends with -on   Change -on to -a    
          phenomenon   phenomena
          criterion   criteria
      ALL KINDS   Change the vowel or Change the word or Add a different ending   
           man   men
           foot   feet
           child   children
           person   people
           tooth   teeth
           mouse   mice
       Unchanging Singular and plural are the same    
           sheep deer fish (sometimes)
      
      interface User {
          <string>id;
          <Friend[]>friends;
          <Manager>user;
      }
      
      interface Friend {
          <string>id;
          <User>user;
          ...<<friendship specific props>>
      }
      
      GET /resources?Id=123
      
      GET /resource?Id=123
      
      GET  /resources     =     GET  /resource
      GET  /resources/1   =     GET  /resource/1
      POST /resources/1   =     POST /resource/1
      ...
      
      numbers = [1, 2, 3]
      
      numbers            GET /numbers
      numbers[1]         GET /numbers/1
      numbers.push(4)    POST /numbers
      numbers[1] = 23    UPDATE /numbers/1
      
      GET /dashboard
      DELETE /session
      POST /login
      GET /users/{:id}/profile
      UPDATE /users/{:id}/profile
      
      |--------------------------+---------------+-------------------+---------------+--------------|
      | API Service Name         | Collection ID | Resource ID       | Collection ID | Resource ID  |
      |--------------------------+---------------+-------------------+---------------+--------------|
      | //mail.googleapis.com    | /users        | /name@example.com | /settings     | /customFrom  |
      | //storage.googleapis.com | /buckets      | /bucket-id        | /objects      | /object-id   |
      |--------------------------+---------------+-------------------+---------------+--------------|
      
      GET  /user             -> Not allowed, 400
      GET  /user/{id}        -> Returns user with given id
      POST /user             -> Creates a new user
      PUT  /user/{id}        -> Updates user with given id
      DELETE /user/{id}      -> Deletes user with given id
      
      GET /users             -> Lists all users, optionally filtered by way of parameters
      GET /users/new?since=x -> Gets all users that are new since a specific time
      GET /users/top?max=x   -> Gets top X active users
      
      GET /user/{id}/friends -> Returns a list of friends of given user
      
      PUT /user/{id}/friend/{id}     -> Befriends two users
      DELETE /user/{id}/friend/{id}  -> Unfriends two users
      GET /user/{id}/friend/{id}     -> Gets status of friendship between two users
      
      GET /user/index
      GET /user/{id}
      
      POST /user
      PUT /user/{id}
      
      DELETE /user/{id}