社区编辑申请
注册/登录
RESTful API 优秀实践,你会了吗?
开发 架构
本篇介绍了一些REST API的一些食用方式,我们工作中可以根据一些各自的条件,作为参考。

哈喽,大家好,我是指北君。

RESTful 风格的HTTP 方法有POST,GET ,PUT ,DELETE,PATCH 等等。那么我们在开发时应该如何写出优雅的RESTful接口呢。本篇就为大家带来一期RESTful API 实践。

1. 前言

REST 全称为 :Resource Representational State Transfer. 是一种分布式超媒体系统(distributed hypermedia systems)架构风格。由Roy Fielding 提出。

REST API 也称RESTful API, 其遵循REST架构规范的应用编程接口, 支持与RESTful WEB服务进行交互。简单来讲就是:符合REST架构风格的 WEB API 或WEB 服务就是 REST API。

2. REST 的6大指导原则

REST 定义了6个原则,这些原则使得一个WEB API 成为真正的RESTful API。

  • 统一接口(Uniform interface)

开发者一旦熟悉了你的其中一个API,那么他就可以遵循类似的结构去使用其他API.

  • 客户端服务器(Client-server)

只要不改变他们之间的接口,服务端和客户端可以相互替换或独立开发。

  • 无状态(Stateless)

客户端上下文状态不应该存储在服务端,而应该有客户端去管理程序的状态

  • 可缓存(Cacheable)

优秀的缓存可以部分或者完全消除客户端和服务端的交互,最终提高应用的伸缩性和性能。

  • 分层系统(Layered System)

REST可以允许你使用分层架构,让你在服务器A上部署API, 服务器B上存储数据,服务器C上进行权限验证,客户端不知道它实际连接的是哪个服务器。

  • 按需编码(Code on demand (optional))

这些规则可以帮组你构建真正的RESTful API ,所以尽量遵循着些规则。如果因为某些原因违反这些规则,事实上你还是在构建RESTful API ,只是不算真正的RESTful。

3. 最佳实践

3.1 API名称

API的名称应该出现在URL中,API的标题也应该和名称一致,所以起名子也是比较重要的一点,这决定了你的API是否容易让人读懂!

3.2 API的版本

API的版本应该遵循, MAJOR.MINOR.PATCH的结构,即主要.次要.补丁 。

如果有重大的改动,导致前后的版本不兼容应该升级主要版本, 比如从1.0 升级到2.0。

如果只是增加了一些特性,前后的版本都是兼容话,可以升级次要版本, 比如从1.0 升级到1.1.

如果有一些小的bug修改的话,可以在补丁版本的上升级,比如从 1.0 升级到1.0.1

例如:

https://mysite.com/v1/...
https://mysite.com/v2/...

3.3提供准确的API文档

开发完成一个API之后,你需要让API的使用者可以正确的使用它,那么就需要一份漂亮的API文档了。

API文档需要提供准确的请求路径, 请求示例, 以及各种error时的状态码等。 可以使用Swagger等工具。

3.4资源路径命名

  • 资源名称使用名词,而不要使用动词。

比如 POST : /cars 表示创建cars , GET: /cars 表示查询cars 而不应该写成/createCars , /getCars 等等。

  • 获取集合资源与获取特定资源,统一使用复数来表示资源。
#获取资源集合时使用复数名词 
例如 /schools


#获取特定资源
例如 /schools/{school-id} /schools/5


#获取特定资源的子资源
例如 /schools/{school-id}/grades /schools/5/grades

3.5资源操作

RESTful API 使用HTTP 方法来对资源进行操作,相对应的一些常用操作如下:

HTTP method

资源操作类型

GET

查询集合,查询单个资源

POST

Create 创建某个资源

PUT

update   更新资源

PATCH

局部更新资源

DELETE

删除资源

  • 创建资源 POST

使用POST方法 创建资源,此处可以创建单个资源或者资源集合。创建成功应该立马返回HTTP 201, 二接受到resource并未立即添加资源则返回 HTTP 202 。

例如: 使用POST: /schools 添加多个school资源,
/schools/{school-id}/grades 添加某个school资源的grade,
  • 查询集合资源 及单个资源
例如: 使用 GET: /schools?type=PRIMARY  查询所有的小学
使用 GET :/schools/{school-id}/grades 查询某个学校的所有年级
GET :/schools/{school-id}/grades/{grade-id} 查询某个学校某个年级
  • 更新及修改资源 PUT/PATCH

更新个修改资源包含多种情况:

一种是完全更新,使用新的资源完全替换旧的资源。

例如:PUT: /schools/{school-id}/address  更新某个客户学校的地址信息

一种是修改局部更新,根据需求去更新修改原有的资源。

