diff --git a/docs/api_style.md b/docs/api_style.md deleted file mode 100644 index ba0315ee4..000000000 --- a/docs/api_style.md +++ /dev/null @@ -1,24 +0,0 @@ -### API - -这里仅考虑REST API的基本情况。 - -#### HTTP Method - -1. 读操作使用GET方法,写操作使用PUT/POST/DELETE方法,其中删除记录的操作使用DELETE方法。 -2. 使用PUT方法实现的API必须是幂等的(多次执行同样操作,结果相同)。 -3. POST则是实现非幂等的接口。 -4. 一般性的CRUD操作,R一般使用GET方法,C使用POST,U使用PUT方法,D使用DELETE方法。 - -#### URL -1. /api/为api地址的prefix -2. 每个项目的的root path后面整合的时候回指定为项目名 如: /api/assets -3. 一般性的增删查改(CRUD)API,完全使用HTTP method加上url提供的语义,url中的可变部分(比如上面提到的) -一般用来传递该API操作的核心实体对象的唯一ID,如果有更多的参数需要提供,GET方法请使用url parameter -(例如:"?client_id=xxxxx&app_id=xxxxxx"),PUT/POST/DELETE方法请使用请求体传递参数。 - - -#### 约定 - -1. 分页 ?page= -2. 每页数量 ?limit= -3. diff --git a/docs/api_style_guide.md b/docs/api_style_guide.md new file mode 100644 index 000000000..1bdc8a4cc --- /dev/null +++ b/docs/api_style_guide.md @@ -0,0 +1,143 @@ +## REST API规范约定 + +这里仅考虑REST API的基本情况。 + +### 协议 + +API与用户的通信协议,总是使用HTTPs协议。 + + +### 域名 + +这版api相对简单, 没有前后端分离, 没有独立app, 所以放在主域名下 + +``` +https://example.org/api/ +``` + +### 版本 + +将API的版本号放入URL + +``` +https://example.com/api/v1/ +``` + +另一种做法是,将版本号放在HTTP头信息中,但不如放入URL方便和直观。Github采用这种做法。 + + +### 路径 + +路径又称"终点"(endpoint),表示API的具体网址。 +在RESTful架构中,每个网址代表一种资源(resource),所以网址中不能有动词,只能有名词,而且所用的名词往往与数据库的表格名对应。一般来说,数据库中的表都是同种记录的"集合"(collection),所以API中的名词也应该使用复数。 +举例来说 cmdb中的assets列表, idc列表 + +``` +https://example.com/api/v1/assets +https://example.com/api/v1/assetgroups +https://example.com/api/v1/assetgroups/:id/assets +https://example.com/api/v1/assets/:id +https://example.com/api/v1/idcs +``` + +一般性的增删查改(CRUD)API,完全使用HTTP method加上url提供的语义,url中的可变部分(比如上面提到的) +一般用来传递该API操作的核心实体对象的唯一ID,如果有更多的参数需要提供,GET方法请使用url parameter +(例如:"?client_id=xxxxx&app_id=xxxxxx"),PUT/POST/DELETE方法请使用请求体传递参数。 + + +### HTTP Method + +对于资源的具体操作类型,由HTTP动词表示。 + +常用的HTTP动词有下面五个(括号里是对应的SQL命令)。 + +- GET(SELECT):从服务器取出资源(一项或多项)。 +- POST(CREATE):在服务器新建一个资源。 +- PUT(UPDATE):在服务器更新资源(客户端提供改变后的完整资源, 幂等 +- PATCH(UPDATE):在服务器更新资源(客户端提供改变的属性)。 +- DELETE(DELETE):从服务器删除资源。 + + +### 过滤信息 + +常见参数约定 + +``` +?keyword=localhost 模糊搜索 +?limit=10:指定返回记录的数量 +?offset=10:指定返回记录的开始位置。 +?page=2&per_page=100:指定第几页,以及每页的记录数。 +?sort=name&order=asc:指定返回结果按照哪个属性排序,以及排序顺序。 +?asset_id=1:指定筛选条件 +``` + + +### 状态码 + +服务器向用户返回的状态码和提示信息,常见的有以下一些(方括号中是该状态码对应的HTTP动词)。 + +- 200 OK - [GET]:服务器成功返回用户请求的数据,该操作是幂等的(Idempotent)。 +- 201 CREATED - [POST/PUT/PATCH]:用户新建或修改数据成功。 +- 202 Accepted - [*]:表示一个请求已经进入后台排队(异步任务) +- 204 NO CONTENT - [DELETE]:用户删除数据成功。 +- 400 INVALID REQUEST - [POST/PUT/PATCH]:用户发出的请求有错误,服务器没有进行新建或修改数据的操作,该操作是幂等的。 +- 401 Unauthorized - [*]:表示用户没有权限(令牌、用户名、密码错误)。 +- 403 Forbidden - [*] 表示用户得到授权(与401错误相对),但是访问是被禁止的。 +- 404 NOT FOUND - [*]:用户发出的请求针对的是不存在的记录,服务器没有进行操作,该操作是幂等的。 +- 406 Not Acceptable - [GET]:用户请求的格式不可得(比如用户请求JSON格式,但是只有XML格式)。 +- 410 Gone -[GET]:用户请求的资源被永久删除,且不会再得到的。 +- 422 Unprocesable entity - [POST/PUT/PATCH] 当创建一个对象时,发生一个验证错误。 +- 500 INTERNAL SERVER ERROR - [*]:服务器发生错误,用户将无法判断发出的请求是否成功。 + + +### 错误处理 + +如果状态码是4xx,就应该向用户返回出错信息。一般来说,返回的信息中将error作为键名,出错信息作为键值即可。 + +``` +{ + error: "Invalid API key" +} +``` + +### 返回结果 + +针对不同操作,服务器向用户返回的结果应该符合以下规范。 + +``` +GET /collection:返回资源对象的列表(数组) +GET /collection/resource:返回单个资源对象 +POST /collection:返回新生成的资源对象 +PUT /collection/resource:返回完整的资源对象 +PATCH /collection/resource:返回完整的资源对象 +DELETE /collection/resource:返回一个空文档 +``` + +### Hypermedia API + +RESTful API最好做到Hypermedia,即返回结果中提供链接,连向其他API方法,使得用户不查文档,也知道下一步应该做什么。 +比如,当用户向api.example.com的根目录发出请求,会得到这样一个文档。 + +``` +{"link": { + "rel": "collection https://www.example.com/zoos", + "href": "https://api.example.com/zoos", + "title": "List of zoos", + "type": "application/vnd.yourformat+json" +}} +``` + +上面代码表示,文档中有一个link属性,用户读取这个属性就知道下一步该调用什么API了。 + +rel表示这个API与当前网址的关系(collection关系,并给出该collection的网址), + +href表示API的路径,title表示API的标题,type表示返回类型。 +Hypermedia API的设计被称为HATEOAS。 +Github的API就是这种设计. + + +### 其它 + +(1)API的身份认证应该使用OAuth 2.0框架。 +(2)服务器返回的数据格式,应该尽量使用JSON + diff --git a/docs/python_style_guide.md b/docs/python_style_guide.md index 1f0209421..ba01c2eb8 100644 --- a/docs/python_style_guide.md +++ b/docs/python_style_guide.md @@ -142,6 +142,8 @@ value = my_dict['key'] 所有文档字符串均以reStructuredText格式编写,方便Sphinx处理。文档字符串的行数不同,布局也不一样。 如果只有一行,代表字符串结束的三个引号与代表字符串开始的三个引号在同一行。 如果为多行,文档字符串中的文本紧接着代表字符串开始的三个引号编写,代表字符串结束的三个引号则自己独立成一行。 +(有能力尽可能用英文, 否则请中文优雅注释) + ``` def foo(): @@ -179,6 +181,7 @@ def bar(): 注释的规范与文档字符串编写规范类似。二者均以reStructuredText格式编写。 如果使用注释来编写类属性的文档,请在#符号后添加一个冒号":"。 +(有能力尽可能用英文, 否则请中文优雅注释) ``` class User(object):