ReSTful 命名风格最佳实践

2023/02/27 API

REST,全拼为 Representational State Transfer,或者说 ReSTful API 是一套系统化约定的风格集合,既不是协议也不是标准,只是一种风格。API 开发者可以有不同的实现方式,这就意味者 API URI 中路径(Path)、QueryString 请求参数和请求体参数命名风格,也可以有多种选择。那么,那种命名风格最好呢?

例如,如果我们提供一个 API 返回 Hello World! 信息,可选的风格可能有如下几种:

  1. 小驼峰:https://zqfan.cc/api/v1/helloWorld
  2. 大驼峰:https://zqfan.cc/api/v1/HelloWorld
  3. 全小写:https://zqfna.cc/api/v1/helloworld
  4. 下划线:https://zqfan.cc/api/v1/hello_world
  5. 横杠:https://zqfan.cc/api/v1/hello-world

答案也很简单,任意选一个,并贯彻到所有接口就可以了。但是知易行难,这并不是一件容易的事情。

我们挑选比较有名的商业云计算代表 AWS 和 开源云计算代表 OpenStack 两家的 API 分析一下。

AWS S3 API

AWS S3 API 几乎是对象存储领域的业界标准了,其他厂商提供对象存储服务的时候,是否兼容 AWS S3 API 是用户 的一大诉求。我们将目前(2023-02-27)S3 所有 API 分类如下:

一元单词,无法区分风格的(注意,由于 REST API 本身没有名称,此处仅为代称):

  1. CopyObject
  2. CreateBucket
  3. CreateMultipartUpload
  4. DeleteBucket
  5. DeleteBucketAnalyticsConfiguration
  6. DeleteBucketCors
  7. DeleteBucketEncryption
  8. DeleteBucketInventoryConfiguration
  9. DeleteBucketLifecycle
  10. DeleteBucketMetricsConfiguration
  11. DeleteBucketPolicy
  12. DeleteBucketReplication
  13. DeleteBucketTagging
  14. DeleteBucketWebsite
  15. DeleteObjects
  16. GetBucketAccelerateConfiguration
  17. GetBucketAcl
  18. GetBucketAnalyticsConfiguration
  19. GetBucketCors
  20. GetBucketEncryption
  21. GetBucketInventoryConfiguration
  22. GetBucketLifecycle
  23. GetBucketLifecycleConfiguration
  24. GetBucketLocation
  25. GetBucketLogging
  26. GetBucketMetricsConfiguration
  27. GetBucketNotification
  28. GetBucketNotificationConfiguration
  29. GetBucketPolicy
  30. GetBucketReplication
  31. GetBucketTagging
  32. GetBucketVersioning
  33. GetBucketWebsite
  34. GetObjectTorrent
  35. HeadBucket
  36. ListBuckets
  37. PutBucketAccelerateConfiguration
  38. PutBucketAcl
  39. PutBucketAnalyticsConfiguration
  40. PutBucketCors
  41. PutBucketEncryption
  42. PutBucketInventoryConfiguration
  43. PutBucketLifecycle
  44. PutBucketLifecycleConfiguration
  45. PutBucketLogging
  46. PutBucketMetricsConfiguration
  47. PutBucketNotification
  48. PutBucketNotificationConfiguration
  49. PutBucketPolicy
  50. PutBucketReplication
  51. PutBucketTagging
  52. PutBucketVersioning
  53. PutBucketWebsite
  54. PutObject

小驼峰风格,共计:

  1. AbortMultipartUpload, uploadId
  2. CompleteMultipartUpload, uploadId
  3. DeleteBucketOwnershipControls, ownershipControls
  4. DeleteObject, versionId
  5. DeleteObjectTagging, versionId
  6. DeletePublicAccessBlock, publicAccessBlock
  7. GetBucketOwnershipControls, ownershipControls
  8. GetBucketPolicyStatus, policyStatus
  9. GetBucketRequestPayment, requestPayment
  10. GetObjectAcl, versionId
  11. GetObjectAttributes, versionId
  12. GetObjectRetention, versionId
  13. GetObjectTagging, versionId
  14. GetPublicAccessBlock, publicAccessBlock
  15. HeadObject, partNumber, versionId
  16. PutBucketOwnershipControls, ownershipControls
  17. PutBucketRequestPayment, requestPayment
  18. PutObjectAcl, versionId
  19. PutObjectRetention, versionId
  20. PutObjectTagging, versionId
  21. PutPublicAccessBlock, publicAccessBlock
  22. RestoreObject, versionId
  23. UploadPart, partNumber, uploadId
  24. UploadPartCopy, partNumber, uploadId

横杠风格,共计:

  1. DeleteBucketIntelligentTieringConfiguration, intelligent-tiering
  2. GetBucketIntelligentTieringConfiguration, intelligent-tiering
  3. GetObjectLockConfiguration, object-lock
  4. ListBucketAnalyticsConfigurations, continuation-token
  5. ListBucketIntelligentTieringConfigurations. intelligent-tiering, continuation-token
  6. ListBucketInventoryConfigurations, continuation-token
  7. ListBucketMetricsConfigurations, continuation-token
  8. ListMultipartUploads, encoding-type, key-marker, max-uploads, upload-id-marker
  9. ListObjects, encoding-type, max-keys
  10. ListObjectsV2, list-type, continuation-token, encoding-type, fetch-owner, max-keys, start-after
  11. ListObjectVersions, encoding-type, key-marker, max-keys, version-id-marker
  12. PutBucketIntelligentTieringConfiguration, intelligent-tiering
  13. PutObjectLockConfiguration, object-lock
  14. SelectObjectContent, select-type

