基本设计原则
API根URL
默认规则下后端工程pai-demo
在部署后的访问域名为demo-api
- 接口的主入口:
https://example.com/demo-api/*
- Swagger入口:
https://example.com/demo-api/doc.html
有特殊需求可以
Service.yaml
的定制二级路由,不使用默认的demo-api
URI末尾不要添加“/”
多一个斜杠,语义完全不同,究竟是目录,还是资源,还是不确定而多做一次301跳转?尽量保持URI结构简洁、语义清晰。
- 反例:
http://api.example.com/shapes/
- 正例:
http://api.example.com/shapes
禁止在URL中使用“_”
目的是提高可读性,“”可能被文本查看器中的下划线特效遮蔽。建议使用连字符“-”替代下划线“”,使用“-”提高URI的可读性。
- 反例:
http://api.example.com/blogs/my_first_post
- 正例:
http://api.example.com/blogs/my-first-post
禁止使用大写字母
RFC 3986中规定URI区分大小写,但别用大写字母来为难程序员了,既不美观,又麻烦,同样的原则:建议使用连字符“-”连接不同单词。
- 反例:
http://api.example.com/My-Folder/My-Doc
- 正例:
http://api.example.com/my-folder/my-doc
不要在URI中包含扩展名
应鼓励REST API客户端使用HTTP提供的格式选择机制Accept request header。
- 反例:
http://api.example.com/my-doc/hello.json
- 正例:
http://api.example.com/my-doc/hello
建议URI中的名称使用复数
为了保持URI格式简洁统一,资源在URI中应统一使用复数形式,如需访问资源的一个实例,可以通过资源ID定位(@PathVariable)。
- 反例:
http://api.example.com/student/1001
- 正例:
http://api.example.com/students/1001
如何处理关联关系?
http://api.example.com/students/1001/courses
- 检索学生1001所学习的所有课程http://api.example.com/students/1001/courses/physics
- 检索学生1001的所学习的物理课程
建议URI设计时只包含名词,不包含动词
每个URI代表一种资源或者资源集合,因此,建议只包含名词,不包含动词。
- 反例:
http://api.example.com/get-all-employees
- 正例:
http://api.example.com/employees
那么,如何告诉服务器端我们需要进行什么样的操作?CRUD?
答案是由HTTP动词表示。
GET
(SELECT):从服务器取出资源(一项或多项)。POST
(CREATE):在服务器新建一个资源。PUT
(UPDATE):在服务器更新资源(客户端提供改变后的完整资源)。PATCH
(UPDATE):在服务器更新资源(客户端提供改变的属性)。DELETE
(DELETE):从服务器删除资源。
举个粟子
- GET /zoos:列出所有动物园
- POST /zoos:新建一个动物园
- GET /zoos/ID:获取某个指定动物园的信息
- PUT /zoos/ID:更新某个指定动物园的信息(提供该动物园的全部信息)
- PATCH /zoos/ID:更新某个指定动物园的信息(提供该动物园的部分信息)
- DELETE /zoos/ID:删除某个动物园
- GET /zoos/ID/animals:列出某个指定动物园的所有动物
- DELETE /zoos/ID/animals/ID:删除某个指定动物园的指定动物
尽量减少对第三方开发人员的随意约束
非常重要的一点:让第三方开发人员自己指定排序过滤器、返回结果集的约束条件;但强烈建议服务器端设置默认单页数量,否则,如果无限制,很可能造成服务器资源及网络资源过度消耗,响应缓慢,网络丢包等异常情况;同时,需要在API文档中明确默认约束条件。
凌云规范
统一规则
- 每个应用都有一个统一的路径前缀,如:
/api
- 每个应用都有一个统一的版本编号,如:
/v1
、/v2
参数配置
在应用的相应配置文件(如: pai-api-config.yaml
)中添加自己的版本信息及使用服务的版本信息
# api version
api:
# 当前服务路径及版本
path: api
version: v1
# 引用的其他服务路径及版本
service:
auth:
path: api
version: v2
console:
path: api
version: v2
operate:
name: pai-operate
url:
path: api
version: v1
作用说明:
- name: 用于解决服务名变化
- url: 用于本地开发时直接指定,如: http://localhost:8080
- path: 用于配合contextPath配置
- verstion: 用于指定版本,经实战验证下来不是太好用,因为一个工程中可能会有多个版本并存,这一个改就全改了,不再建议使用动态变理,可以直接编码进去
在代码中使用
- Application
@SpringBootApplication
@PropertySource(value = "classpath:pai-api-config.yaml", factory = YamlPropertySourceFactory.class)
public class TestApplication {
public static void main(String[] args) {
SpringApplication.run(TestApplication.class, args);
}
}
- Controller
@RestController
@RequestMapping("${api.path}/test/v1")
public class TestController {
@GetMapping("/test01")
public String test01() {
return "************ test01 ************";
}
}
- Feign Client
@FeignClient(name = "${api.service.operate.name:pai-operate}", url = "${api.service.operate.url:}", contextId = "OperateService")
public interface OperateService {
@GetMapping(value = "${api.service.console.path}/console/v1/park/{code}")
public Reply queryPark(@PathVariable("code") String code, @RequestHeader(SecurityConstants.FROM) String from);
}
文档更新时间: 2024-03-25 11:24 作者:姚连洲