Manager REST API设计开发规范
FusionInsight Manager REST API设计开发规范
FusionInsight Manager是FusionInsight产品统一的运维管理平台,提供全面的安装部署等运维功能。Manager除了提供自带WebUI外,还对外提供syslog、SNMP、REST_API等接口。syslog、SNMP接口提供的功能较为有限,syslog仅提供告警上报功能,SNMP可提供告警上报和服务级性能监控数据查询。对于灵活一些的第三方应用来讲,一般使用REST_API对接。Manager的REST_API接口提供了全量的运维管理能力。为标准化Manager REST_API接口的设计开发,制定了该规范。
使用对象
适用范围
术语定义
规则:编程时必须遵守的约定
说明:某个规则的具体解释
错误示例:违背某条规则的例子
正确示例:遵循某条规则的例子
例外情况:相应的规则不适用的场景
1 REST简介
REST(Representational State Transfer 表述性状态传递)是一种架构设计风格,最早由Roy Fielding在他的博士论文中提出(http://www.ics.uci.edu/~fielding/pubs/dissertation/rest_arch_style.htm)
通俗来讲就是:资源在网络中以某种表现形式进行状态转移。分解开来:
l Resource:资源.
l Representational:某种表现形式,比如用JSON,XML,JPEG等;
l State Transfer:状态变化。通过HTTP动词实现。
可简洁理解为:用URI定位资源,用HTTP动词(GET,POST,DELETE,DETC)描述操作。
其提出的设计概念和准则为:
l 网络上的所有事物都可被抽象为资源
l 每一个资源都有唯一的资源标识(resource identifier),对资源的操作不会改变这些标识
l 所有的操作都是无状态的
l 使用标准方法操作资源
REST规定,所有资源通过统一资源标识符(Universal Resource Identifier,URI)来识别和定位,并且针对这些资源而执行的操作是通过 HTTP 规范定义的。其核心操作为GET,PUT,POST,DELETE。对资源的操作可归为以下4种:
l 获取资源的一个表示:GET
l 创建一个新资源:向一个新URL发送PUT,或者向一个已有URL发送POST
l 修改已有资源:向已有URL发送 PUT
l 删除已有资源:DELETE
规则 1.1所有对外发布的REST API必须支持HTTPS协议
规则 1.2请求和响应的消息都必须设置媒体类型,并且采用UTF-8格式编码
说明:如没有特殊业务需要,必须使用application/json。如果提供的API是文档上传接口,媒体类型可按照流类型根据不同的业务需求自行确定。
Request
Accept: application/json
Content-Type: application/json;charset=UTF-8
Response
Content-Type: application/json;charset=UTF-8
规则 2.1使用统一的URI格式
说明:格式规定如下:https://server:port/{app}/api/{version}/{domain}/{rest-convention}
l server:port:服务所在地址,使用域名或IP,端口号可缺省(协议默认值)
l {app}:指定的应用名称
l /api:代表该应用下提供的API,用于区分API接口和其他静态资源
l {version}:代表API版本号,例如v1、v2
l {domain}:app所提供的顶级概念,可以是实体概念,也可以是app平台提供的服务。在Manager中,顶层的管理对象作为一个domain,比如集群,主机,用户等。
l {rest-convention}:REST资源
规则 2.2 URI中禁止使用大写字母,并采用蛇形命名法
说明:避免大小写混杂,仅在URI中使用小写字母是一种很好的做法,蛇形命名是指由一个或多个小写完整单词用下划线分隔连结在一起组成。
举例:
/clusters/{cluster_id}
/clusters?cluster_name=test
规则2.3 URI结尾不应包含正斜杠分隔符(/)
说明:正斜杠(/)不会增加语义值,且可能导致混淆。REST API不允许一个尾部的斜杠,不应该将它包含在提供给客户端的链接的结尾处。
规则2.4 通过父级资源访问资源
说明:例如,“/clusters/{cluster_id}”中, clusters即为父级资源
不过这里需要注意,避免因资源嵌套太深导致URI过长,建议URI资源嵌套不超过3级
规则2.5 使用复数名词定义资源集
说明:使用复数名词定义资源集。比如在/users/{ user_name }中,我们使用users来标识所有的用户资源,下面一级的{user_name}代表单数,即指定的用户。再比如:
/clusters/{cluster_id}/services/{service_name}:clusters和services均为复数
规则2.6 URL中不能包含URL特殊字符,需要使用特殊字符时需要进行转义编码
某些字符,由于有特殊含义或者系统保留,容易被网络防火墙阻断导致URI调用不生效,不建议在URI中使用,如果必须要用需要用转义编码替换
举例:
RFC1738标准参考地址:
http://www.faqs.org/rfcs/rfc1738.html
规则2.6 URI和参数经过URI编码之后的总长度不超过2048
说明: HTTP协议本身不对URI的长度作事先的限制,服务器必须能够处理任何他们提供资源的URI,并且应该能够处理无限长度的URIs,这种无效长度的URI可能会在客户端以基于GET方式的请求时产生。如果服务器不能处理太长的URI的时候,服务器应该返回414状态码(此状态码代表Request-URI太长)。虽然协议中未明确对URI进行长度限制,但是在真正实现中,不同的浏览器和服务端框架对URI长度还是有限制的,因此URI在设计时必须考虑超长问题。
以下是不同浏览器对URI的长度限制:
游览器 |
最大长度(字符数) |
备注 |
Internet Explorer |
2083 |
如果超过这个数字,提交按钮没有任何反应 |
Firefox |
65,536 |
|
chrome |
8182 |
|
Safari |
80,000 |
|
Opera |
190,000 |
|
curl(linux下指令) |
8167 |
规则3.1 允许使用的HTTP方法
说明:
在HTTP规范中定义了GET/PUT/POST/DELETE/HEAD/OPTIONS/TRACE/PATCH等HTTP操作。常见的使用中,只允许按照以下定义使用相应的HTTP方法:
GET:读取资源
POST:创建资源
PUT:修改资源,或者对资源进行操作
DELETE:删除、回收资源
使用GET/POST/PUT/DELETE四种方法之外的方法,可能遇到某些服务器不支持的情形。例如,PATCH方法(对已知资源进行局部更新),支持PATCH方法的容器比较少,暂不建议使用)
RFC 5789(PATCH Method for HTTP)文档明确说明:“ PATCH is neither safe nor idempotent as defined by [RFC2616], Section9.1.” ,即 PATCH方法非幂等。此外,由于业界对PATCH方法的使用风格不统一,以及多数标准开发框架对PATCH的支持不完善,所以在能够使用PUT请求定义操作接口的情况下,不建议业务使用PATCH操作。若某些业务必须使用,需定义详细的请求消息体格式和使用场景。
规则3.2 合理的使用HTTP方法
说明:
(1)对资源进行不符合CRUD(创建、查询、更新和删除)操作时,HTTP方法使用POST。
例:启动HDFS服务:
POST /clusters/1/services/HDFS/commands/start
(2)如果对资源的查询、删除操作时需要携带复杂的条件参数(如果通过URI参数形式携带可能导致URI长度超过浏览器/HTTP Server允许的长度或复杂参数数据结构),或这些参数仅能在请求的body中携带(敏感信息),那么使用POST方法。
注:GET方法一般不携带请求体。
例:按预设条件查询主机列表:
POST /hosts,其查询条件在请求body中携带。
规则3.2 HTTP方法安全性和幂等性要求
说明:
HTTP协议规定了不同方法的安全特性和幂等特性,作为服务提供者的服务器必需为客户端提供这些特性。
安全性,仅指该方法的多次调用不会产生副作用,不涉及传统意义上的“安全”,这里的副作用是指资源状态。即,安全的方法不会修改资源状态,尽管多次调用的返回值可能不一样(被其他非安全方法修改过)。
幂等性,是指该方法多次调用返回的效果(形式)一致,客户端可以重复调用并且期望同样的结果。幂等的含义类似于编程语言中的setter方法,一次调用和多次调用产生的效果是一致的,都是对一个变量进行赋值。安全性和幂等性含义有些接近,容易搞混。
HTTP方法的安全性和幂等性见下表:
方法名 |
安全性 |
幂等性 |
GET |
是 |
是 |
DELETE |
否 |
是 |
PUT |
否 |
是 |
POST |
否 |
否 |
GET操作是安全的。所谓安全是指不管进行多少次操作,资源的状态都不会改变。比如用GET查看集群信息,不管查看多少次,集群都没有变化。因为GET操作是安全的,所以它自然也是幂等的
PUT,DELETE操作是幂等的。所谓幂等是指不管进行多少次操作,结果都一样。比如用PUT修改集群信息,然后再做同样的操作,每次操作后的结果并没有不同,DELETE也是一样。
POST操作既不是安全的,也不是幂等的,比如重复创建集群,有可能每次都创建一个新的,每次创建的集群状态,时间可能都不一致。
安全和幂等的意义在于,当操作没有达到预期的目标时,我们可以不停的重试,而不会对资源产生副作用。
规则3.3 查询资源列表时支持分页
说明:如果记录请求的资源数量很多,服务器不可能都将它们返回给客户端。API应该提供分页参数。
通过在GET请求的URI中添加limit和offset参数实现分页返回列表信息。
示例: GET /users?offset=0&limit=10
语意: 返回起始记录数为0的用户列表。
limit:限制每页显示的条目数量。
offset:查询的起始位置,默认从0开始。
另外,返回结果中需要携带条目总数,用totalCount表示
有些规范中在HTTP Header中添加Range参数来表示分页,本规范中禁止这样使用,使用HTTP Header会增加额外的处理逻辑,易用性不强
规则3.3 查询资源列表时支持排序
说明:
示例: GET /users?order_by=name&order=asc
语意: 返回按姓名升序的用户列表。
order_by:排序字段
order:排序方式,取值范围asc,desc
规则3.3 支持属性条件过滤
说明:
建议查询资源列表的API支持属性条件过滤,让用户可以只获取满足需求的资源列表,也可以根据业务特点要求用户必须指定过滤条件:
简单过滤:采用“属性=value”,多个值时用逗号间隔,例如“services=HDFS,Yarn”。
(1)对于支持的过滤字段,但过滤值为空字符串,会返回指定过滤字段的值为空字符串的资源(而不是忽略该过滤条件,返回全部资源)。
(2)对于响应体为资源集合的API,可要求请求URI中必须携带某些属性过滤条件。
规则4.1请求相应消息体必须支持JSON格式封装
规则4.2 JSON格式消息体中,key值采用小驼峰命名风格
说明:由于使用JSON作为消息体格式,因此对象模型中的JSON key值仍然按照JSON的格式规范,采用小驼峰风格,例如
{
"description": "string",
"id": "string",
"name": "string",
"sysUserGroup": true,
"userRoles": [
"string"
],
"users": [
"string"
]
}
规则 4.3日期时间属性定义规范
说明:
(1) API返回的资源的日期/时间属性应该采用ISO 8601格式,YYYY-MM-DDTHH:mm:ss.sssZ,ISO 8601参见 https://en.wikipedia.org/wiki/ISO_8601
(2) 使用统一的标准时间,避免时差。约定统一采用UTC。UTC参见http://en.wikipedia.org/wiki/Coordinated_Universal_Time
(3) 客户端应该采用ISO 8601格式的时间给服务端。API服务端应该能够解析任何有效的ISO 8601的时间戳在任何时区。
注意:UTC时间全称为协调世界时,又称世界统一时间,UTC代表的是时间标准,ISO 8601则是表示时间的一种标准格式
YYYY-MM-DDTHH:mm:ss.sssZ
T 表示日期和时间中间的分隔符
Z 表示是UTC时间,其他时区后面用加时差表示
例如,UTC时间下午2点30分5秒表示为14:30:05Z或143005Z,当时的北京时间表示为22:30:05+08:00或223005+0800,也可以简化成223005+08
规则4.4 明确定义枚举情况的参数表示形式,禁止使用魔鬼数字代替
说明:例如,true,false,禁止使用0,1等不易理解的值
服务的运行状态:GOOD, BAD, PARTIALLY_HEALTHY, STOPPED, START_FAILED, STOP_FAILED, STARTING, STOPPING, UNKNOWN
规则4.5 API应保证属性一致性
说明:属性名称全局应该一致,同一种含义的属性不应该在不同的接口名称不一致。例如分页参数offset:有些地方采用start,有些采用offset,虽然属性含义一致,但是为了API的易理解性,我们统一采用offset。另外,例如在Manager的管理模型中role通常代表服务角色,但是该名称和用户管理中的角色冲突,为了避免混淆,将用户体系中的角色命名为userRole,用以区分。
规则5.1 使用HTTP状态码描述API操作状态
说明:HTTP状态码(HTTP Status Code)是用以表示服务器HTTP响应状态的3位数字代码。它由 RFC 2616 规范定义的,并得到RFC 2518、RFC 2817、RFC 2295、RFC 2774、RFC 4918等规范扩展,完整的HTTP状态码参见附录A。
从实际的操作状态,HTTP状态码可以分为3类:
(1) 一切工作正常,对应2xx状态码
(2) 调用API的应用做错了什么事情(例如,请求参数不合法),对应4xx状态码
(3) API的实现出现了异常(如服务数据连接不正常,服务不能对外提供操作),对应500状态码
目前,建议使用200、201、202、204、400、403、404和500这8个状态码。
200(OK):处理请求成功,并且有响应体返回。
用于查询类请求,如果查询对象存在,并以json格式在响应体中返回,响应的状态码为200。
注意:
(1) 在批量查询的场景下,由于批量查询实际是在全量查询的基础上增加了过滤条件,所以即使没有满足过滤条件的记录,依旧有响应体返回,只是此时返回的是空列表,而不是null,所以响应的状态码也为200。
(2) 用ID来对单条记录进行查询时,如果要查询的“资源”不存在,响应状态码为404(Not Found)。
201(Created):创建请求成功
对于POST请求,如果操作结果有数据返回,如创建用户成功时返回用户的id,响应的状态码为201。
202(Accepted): 表示一个请求已经进入后台排队(异步任务)。
204(No Content): 处理请求成功,但无响应体。
204专用于非查询类请求成功,但是无数据返回的场景。
400(Bad Request): 请求错误
请求传递的请求体不满足接口定义:如缺少必须字段、非空字段值为空、请求体为null等。
403 (Forbidden): 禁止访问
表示请求方对要处理的资源不具备权限,拒绝为其服务的场景。
404(Not Found):资源找不到
用ID来对单条记录进行查询时,如果要查询的“资源”不存在,响应状态码为404。
500(Internal Server Error):不可预知的错误
服务器内发生了内部错误,需要维护人员定位并解决
规则5.2 请求成功和请求失败时分别对应不同的响应结果
说明:请求成功和请求失败时要求对应不同的HTTP状态码,当请求失败时要求有响应的错误代码和错误描述(见规则5.3),请求成功时不应携带错误描述和错误代码冗余字段,因此要求当请求成功和请求失败时需要对应不同的影响结果。
例如,”获取集群基本信息API”
GET /clusters/{cluster_id}
当请求成功返回状态码200时,响应结果如下:
{
"authenticationMode": "string",
"badHostsNum": 0,
"badServiceNum": 0,
"creationTime": 0,
"description": "string",
"hostsNum": 0,
"id": 0,
"name": "string",
"serviceNum": 0
}
当请求失败返回状态码404时,响应结果如下:
{
"errorCode": "string",
"errorMessage": string
}
规则5.3 错误响应要求必须由errorCode,errorMsg两部分组成
说明:为了详细描述请求失败的原因,响应结果应当包含errorCode,errorMsg内容,分别描述错误码和错误信息。各个服务都需要自定义自己的错误码。每个服务要定义自己的错误码。错误码遵循如下格式:
{ServiceName}_{StatusCode}_xxxx(0001~9999)
举例:
服务 |
错误码 |
说明 |
Controller |
CONTROLLER_4000001 |
集群名称不合法 |
CONTROLLER_4040001 |
集群不存在 |
|
CONTROLLER_5040001 |
AOS服务无法访问。 |
以下是Manager中常见的服务列表
服务 |
说明 |
Controller |
核心控制服务 |
AOS |
权限管理服务 |
ACS |
用户管理服务 |
WEB |
Web服务 |
CEP |
监控汇聚服务 |
PMS |
监控服务 |
FMS |
告警服务 |
规则5.2 尽量使用对象封装响应结果
说明:接口返回的响应结果不建议使用基本数据类型或集合类型直接封装,为了考虑之后API的扩展,建议使用对象封装响应结果。例如,支持分页的接口都会在返回结果中都会携带一个数据总量的属性,如果刚开始未支持分页,返回结果使用集合类型,后面再想支持分页就势必带来不兼容性的接口变更。
规则 6.1 使用HWSF框架进行参数校验
Huawei WSF安全框架是一个集成了Spring Security和ESAPI的安全能力的基础上,结合我司安全规范要求以及产品实际情况进行定制开发的、针对java语言的 web类系统的安全开发框架,产品开发过程中可以使用该框架提供的安全能力来构建安全的web应用。
HWSF框架提供了对输入参数校验的能力,分别包含以下内容:
l 提供对HTTP request头参数校验
l 提供对GET请求参数校验
l 提供对POST请求参数校验
l 提供对JSON内容校验
l 提供对XML内容校验
l 提供19种校验器:如判空校验器、字符串校验器、EMAIL格式校验器等
提供调用API对数据进行校验
详细指导参见《Huawei+WSF+V100R001使用指南_2.0.1+.docx》
规则 6.1 URI中禁止传递带有敏感数据的参数
说明:Token,Password都属于敏感参数,禁止URI中携带该类型参数。敏感数据传输必须使用HTTPS协议,并且通过POST方法传递。
例如,删除主机API中的osPassword属性,需要放到body中
DELETE /hosts
{
"forceMode": true,
"hosts": [
"string"
],
"osPassword": "string",
"osUserName": "string"
}
规则 6.2 使用HTTP Basic Authentication作为API的认证方式
HTTP Basic Authentication是HTTP的官方认证协议,HTTP 基本认证包含以下过程
基本认证步骤:
1、客户端访问一个受http基本认证保护的资源。
2、服务器返回401状态,要求客户端提供用户名和密码进行认证。(验证失败的时候,响应头会加上WWW-Authenticate: Basic realm="请求域"。)
401 Unauthorized
WWW-Authenticate: Basic realm="Authentication Required"
3、客户端将输入的用户名密码用Base64进行编码后,采用非加密的明文方式传送给服务器。
Authorization: Basic xxxxxxxxxx.
4、服务器将Authorization头中的用户名密码解码并取出,进行验证,如果认证成功,则返回相应的资源。如果认证失败,则仍返回401状态,要求重新进行认证。
由于HTTP协议是无状态的,因此同一个客户端对服务器的每个请求都要求认证。把 "用户名+冒号+密码" 用BASE64转码后的字符串并不安全,所以必须使用HTTPS传输。
规则 6.2 使用Spring Security框架进行API鉴权
对于资源的操作权限限制,通过Spring Security框架进行鉴权,业务可以根据用户的实际权限选择暴露GET/POST/PUT/DELETE的一种或几种,对不安全的资源操作不对外暴露
规则 6.3 管理面所有对系统产生影响的用户活动、操作指令必须记录审计日志
1、日志记录需涵盖管理面上所有的用户活动,包括:
(1)登录和注销
(2)增加、删除用户和用户属性(帐号、口令等)的变更;
(3)用户的锁定和解锁,禁用和恢复;
(4)角色权限变更;
(5)系统相关安全配置(如安全日志内容配置)的变更;
(6)重要资源的变更,如某个重要文件的删除、修改等。
2、日志记录需涵盖管理面上所有的操作指令,包括:
(1)对系统配置参数的修改;
(2)对系统进行启动、关闭、重启、暂停、恢复、倒换;
(3)对业务的加载、卸载;
(4)软件的升级操作,包括远程升级和本地升级;
(5)对重要业务数据的创建、删除、修改;
3、管理面上传/导入文件、下载/导出包含敏感信息的文件及对文件的远程删除操作(如:使用FTP/SFTP)必须记录日志。对于第三方OS/DB,如果不支持记录日志、记录内容不全或者启用记录存在严重性能影响,且风险可控,不强制要求。
日志内容要能支撑事后的审计,记录内容至少包括用户ID、时间、事件类型、被访问资源的名称、访问发起端地址或标识、访问结果。
规则 6.5 日志中禁止打印敏感信息
说明:根据公司安全红线规定,日志中禁止明文记录敏感数据 ,包括口令、对称密钥、预共享密钥、私钥、敏感个人数据、Session ID等。
使用Swagger规范(即OpenAPI规范)描述文档,使用Springfox作为文档生成工具
其他待补充
规则 8.1 API变更管理要求
l 可以接受的兼容性接口变更
² 请求资源,请求消息体增加可选属性
² 请求资源,响应消息体增加属性
² 修复BUG:一个请求,之前返回错误的结果响应,变更后返回成功的响应
l 下列情况的API变更,一般不可接受
² 请求资源,请求消息体增加必选属性
² 修复BUG:一个请求之前是成功的,但现在返回错误。
² 变更或删除一个资源属性
² 更改一个属性的语意。例如:dhcp_enable之前为是否打开dhcp,现在为是否静态注入IP
² 变更或删除一个response header
² 变更成功时的响应码
l 有些情况下不兼容API接口变更可以考虑
² 变更是为了改善接口一致性,有时候是为了接口一致性,使接口对外更好理解。可以考虑在新的版本API中对接口进行统一变更。
² 修改响应错误码使之更加准确
序号 |
文献编号或出处 |
文献名称
|
1 |
《RESTful API 设计指南》 |
|
2 |
《HTTP 接口设计指北》 |
|
3 |
http://w3.huawei.com/info/cn/doc/viewDoc.do?did=8888653&cata=352891 |
《云服务API设计规范-V1.0》 |
4 |
《RESTful 介绍及设计思路》 |
|
5 |
http://3ms.huawei.com/hi/group/2833243/file_11208311.html?for_statistic_from=my_group_file |
《API参考文档写作指南》 |
常用的HTTP响应码(状态码):
响应码 |
说明 |
|
200 |
OK |
成功返回状态,对应GET,PUT,PATCH,DELETE. |
201 |
Created |
成功创建 |
202 |
Accepted |
服务器已接受请求,但尚未处理 |
301 |
Moved Permanently |
资源已被永久的改变了位置 |
303 |
See Other |
对应当前请求的响应可以在另一个 URI 上被找到 |
304 |
Not Modified |
HTTP缓存有效 |
400 |
Bad Request |
请求格式错误 |
401 |
Unauthorized |
未授权 |
403 |
Forbidden |
授权成功,但该用户没有权限 |
404 |
Not Found |
请求的资源不存在 |
405 |
Method Not Allowed |
授权成功的用户不允许使用该HTTP方法 |
410 |
Gone |
被请求的资源在服务器上已经不再可用,而且没有任何已知的转发地址。 |
415 |
Unsupport Media Type |
请求时的内容的类型不正确 |
422 |
Unprocessable Entity |
用户校验错误 |
429 |
Too Many Request |
请求过多 |
500 |
Internal Server Error |
服务器内部错误 |
503 |
Server Unavailable |
服务器当前不能处理客户端的请求,一段时间后可能恢复正常 |
- 点赞
- 收藏
- 关注作者
评论(0)