• RESTful Api 规范


    Choerodon 符合 REST 原则,它是一个RESTful 架构。

    RESTful API Design 名词定义

    HTTP Verbs

    Resource Oriented Design

    设计流程

    1. 确定一个API提供什么类型的资源
    2. 确定资源之间的依赖关系
    3. 基于类型和依赖关系确定资源的命名
    4. 确定资源的结构
    5. 为资源添加最少的方法

    Resource Names

    资源是一个实体对象,那么资源名就是这个资源的标识。

    一个资源名应该由Resource ID,Collection ID 和API Service 名组成。

    例1:存储服务有 buckets 的集合,其中每个桶包含一个 objects 集合。

    API Service Name Collection ID Resource ID Sub-Collection ID Sub-Resource ID
    //gateway.com.cn/storage /buckets /bucket-id /objects /object-id

    例2:电子邮件服务用户的集合。sub-resource 每个用户都有一个设置,设置 sub-resource 有许多其他的子资源,包括 customFrom:

    API Service Name Collection ID Resource ID Sub-Collection ID Sub-Resource ID
    //gateway.com.cn/mails /users /[email protected] /settings /customFrom

    Resource ID

    Collection ID

    Action 命名规范

    基本规范

    类别

    Description Action Name HTTP Mapping HTTP Request Body HTTP Response Body
    查询所有 list GET N/A Resource* list
    获取单个资源 query GET N/A Resource*
    创建单个资源 create POST Resource Resource*
    更新单个资源 update PUT Resource Resource*
    删除单个资源 delete DELETE N/A Empty

    List

    List 方法接受一个 Collection id 和0或多个参数作为输入,并返回一个列表的资源。

    Query

    Query 方法接受一个 Resource name 和0或多个参数,并返回指定的资源。

    Create

    Create 方法接受一个 Collection id ,一个资源,和0或多个参数。它创建一个新的资源在指定的父资源下,并返回新创建的资源。

    Update

    Update 方法接受一个资源和0或多个参数。更新指定的资源和其属性,并返回更新的资源。

    Delete

    Delete 方法接受一个Resource Name 和0或多个参数,并删除指定的资源。

    自定义方法

    自定义的方法应该参考5个基本方法,应该用于基本方法不能实现的功能性方法。可能需要一个任意请求并返回一个任意的响应,也可能是流媒体请求和响应。

    可以对应a resource, a collection 甚至 a service。

    批量添加

    Description Action Name HTTP Mapping HTTP Request Body HTTP Response Body
    批量添加 batchCreate POST /batch_create Resource* list Resource IDS

    批量删除

    Description Action Name HTTP Mapping HTTP Request Body HTTP Response Body
    批量删除 batchDelete POST /batch_delete Resource IDS Empty

    更新单个资源中的属性

    Description Action Name HTTP Mapping HTTP Request Body HTTP Response Body
    更新资源的状态 updateAttribute POST /:attribute?value= N/A {“key”:“”,“value”:“”}
    更新用户的年龄 updateAge POST /v1/users/1/age?value=20 N/A {“key”:“age”,“value”:“20”}

    对资源执行某一动作

    Description Action Name HTTP Mapping HTTP Request Body HTTP Response Body
    对资源执行某一动作 customVerb POST /custom_verb N/A *
    取消某种操作 cancel POST /cancel N/A Boolean
    从回收站中恢复一个资源 undelete POST /v1/projects/1/undelete N/A Boolean
    检查项目是否重名 checkName POST /v1/projects/1/check?name= N/A

    查询某一资源的单个属性

    Description Action Name HTTP Mapping HTTP Request Body HTTP Response Body
    查询资源的某属性 queryAttribute GET /:attribute N/A {“key”:“”,“value”:“”}
    查询用户的年龄 queryAge GET /v1/users/1/age N/A {“key”:“age”,“value”:“25”}
    查询用户下的项目 queryProjects GET /v1/users/1/projects N/A {“key”:“projects”,“value”:[]}

    查询collection 的数量

    Description Action Name HTTP Mapping HTTP Request Body HTTP Response Body
    查询Collection 的数量 count GET /count N/A {“key”:“”,“count”:“”}
    查询组织的数目 count GET /v1/organizations/count N/A {“key”:“organizations”,“count”:“100”}
    查询用户下的所有项目数量 countProjects GET /v1/users/1/projects/count N/A {“key”:“projects”,“count”:“100”}

    复杂条件查询

    版本控制

    版本兼容的修改:

    版本不兼容的修改:

    Demo

    
    @RestController
    @RequestMapping("/v1/users")
    public class UserController {
    
        @GetMapping("/")
        public ResponseEntity<User> list() {
            return null;
        }
    
        @GetMapping("/{id}")
        public User query(@PathVariable("id") String id) {
            return null;
        }
    
        @PostMapping("/")
        public ResponseEntity<User> create(@RequestBody User user) {
            return null;
        }
    
        @PutMapping("/{id}")
        public ResponseEntity<User> update(@PathVariable("id") String id, @RequestBody User user) {
            return null;
        }
    
        @DeleteMapping("/{id}")
        public ResponseEntity<User> delete(@PathVariable("id") String id) {
            return null;
        }
    
        @PostMapping("/batch_create")
        public ResponseEntity<User> batchCreate(@RequestBody List<User> users) {
            return null;
        }
    
        @PostMapping("/batch_delete")
        public ResponseEntity<User> batchDelete(@RequestBody List<User> users) {
            return null;
        }
    
        @PostMapping("/age")
        public ResponseEntity<User> updateAge(@RequestParam("value") Integer age) {
            return null;
        }
    
        @PostMapping("/{:id}/undelete")
        public ResponseEntity<User> undelete(@PathVariable("id") String id) {
            return null;
        }
    
        @PostMapping("/check")
        public ResponseEntity<User> checkName(@RequestParam("name") String name) {
            return null;
        }
    
        @GetMapping("/{:id}/age")
        public ResponseEntity<User> queryAge(@PathVariable("id") String id) {
            return null;
        }
    
        @GetMapping("/{:id}/name")
        public ResponseEntity<User> queryByUserIdAndName(@PathVariable("id") String id, @RequestParam("name") String name) {
            return null;
        }
    
        @GetMapping("/{:id}/projects/count")
        public ResponseEntity<User> countProjects(@PathVariable("id") String id, @RequestParam("name") String name) {
            return null;
        }
    
        @GetMapping("/")
        public ResponseEntity<User> listByOptions(@RequestBody Map<String, Object> options) {
            return null;
        }
    
    }