基本设计原则

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   作者:姚连洲