例如:PATCH: /schools/{school-id}/teachers  调整某个学校的老师

举个例子:

原有的资源如下:

{
"a":"A",
"b":{
"c":"C",
"d":"D"
}
}

当PATAH请求 如下:

PATCH  HTTP/1.1
Content-Type: application/merge-patch+json
{
"a":"Z",
"b":{
"d":null
}
}

修改后的resource如下:

{
"a":"Z",
"b":{
"c":"C"
}
}
  • 删除资源

删除资源使用DELETE方法,删除的方法有直接删除,或者使资源不可见。

3.6请求参数

  • 其余不是资源的参数应该出现在请求参数中。而且查询参数应该出现在GET请求中,不应该出现在PUT,POST请求中。
  • 请求参数应该使用驼峰命名法。
例如:GET /orders?startDate=2022-01-03&endDate=2022-02-03
DELETE /orders?status=EXPIRED
  • 使用唯一查询参数进行过滤
GET /orders?orderType=PAID
GET /orders?amount>100.00
  • 分页查询
API 使用offset={resultOffset}&limit={resultsPerPage} 进行分页查询,
并且以第0条数据为起始。

另外也可以使用 page={pageNumber}&limit={resultPerPage} 此时起始页为第1页

使用index={pageIndex}&limit={resultPerPage}, 每一页可以返回上一页或者下一页的link

可以看如下例子:
GET /orders?page=1&limit=15 第一页的15条数据
GET /orders?offset=0&limit=15 第一页的15条数据
GET /orders?page=5&limit=10 第五页的10条数据 第51-60
GET /orders?offset=50&limit=10 第51到60条数据
GET /orders?index=xxxxxxx&limit=10 同样也可以表示第51-60条数据,
只不过对客户端来说可能不知道第几页,response中应该包含有上一页和下一页的index
  • 排序

API的排序功能是API非常重要的一个功能,可以使用sort,sort-by 即使没有指出要排序,那么而应该给一个默认的排序。

例如:
GET /orders?sort=asc(date) /orders?sort=desc(date)
GET /orders?sort=+date /orders?sort=-date
GET /orders?sort=date.asc /orders?sort=date.desc
GET /orders?sort=date&order-by=asc /orders?sort=-date&order-by=desc

多字段排序示例:
GET /orders?sort=desc(date),asc(amount)
GET /orders?sort=-date,+amount

3.7使用HTTP状态码处理错误

http status

描述

2XX

SUCCESS

200

OK

201

Create

202

Accepted

204

No Content

4XX

Client Error

400

Bad Request

401

Unauthorized

403

Forbidden

404

Not Found

429

Too Many Request

5xx

Server Errors

500

Internal Server Error

总结

本篇介绍了一些REST API的一些食用方式,我们工作中可以根据一些各自的条件,作为参考。

责任编辑:武晓燕 来源: Java技术指北
相关推荐

2022-05-25 16:52:55

数据智能瑞数信息API

2022-05-24 08:21:16

数据安全API

2022-05-17 15:51:32

数据中心运维能力基础设施

2022-05-16 10:36:08

GitHub开源项目

2022-05-26 10:13:22

C/C++GCC插件单元测试

2022-04-29 10:40:38

技术服务端K8s

2022-05-24 19:49:22

2022-05-09 11:57:39

云原生实践安全

2022-05-25 07:11:13

2022-03-29 10:04:44

APIHarmony文件管理

2022-05-10 08:02:05

2022-02-20 23:15:46

gRPCGolang语言

2022-04-25 11:26:16

开发SpringBoot

2022-05-17 09:02:30

2022-05-22 21:23:10

前端监控系统

2022-05-19 19:26:33

区块链大数据数据分析

2022-04-18 10:13:32

软件开发写作

2022-05-23 09:18:55

RocketMQ存储中间件

2022-05-13 11:24:09

数据美团

2022-04-23 17:49:05

元宇宙51CTOMetaCon

同话题下的热门内容

架构师必备:多维度查询的优秀实践快手一面:讲一讲 Hadoop、Hive、Spark 之间的关系?分布式系统之Sentinel介绍与使用图解 Kafka 生产者元数据拉取管理全流程链路追踪:Sleuth整合ZipKinSOA中的软件架构设计及软硬件解耦方法论链路追踪:项目整合Sleuth实现链路追踪阿里10年沉淀|那些技术实战中的架构设计方法

编辑推荐

终于有人把Elasticsearch原理讲透了!花了一个星期,我终于把RPC框架整明白了!拜托!面试不要再问我Spring Cloud底层原理陌陌基于K8s和Docker容器管理平台的架构实践收藏 | 第一次有人把“分布式事务”讲的这么简单明了
我收藏的内容
点赞
收藏

51CTO技术栈公众号