API 书写规范

2017-07-11  本文已影响405人  刘月玮

Swagger API �编写规范

参考文档地址

  1. https://blog.mwaysolutions.com/2014/06/05/10-best-practices-for-better-restful-api/
  2. https://hackernoon.com/restful-api-designing-guidelines-the-best-practices-60e1d954e7c9
  3. https://www.snyxius.com/blog/21-best-practices-designing-launching-restful-api/#.WVESmnWGMk-
  4. http://www.vinaysahni.com/best-practices-for-a-pragmatic-restful-api

常用 HTTP Methods

常见传参方式

规则

1. 常规

1.1对 Swagger Tag, 采用单数,小驼峰方式命名

```js
// Good
tags: courseSchedule
tags: news
```

```js
// Bad
tags: users                                                       (需要采用单数)
``` 

1.2 对所有的资源采用小驼峰名;单数名词使用复数,不可数名词正常使用;

```js
// Good
/courseSchedules    
/people                                                            (不可数名词正常使用)
```

```js
// Bad
/courseSchedule                                                   (单数名词需要复数)
/CourseSchedules                                                  (需要采用小驼峰命名方式)
```

- 路由最后不可以加 / 

```js
// Good
/courseSchedules
```
    
```js
// Bad
/courseSchedules/                                                (需要去掉 / )
```

1.3 路由参数使用小驼峰

```js
// Good
/courseSchedules?type=1
/courseSchedules/{courseScheduleID}
```

1.4 请求 body 采用参数采用大驼峰命名方式,参数定义采用直接定义,不可以采用 $ref 引用

```js
// Good
...
  post:
      ...
      parameters:
        - name: body
          in: body
          required: true
          schema:
            type: array
            items:
              type: object
              properties:
                StudentID:
                  type: string
                  description: 学生ID
      responses:
        '200':
...  
``` 

```js
// Bad
    post:
      tags:
        - class
      summary: 创建班级
      operationId: createClass
      description: 通过班级名称、考试类型、机构ID、助教ID 创建班级
      parameters:
        - name: body
          in: body
          description: 班级名称、考试类型、助教ID
          required: true
          schema:
            type: object
            $ref: '#/definitions/ClassInfo'
      responses:
        '200':
```

1.5 批量创建请求 body 的 schemaType = array; 单个创建请求 body 的 schemaType = object

```js
// Good
  (批量创建例子)
  ...
  post:
      ...
      parameters:
        - name: body
          in: body
          required: true
          schema:
            / type: array /
            items:
              type: object
              properties:
                StudentID:
                  type: string
                  description: 学生ID
      responses:
        '200':
 ...  
 
 (单个创建例子)
 ... 
  post:
       ...
      parameters:
        - name: body
          in: body
          description: 班级名称、考试类型、助教ID
          required: true
          schema:
            / type: object /
            properties:
              ClassName:
                type: string
              TestType:
                type: integer
                format: int32
              MemberID:
                type: string
      responses:
        '200':
 ...  
  ```

1.6 返回值使用大驼峰 (为了和数据库的字段保持统一)

```js
// Good
SuccessResponse 返回示例
{
    Message: '成功'
}

ErrorResponse 返回示例
{
    Message: '错误'
}

``` 

2. GET:(GET 用于获取和查询)

2.1 获取单个资源时,路由结构为 /资源复数/{资源ID}; 资源为不可数名词直接使用

```js
// Good
/courseSchedules/{courseScheduleID}
/members/{memberID}
```

```js
// Bad
/courseSchedule?courseScheduleID=1                            (需要把ID放进路由层)
/courseSchedules/{id}                                         (需要把ID参数名称写全)
/institutions/{institutionID}/members/{memberID}              (资源主键存在,不需要层级)
```

2.2 获取资源列表, 路由结构为 /资源复数, 条件参数放入 query;但参数属于业务层关系,一定要把参数放入路由

```js
// Good
/courseSchedules
/institutions/{institutionID}/members
/courseSchedules/{courseScheduleID}/planQuestRatings/{planQuestRatingID}/stepRatings
```

```js
// Bad
/courseSchedules?institutionID=1                              (有明确业务层级关系的参数,需要把参数放入路由)
```