小驼峰和横杠混合风格,共计:

  1. GetObject, partNumber, versionId, response-cache-control, response-content-disposition, response-content-encoding, response-content-language, response-content-type, response-expires
  2. GetObjectLegalHold, versionId, legal-hold
  3. ListParts, uploadId, max-parts, part-number-marker
  4. PutObjectLegalHold, versionId, legal-hold

大驼峰风格,共计:

  1. WriteGetObjectResponse, WriteGetObjectResponse

可以看到,小驼峰和横杠风格的大致相同,并且有个别接口两者都出现了(均为请求参数),此外还有极个别的大驼峰参数。

阅读 AWS S3 API 文档还能够发现,许多接口将一些参数定义在 HTTP 头部中,同时也有其他参数定义在 URI 和请求体中。出现在 HTTP 头部的参数基本为全小写横杠分隔(x-amz-前缀,HTTP 标准头部则为大驼峰横杠分隔),但也有例外 GetObject 出现大驼峰和横杠的头部。涉及到术语 MD5 时,采用的是大写,但其他术语又是全小写,如 sdk,mfa,sha1。出现在请求体中的均为大驼峰。

AWS S3 Control API

我们再看看 AWS S3 Control API,分析发现:

一元单词,无法区分风格,共计:

  1. CreateBucket
  2. CreateJob
  3. DeleteBucket
  4. DeleteBucketPolicy
  5. DeleteBucketTagging
  6. DeleteJobTagging
  7. DescribeJob
  8. GetBucket
  9. GetBucketPolicy
  10. GetBucketTagging
  11. GetBucketVersioning
  12. GetJobTagging
  13. GetMultiRegionAccessPoint
  14. GetMultiRegionAccessPointPolicy
  15. GetMultiRegionAccessPointRoutes
  16. PutBucketPolicy
  17. PutBucketTagging
  18. PutBucketVersioning
  19. PutJobTagging
  20. UpdateJobPriority

全小写风格,共计:

  1. CreateAccessPoint
  2. CreateAccessPointForObjectLambda
  3. DeleteAccessPoint
  4. DeleteAccessPointForObjectLambda
  5. DeleteAccessPointPolicy
  6. DeleteAccessPointPolicyForObjectLambda
  7. DeleteBucketLifecycleConfiguration
  8. DeleteStorageLensConfiguration
  9. DeleteStorageLensConfigurationTagging
  10. GetAccessPoint
  11. GetAccessPointConfigurationForObjectLambda
  12. GetAccessPointForObjectLambda
  13. GetAccessPointPolicy
  14. GetAccessPointPolicyForObjectLambda
  15. GetBucketLifecycleConfiguration
  16. GetMultiRegionAccessPointPolicyStatus
  17. GetStorageLensConfiguration
  18. GetStorageLensConfigurationTagging
  19. PutAccessPointConfigurationForObjectLambda
  20. PutAccessPointPolicy
  21. PutAccessPointPolicyForObjectLambda
  22. PutBucketLifecycleConfiguration
  23. PutStorageLensConfiguration
  24. PutStorageLensConfigurationTagging
  25. SubmitMultiRegionAccessPointRoutes

小驼峰风格,共计:

  1. DeletePublicAccessBlock
  2. GetPublicAccessBlock
  3. ListJobs
  4. ListMultiRegionAccessPoints
  5. ListRegionalBuckets
  6. PutPublicAccessBlock
  7. UpdateJobStatus

全小写和小驼峰混合风格,共计:

  1. GetAccessPointPolicyStatus
  2. GetAccessPointPolicyStatusForObjectLambda
  3. ListAccessPoints
  4. ListAccessPointsForObjectLambda
  5. ListStorageLensConfigurations

横杠风格,共计:

  1. CreateMultiRegionAccessPoint
  2. DeleteMultiRegionAccessPoint
  3. PutMultiRegionAccessPointPolicy

横杠和下划线混合风格,共计:

  1. DescribeMultiRegionAccessPointOperation

我们可以看到,AWS S3 Control API 更偏向全小写风格,也有小驼峰以及小驼峰混合全小写的情况,也有横杠风格,极个别出现横杠和下划线混合的情况。

OpenStack Nova API

OpenStack 是以开源云计算操作系统为目标,运营得较好的社区。代码检视比较严格,尤其是核心项目。我们选择其中最核心的计算模块,也是元老项目的 Nova 为例,分析下 OpenStack Nova API 的风格。

Nova 的 API 风格更为彻底的遵循了 REST 风格,和 AWS S3 API 还在使用 XML 不同,Nova 使用 Json 格式进行数据交互。但是风格统一程度和 AWS 一样,并不高。

Path 中参数命名风格:

  • 变量参数统一下划线风格
  • 固定路径名横杠风格,较多,例如 /servers/{server_id}/remote-consoles
  • 固定路径名横杠和下划线混用,较少,例如 /servers/{server_id}/os-volume_attachments

QueryString 中参数命名风格:

  • 下划线风格,最多,例如 access_ip_v4
  • 横杠风格,较多,例如 changes-since
  • 小驼峰,较少,例如 minDisk

请求体中参数命名风格:

  • 小驼峰风格,较多,例如 flavorRef
  • 下划线风格,较多,例如 availability_zone
  • 冒号风格,较多,例如 os:scheduler_hints.build_near_host_ip
  • 横杠,较少,例如 OS-DCF:diskConfig

对于资源的多种操作,将其定义为 POST /servers/{server_id}/action,在请求体中给出 action 实际参数名,风格为大驼峰。

也有使用 GET 语义的操作,例如 GET /os-hosts/{host_name}/reboot 重启机器。

原文zqfan (zhiqiangfan@tencent.com) 发表。版权声明(License): (CC 4.0) BY-NC-SA

Search

    Table of Contents