# 概述
# 总体设计
- 上海交通大学网络信息中心提供各类APIs,采用基于OAuth2.0 (opens new window)授权体系的安全策略,开放API在OAuth的保护下提供服务,在使用本文档所涉及的任何API前,请先通读API授权框架 重要 以及本概述的所有内容重要。
- 所有API使用RESTful Style。如:GET https://api.sjtu.edu.cn/v1/me/profile
- REST的动词仅使用 GET / PUT / UPDATE / DELETE 四种,通过method参数给出的动词拥有比HTTP协议更高的优先级,method参数大小敏感,参见RFC2616 (opens new window)。
- 所有Naming采用Camel命名法 (opens new window),access_token除外。
- Url和参数Case sensitive/大小写敏感 (opens new window)
# API表述
在本文档中每个API会被表述为如下格式:
每个API的调用链接后跟着获取令牌时支持的授权方式(上述授权码),以及该API的授权范围(scope)(上述profile等),授权方式和授权范围如果支持多个会显示多个同类型的标签,支持多个授权范围(scope)的接口您只需申请其中一个scope即可调用。
如果我们提供的SDK中支持了该API的使用会标记SDK,点击该标记可以直接访问对应SDK方法文档。
# 准备工作
# 申请应用以及授权范围
所有开放API接口在OAuth的保护下工作,为此您的应用系统必须首先申请jAccount接入,按照您需要调用的API接口的授权范围(scope)要求,勾选对应的访问授权。申请工作请登录my.sjtu.edu.cn或者交我办app在线完成,申请入口为服务大厅 -> 网络服务 -> jAccount接口申请。
申请通过后,您将获取到您的应用系统的一组参数:
- appId:应用系统的id,如japortal000000。
- appSecret:应用系统密钥,为一个长度为48字符的字符串。
# 申请增加授权范围
如果您以前已经申请过jAccount接口申请,只是以前申请时的scope不包含目前想调用的api所需scope,请发邮件到gwang@sjtu.edu.cn申请增加scope,邮件中请附带appId以及新增的scope代码。
# 令牌获取
每个API有其支持的授权方式及其所需的授权范围(Scope),在API的表述上会以标签的方式注明,在获取令牌时需按文档中支持的授权方式来获取,并带上指定的授权范围参数。
# 三种授权方式下令牌获取的示例请参见
- 使用授权码(Authorization Code)过程的 OIDC 认证模式
- 客户端凭据授予(Client Credentials Grant)
- 资源拥有者密码凭据许可(Resource Owner Password Credentials)
# 使用API SDK获取令牌
我们提供了JAVA版的API SDK,用于方便的用JAVA开发使用API的应用,通过SDK中封装的方法可以方便的获取客户端模式、密码模式的令牌,具体请参考此处。
# 构造请求
# 请求方法
所有API支持的请求方法包括
- GET 请求服务器返回指定资源
- PUT 请求服务器新增指定资源
- POST 请求服务器更新指定资源或者执行特定操作
- DELETE 请求服务器删除指定资源
# 请求头
- Content-Type 消息体的类型(格式),如无特殊说明,请默认设置"application/json"
# 请求消息体
请求消息体通常以结构化格式发出,与请求消息头中Content-type对应,如无特殊说明请按json格式组织请求数据。若请求消息体中参数支持中文,则中文字符必须为UTF-8编码。
并不是每个API请求都需要请求体,一些GET、DELETE类型的API就不需要请求消息体。
# 调用参数
# 令牌参数
令牌参数可以加在URI查询参数上或请求体里,也可以放在请求头。当放到查询参数或请求体时参数名为access_token,当放到请求头时请放到名为Authorization的头里,内容为Bearer {token}。可参见RFC6750 Authenticated Requests (opens new window)。
GET /v1/me/profile?access_token=tokenxxx HTTP/1.1
Host: api.sjtu.edu.cn
2
GET /v1/me/profile HTTP/1.1
Host: api.sjtu.edu.cn
Authorization: Bearer tokenxxx
2
3
# 路径参数
请求路径中的参数用{}包裹,例如:
该API的url中包含着修改邮件的id这个参数
# 查询参数
查询参数可以跟在API访问的资源路径之后,查询参数前面需要带一个"?",形式为“参数名=参数取值”
# 请求体参数
对于复杂结构的数据参数会被要求在请求体中传递
PUT https://api.sjtu.edu.cn/v1/notification HTTP/1.1
Content-Type: application/json
{
"name":"邮件标题",
"content":"邮件内容",
"emails":["yech@sjtu.edu.cn"],
"channels":["email"]
}
2
3
4
5
6
7
8
9
# 返回数据
# 状态码
HTTP响应状态代码指示特定HTTP请求是否已成功完成。状态代码由section 10 of RFC 2616 (opens new window)定义。在API响应中常见的状态码见下表。
状态码 | 描述 |
---|---|
200 OK | 请求成功 |
400 Bad Request | 请求错误(通常是参数错误) |
403 Forbidden | 拒绝请求(通常是鉴权失败) |
404 Not Found | 请求资源未找到(通常是url地址错误) |
405 Method Not Allowed | 请求的方法不被允许(通常是请求方法错误) |
500 Internal Server Error | 服务器内部错误(通常是API接口处理中有错误) |
503 Service Unavailable | 服务不可用(通常是API服务器因维护正在重启中或者停机中) |
一般在状态码为403时会在响应体中有具体的错误原因
HTTP/1.1 403 Forbidden
Content-Type: application/json;charset=UTF-8
Content-Language: zh-CN
Content-Length: 48
{"errno":10002,"error":"认证失败","total":0}
2
3
4
5
6
# 数据格式
所有复杂对象的数据格式使用JSON表示。比如:
{
"id": "21EC2020-3AEA-1069-A2DD-08002B30309D"
"account": "marstone",
"name": "Jinbo Du",
"uri": "https://home.sjtu.edu.cn/profile/marstone",
"kind": "canvas.profile",
"organize": 40100,
"portraits": {
"urlTiny": "https://home.sjtu.edu.cn/images/avatar/marstone_t.png",
"urlNormal": "https://home.sjtu.edu.cn/images/avatar/marstone_n.png"
}
}
2
3
4
5
6
7
8
9
10
11
12
其中,如未经说明:
- 所有对象id使用GUID。但kind为"canvas.profile"还带有account(string)字段, 一些外部数据结构可能拥有自己主键类型。
- 对象kind属性可以唯一标记对象类型
- 对象uri属性为web访问地址
- 所有时间类型使用long型,即Unix时间戳 (opens new window):到UTC 1970年1月1日的秒数
- 当动词为 PUT / POST 时,如无特殊说明,发送到服务器的需要被增、改的对象使用Json序列化
# 通用结构
API的返回值的通用结构包含:
参数名 | 类型 | 描述 |
---|---|---|
errno | int | 错误代码,返回0表示调用成功. |
error | string | 可选,错误信息 |
total | string | 可选,仅需分页时需要。表示查询数据的总长度。一般来说, total >= entities.length |
nextToken | string | 可选,仅分页时需要。查询下一页数据时可以使用的token |
entities | object[] | 返回的对象。如无具体对象返回,则数组长度应为0;如返回单条,则存放在entities[0];多条则依次存放入如数组。 |
HTTP/1.1 200 OK
Content-Type: application/json;charset=UTF-8
{
"errno":0,
"error":"success",
"total":0,
"entities":[{
"id":"A0000000-1111-2222-3333-012345678901",
"account":"testprofile",
"name":"张三",
"kind":"canvas.profile",
"timeZone":0
}]
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
HTTP/1.1 200
Content-Type: application/json;charset=UTF-8
{
"errno":10001,
"error":"BAD_PARAMETERS\n\nMORE_INFORMATION:phones is required",
"total":0
}
2
3
4
5
6
7
8
# 数据分页
- limit:对于大数据量的集合查询,可以通过给出limit(默认值为100)参数限制返回的条数。
- start:起始数据的index,start和pageToken两者给出一个即可。同时给出时,将忽略pageToken。
- pageToken:下一页的token,在查询结束后会以nextToken参数返回,详见下面说明。
下面例子中,是当limit=5时,查询用户circles的返回值:
{
errno:0,
error:"Succeed.",
total:20,
nextToken:"3A4bz-e",
entities: [
{ id:"100001", name:"网络信息中心", },
{ id:"100002", name:"网络信息中心开发部", },
{ id:"100003", name:"Z07037XX班", },
{ id:"100004", name:"2011年度网球初级班", },
{ id:"100005", name:"我的同事" }
]
}
2
3
4
5
6
7
8
9
10
11
12
13
- count:返回值中的count表示数据的总条数(并非本页返回的条数)。
- nextToken:用于查询下一页数据的参数,再次查询时,通过pageToken传入; 如果nextToken不存在,表示已到最后一页。
查询形如:
GET https://api.sjtu.edu.cn/v1/me/circles?pageToken=3A4bz-e&limit=5
# 统计API
统计类的api需要的参数包括:
1. filters:筛选条件,逗号并列分隔;筛选条件支持的操作符包括>,<,>=,<=,=,!= 其中=和!=后面的参数可以多个,以:分别代表in和not in;筛选条件操作符前为筛选的entity字段名,每个统计api会定义一系列所支持的筛选字段。 2. dimensions:要做分析的纬度字段,逗号并列分隔,每个统计api会定义一系列所支持的维度 3. fields:要统计的内容,可使用Count, Sum, Avg, Min, Max等聚合函数,逗号并列分隔,聚合函数的参数为entity字段名称,每个统计api会定义一系列所支持的统计字段名称
举例说明:
对于 流程实例的分析请求: GET /v1/instances/statistics
参数:
- filters=createTime>=1340121600,status!=1 // 分析2012年6月20日以后的,状态不是1的实例
- dimensions=status,creator // 以状态和创建人作为分析字段
- fields=count(id) // 对id计数
统计结果的数据结构是:
[{status:statusValue,creator:creatorValue,count_id:countValue}]
返回结果json格式,数组大小为dimension数量加上fields数量,fields对应的key是聚合函数名_字段名(如上例中的count_id)
# 错误代码
API错误代码表
错误代码 | 错误名称 | 错误信息 |
---|---|---|
-1 | UNKNOWN_ERROR | Unknown error, InfoPlus got itself in trouble. |
-2 | EXCEPTION | Exception |
10001 | BAD_PARAMETERS | Invalid Parameters |
10002 | AUTHENTICATION_FAILED | Authentication failed |
10003 | ENTITLE_FAILURE | EntitleService Unavailable |
10004 | INTERNAL_FAILURE | Server got itself in trouble |
10005 | INSERT_FAILURE | Insert Data failed |
10006 | UPDATE_FAILURE | Update Data failed |
10007 | ACCESS_TOKEN_EXPIRED | 令牌过期 |
10008 | GETDATA_NOT_FOUND | 数据不存在 |
10010 | AUTHENTICATION_SCOPE_FAILED | AUTHENTICATION_SCOPE_FAILED |
15005 | MODIFY_NOTIFICATION_VERBRESULT_ERROR | 通知的操作结果不可再次修改 |
15006 | RECEIVER_BEYOND_LIMIT | 接受人数不允许超出10位 |
15007 | OPERATION_OBJECT_ERROR | 操作对象缺失或错误 |
15008 | CIRCLE_ADMIN_NOT_TRUST_CIRCLE | 群管理员不允许信任自己的群 |
15009 | PROFILE_HAS_TRUST_CIRCLE | 已经信任圈子 |
15010 | NOTIFICATION_SEND_CHANNEL_ERROR | 通知的推送渠道有错误! |
50001 | UPLOAD_FILE_MESSAGE_NOTEXITS | 未找到需要上传的文件 |
50002 | UPLOAD_FILE_MESSAGE_TOOLARGE | 需要上传的文件过大 |
50003 | EDIT_FILE_MESSAGE_FILENAME_ERROR | 文件名称不合法 |
50004 | EDIT_FILE_MESSAGE_FILETAGS_ERROR | 文件Tags不合法 |
50005 | FILE_MESSAGE_APPID_INVALID | appid无效 |
50006 | FILE_UPLOAD_ACCOUNT_ERROR | 上传的文件账号错误 |
60001 | TASK_EXIST | 该任务在任务中心已存在 |
70001 | INVALID_CLASSES | 教学班信息不可用 |
API列表 →