REST API是否有命名规范指南?

222

在创建REST API时,是否有任何指南或事实标准来规范API中的命名约定(例如:URL端点路径组件、查询字符串参数)?是驼峰命名法常见,还是下划线?还是其他方式?

例如:

api.service.com/helloWorld/userId/x
或者
api.service.com/hello_world/user_id/x
注意:这不是关于RESTful API设计的问题,而是关于最终路径组件和/或查询字符串参数使用的命名约定指南。

任何指南将不胜感激。

10个回答

166

我认为你应该避免使用驼峰命名法。通常使用小写字母。我也会避免使用下划线,改用破折号。

所以你的URL应该看起来像这样(忽略设计问题,因为你要求的是这样的)

api.service.com/hello-world/user-id/x

190
根据RFC2616规定,URL中只有scheme和host部分是不区分大小写的。 URL的其余部分,即路径和查询应区分大小写。参见http://www.w3.org/Protocols/rfc2616/rfc2616-sec3.html#sec3.2.3 - Darrel Miller
11
Daniel,你说得对,感谢指出。但是,实际上,我们通常希望URL不区分大小写,特别是资源名称部分。除非其中一个返回404,否则userid和UserId的行为方式没有区别是没有意义的。 - LiorH
19
为什么你认为大小写敏感“没有意义”?在许多其他情境下,大小写敏感能够产生良好的效果。有些网络服务(例如亚马逊S3)强制对URL端点进行大小写敏感性检查,我认为这是非常合适的。 - Hank
6
Windows服务器的文件系统默认情况下是不区分大小写的,除非我严重错误。http://technet.microsoft.com/en-us/library/cc725747.aspx - samspot
5
不错!我曾认为当服务器创建时,Windows 已经直接使用大小写敏感的文件名了。哇,他们竟然一直坚持他们自己的方式,例如“1 Microsoft Way”。;-) - Dennis
显示剩余5条评论

100

27
这会导致下划线连接的“单词”在Google的搜索索引中被保留为整体,而连字符连接的则被拆分为独立的单词。 - Dennis
13
虽然 Google Maps API 使用下划线,但是 Google 样式指南 要求使用驼峰命名法。Google+ APICustom Search API 等其他 API 使用驼峰命名法。 - Jade
3
然而他们仍然使用“-”作为这些URL的分隔符 :P https://developers.google.com/custom-search/json-api/v1/reference/cse/list https://developers.google.com/+/best-practices https://dev.twitter.com/overview/case-studies另一方面,他们在查询参数中使用camelCase。 - Mattias
1
我认为在这里和那里的所有讨论之后,我会使用下划线。 - Richard Fu
2
没有人知道... - Piotr Kula
显示剩余2条评论

85

仔细观察普通 Web 资源的 URI。这些是你的模板。想想目录树;使用类似于 Linux 的简单文件和目录名称。

HelloWorld 不是一个真正好的资源类别。它似乎不是一个“东西”。可能是,但它不太像名词。一个 greeting 是一个东西。

user-id 可能是你要获取的名词。然而,你请求的结果很可能不只是一个 user_id。更有可能的是请求的结果是一个 User。因此,user 是你要获取的名词。

www.example.com/greeting/user/x/

我觉得这个说法有道理。重点是让你的REST请求成为一种名词短语——一条通过层次结构(或分类法、目录)的路径。尽可能使用最简单的名词,避免使用名词短语。

通常,复合名词短语通常意味着你的层次结构中有另一个级别。所以你不会用/hello-world/user//hello-universe/user/。你需要用/hello/world/user/hello/universe/user/或者可能是/world/hello/user//universe/hello/user/

关键是提供资源之间的导航路径。


4
我更关注最终路径名和/或查询字符串参数的命名约定,无论它们是什么。我同意您的设计建议,所以谢谢您,但是在这个问题上,我只是在问命名约定。 - jnorris
1
请注意,您可以在非分层资源上使用REST。您使用的实际URI命名约定并不重要,只需使用您认为漂亮且易于在服务器上解析的任何内容即可。客户端不应该知道如何生成您的URI,因为您需要通过响应中的超文本将URI发送到资源。 - aehlke

31

'UserId'是完全错误的方法。动词(HTTP方法)和名词方法是Roy FieldingREST架构所设计的。名词可以是以下两种之一:

  1. 事物的集合
  2. 一个事物

一个好的命名约定是:

[POST or Create](To the *collection*)
sub.domain.tld/class_name.{media_type} 

[GET or Read](of *one* thing)
sub.domain.tld/class_name/id_value.{media_type}

[PUT or Update](of *one* thing)
sub.domain.tld/class_name/id_value.{media_type}

[DELETE](of *one* thing)
sub.domain.tld/class_name/id_value.{media_type}

[GET or Search](of a *collection*, FRIENDLY URL)
sub.domain.tld/class_name.{media_type}/{var}/{value}/{more-var-value-pairs}