2.3 需要单独把获取资源某个属性或抽象资源做成接口时可以采用动宾命名, 使用 get属性名称 / get抽象资源 ;另外不能使用 find 命名来区分返回信息是否为集合

```js
// Good
/institutions/{institutionID}/students/getVip
/students/{studentID}/planQuestRatings/getSummary
/courseSchedules/{courseScheduleID}/planQuestRatings/getNextTask
```

```js
// Bad
/institutions/{institutionID}/classes/findWithCount          (不能使用 find)
```

2.4 通过类别或条件来获取资源时,可采用 By 动宾结构来表述

```js
// Good
/words/getByPrefix
/institutions/{institutionID}/students/countByType 
```

2.5 获取扩展资源使用 getWith*** 方式来表述

```js
// Good
/institutions/{institutionID}/classes/getWithCount
/institutions/{institutionID}/members/getWithUserInfo
/courseSchedules/{courseScheduleID}/getWithUserName
/members/{memberID}/getWithUserInfo
```

3. POST:

只用于创建,路由结构为 /资源复数 ; 参数只能通过请求 Body 方式传参; 另外参数属于业务层级的也必须提取到路由层

```js
// Good
/courseSchedules                                (使用复数)
/people                                         (不可数名词直接使用)
/institutions/{institutionID}/licenseCategories (有明确的参数层级关系)
```

```js
// Bad
/courseSchedules?type=1&courseName=aa         (参数需要通过 Body 传递)
```

4. PUT: (PUT 用于修改/更新资源)

4.1 路由结构为 /资源复数/{资源ID}, 只能通过 Body 方式传参,另外参数属于务层级的也必须提取到路由层

```js
// Good
/courseSchedules/{courseScheduleID}                       (更新资源属性) 
```

```js
// Bad
/courseSchedules?courseScheduleID=1                        (需要把 ID 放进路由)
/users/{userID}?userName=AAA&age=12               (需要把参数通过 Body 方式传递)
```

4.2 把更新某个属性或抽象资源做成接口,使用 set 采用动宾结构: set属性 / set抽象资源

  ```js
// Good
/courseSchedules/{courseScheduleID}/setCourseName         (更新资源指定属性)  
/users/{userID}/setSimpleInfo              (更新抽象资源) 
```
```js
// Bad
/courseSchedules/{courseScheduleID}/courseName             (需要使用属性动宾命名,如 set)
```

4.3 修改/更新非资源属性,采用动宾结构,如果资源很明确只加一个动词即可

```js
// Good
     /licenseCategories/{licenseCategoryID}/charge   
  /wordBooks/{userWordBookID}/markUnitComplete
   /institutions/{institutionID}/students/{studentID}/upgradeToVip 
     /wordBooks/{userWordBookID}/activateP2
   /wordBooks/{userWordBookID}/enter    
```

```js
// Bad
/licenseCategories/{licenseCategoryID}/chargeLicenseCount  (如果资源很明确的,只加一个动词即可)

/institutions/{institutionID}/students/{studentID}/vip      (需要采用动宾命名)
```

4.4 业务通过修改状态标注状态删除, 使用 PUT 并在通过路由命名方式来表述

```js
// Good
PUT: 
     /institutions/{institutionID}/members/{memberID}/deactivate
```
```js
// Bad
DELETE: 
/institutions/{institutionID}/members/{memberID}     
```

5. DELETE:删除接口使用, 路由结构为 /资源复数/{资源ID}

```js
// Good
/courseSchedules/{courseScheduleID}
```

```js
// Bad
/courseSchedules?courseScheduleID=1                    (ID 放进路由)
```     

6. 接口路由放置规则

因为 swagger 路由采用自上而下,最大优先匹配进入原则。所有在相同路由前缀,模糊条件匹配路由靠后

```js
// Good
路由定义顺序
1. /institutions/{institutionID}/students/getVip
2. /institutions/{institutionID}/students/{studentID}
```

```js
// Bad
路由定义顺序
1. /institutions/{institutionID}/students/{studentID}
2. /institutions/{institutionID}/students/getVip
```
上一篇下一篇

猜你喜欢

热点阅读