• 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 NameCollection IDResource IDSub-Collection IDSub-Resource ID
    //gateway.com.cn/storage/buckets/bucket-id/objects/object-id

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

    API Service NameCollection IDResource IDSub-Collection IDSub-Resource ID
    //gateway.com.cn/mails/users/name@example.com/settings/customFrom

    Resource ID

    Collection ID

    Action 命名规范

    基本规范

    类别

    DescriptionAction NameHTTP MappingHTTP Request BodyHTTP Response Body
    查询所有listGETN/AResource* list
    获取单个资源queryGETN/AResource*
    创建单个资源createPOSTResourceResource*
    更新单个资源updatePUTResourceResource*
    删除单个资源deleteDELETEN/AEmpty

    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。

    批量添加

    DescriptionAction NameHTTP MappingHTTP Request BodyHTTP Response Body
    批量添加batchCreatePOST/batch_createResource* listResource IDS

    批量删除

    DescriptionAction NameHTTP MappingHTTP Request BodyHTTP Response Body
    批量删除batchDeletePOST/batch_deleteResource IDSEmpty

    更新单个资源中的属性

    DescriptionAction NameHTTP MappingHTTP Request BodyHTTP Response Body
    更新资源的状态updateAttributePOST/:attribute?value=N/A{“key”:“”,“value”:“”}
    更新用户的年龄updateAgePOST /v1/users/1/age?value=20N/A{“key”:“age”,“value”:“20”}

    对资源执行某一动作

    DescriptionAction NameHTTP MappingHTTP Request BodyHTTP Response Body
    对资源执行某一动作customVerbPOST/custom_verbN/A*
    取消某种操作cancelPOST/cancelN/ABoolean
    从回收站中恢复一个资源undeletePOST /v1/projects/1/undeleteN/ABoolean
    检查项目是否重名checkNamePOST /v1/projects/1/check?name=N/A

    查询某一资源的单个属性

    DescriptionAction NameHTTP MappingHTTP Request BodyHTTP Response Body
    查询资源的某属性queryAttributeGET/:attributeN/A{“key”:“”,“value”:“”}
    查询用户的年龄queryAgeGET /v1/users/1/ageN/A{“key”:“age”,“value”:“25”}
    查询用户下的项目queryProjectsGET /v1/users/1/projectsN/A{“key”:“projects”,“value”:[]}

    查询collection 的数量

    DescriptionAction NameHTTP MappingHTTP Request BodyHTTP Response Body
    查询Collection 的数量countGET/countN/A{“key”:“”,“count”:“”}
    查询组织的数目countGET /v1/organizations/countN/A{“key”:“organizations”,“count”:“100”}
    查询用户下的所有项目数量countProjectsGET /v1/users/1/projects/countN/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;
        }
    
    }