[GET or Search](of a *collection*, Normal URL)
sub.domain.tld/class_name.{media_type}?var=value&more-var-value-pairs

其中{media_type}之一为:json、xml、rss、pdf、png,甚至是html。

还可以通过在末尾添加's'来区分集合,例如:

'users.json' *collection of things*
'user/id_value.json' *single thing*

但这意味着你必须记住你放置了哪些's',哪些没有。此外,地球上一半的人口(从亚洲开始)讲的语言没有明确的复数形式,因此URL对他们来说不太友好。

{var} 的意思是什么?如果我按名称搜索用户,例如 .../user/username/tomsawyer? - Hans-Peter Störr
1
如果你有三个名为x、y、z的变量(var),那么你的URL将会是这样的:http://sub.domain.tld/x/value_of_x/y/value_of_y/z/value_of_z - Dennis
@hstoerr 为了确保我表达清楚,大多数脚本语言使用某种“花括号变量替换”。因此,{var} 表示某个变量(它的名称)驻留在那里,所以下一个 {value} 就是它之前 {var} 的值。例如:sub.domain.tld/script/{var}/{value}.json [www.yelp.com/food_reviews/review_averages_higher_than/4.json] 将尝试从 Yelp.com 获取显示评价高于4的食品评论的 JSON 结果。 - Dennis
在我看来,这是最好的答案,也感谢你考虑到国际化。 - beiller

14

44
休息一下吧,但拥有美观的URL仍然很不错。 - Dave
1
同意@HDave的观点,让URL易于理解非常符合REST的精神。你正在使用URL,为什么不希望它们像代码中的变量和参数名称一样容易理解呢? - mahemoff
5
抱歉,我有点龟毛。但是你的URL长什么样与REST无关。这并不意味着它们不是好事情,只是与REST描述的内容无关。说REST是关于以这种方式构造URL的结构是误导性的,因为它会导致人们将具有可读/结构化URL的RPC API描述为REST。 - aehlke
6
简而言之,美观的URL非常好,并且每个人都应该使用它们。但这与REST无关。 - aehlke
1
@aehlke 感谢您澄清这一点。其余部分与URL结构无关。我不明白为什么人们很难理解。 - user1431072
@user1431072 这些年来滥用"REST"这个术语,尤其是在Rails等方面。很遗憾。 - aehlke

9

域名不区分大小写,但URI的其余部分可以区分大小写。假设URI不区分大小写是一个大错误。


5

4
如果您使用Oauth2对客户进行身份验证,我认为您将需要至少使用下划线来命名两个参数:
  • client_id
  • client_secret
我在我的(尚未发布的)REST API中使用了驼峰式大小写。在编写API文档时,我一直在考虑将所有内容更改为蛇形大小写,以便不必解释为什么Oauth参数是蛇形大小写而其他参数不是。
请参见:https://www.rfc-editor.org/rfc/rfc6749

3

我认为在这个例子中,驼峰式命名并不是问题所在,但我想对上面的例子使用更符合RESTful规范的命名约定:

api.service.com/helloWorld/userId/x

而不是将userId作为查询参数(这是完全合法的),我的例子以一种更符合RESTful规范的方式表示了资源。


这不是关于RESTful API设计的问题,而是关于最终使用的路径组件和/或查询字符串参数要使用的命名约定指南。在您的示例中,路径组件应该如何命名,应该使用驼峰式还是下划线? - jnorris
既然在REST中,你的URL是你的接口,那么这就是一个API问题。虽然我不认为有任何针对你的示例的特定指南,但我个人会选择驼峰命名法。 - Gandalf
不应该在希望被 HTTP 栈的任何级别缓存的资源中使用查询参数。 - aehlke
@aehlke 同样的道理也适用于相反的情况。如果您不想缓存查询参数,请使用 GET 样式来处理参数,或者确保为任何不想缓存的内容修改/插入防缓存头文件。此外,还有一些标题是对象/页面返回的哈希值,使用它来指示您想要缓存的更改内容,但在编辑时进行更新。 - Dennis
@aehlke 发现了缓存并正在添加它。我记得在一个CodeCamp演示中,其中一个加速方法是做所有这些头文件,然后在其内容更改时更改文件名和所有引用,以便在设置了长时间缓存时间后,让浏览器和代理服务器提供更新版本。这里是所有令人不快的细节:https://developers.google.com/speed/docs/best-practices/caching - Dennis

0

我认为在REST URL中尽可能少使用特殊字符是更好的选择。 REST的一个好处是使服务的“接口”易于阅读。骆驼命名法或帕斯卡命名法可能适用于资源名称(Users或users)。我认为REST没有真正的硬标准。

此外,我认为甘道夫是正确的,在REST中通常不使用查询字符串参数会更清晰,而是创建定义要处理哪些资源的路径。

http://api.example.com/HelloWorld/Users/12345/Order/3/etc


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接