From b1d2a070dccc8e94ba62e73ea5062dc5c0ec65ca Mon Sep 17 00:00:00 2001 From: Yan Qing Date: Wed, 1 Apr 2020 18:03:03 +0800 Subject: [PATCH] Improve swagger document; Add user and group documents; Fix settings API. --- CHANGELOG.md | 16 + Makefile | 10 +- README.md | 2 +- doc/api.md | 521 --------- doc/openapi.md | 2247 +++++++++++++++++++++++++++++++++++++++ doc/openapi.yaml | 927 ++++++++++++++++ doc/openapi_header.yaml | 456 ++++++++ doc/paths_group.yaml | 257 +++++ doc/paths_user.yaml | 197 ++++ doc/paths_version.yaml | 17 + doc/swagger.yaml | 387 ------- doc/swagger_header.yaml | 141 ++- doc/swagger_user.yaml | 198 ---- src/api/router.go | 8 +- src/api/user_test.go | 20 + src/bll/user.go | 7 +- 16 files changed, 4290 insertions(+), 1121 deletions(-) delete mode 100644 doc/api.md create mode 100644 doc/openapi.md create mode 100644 doc/openapi.yaml create mode 100644 doc/openapi_header.yaml create mode 100644 doc/paths_group.yaml create mode 100644 doc/paths_user.yaml create mode 100644 doc/paths_version.yaml delete mode 100644 doc/swagger.yaml delete mode 100644 doc/swagger_user.yaml diff --git a/CHANGELOG.md b/CHANGELOG.md index 54030c5..d5164c7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,22 @@ All notable changes to this project will be documented in this file starting fro This project adheres to [Semantic Versioning](http://semver.org/). ----- +## [1.2.2] - 2020-04-01 + +**Change:** + +- Improve swagger document. +- add user and group documents. + +**Fixed:** + +- Fix settings API. + +## [1.2.1] - 2020-03-29 + +**Change:** + +- Update Gear version. ## [1.2.0] - 2020-03-25 diff --git a/Makefile b/Makefile index 13726ca..9a56ac4 100644 --- a/Makefile +++ b/Makefile @@ -13,10 +13,12 @@ test: doc: # https://github.com/Mermade/widdershins # Install: npm i -g widdershins - echo "# Content generated by 'make doc'. DO NOT EDIT.\n" > doc/swagger.yaml - cat doc/swagger_header.yaml >> doc/swagger.yaml - cat doc/swagger_user.yaml >> doc/swagger.yaml - widdershins --language_tabs 'shell:Shell' 'http:HTTP' --summary doc/swagger.yaml -o doc/api.md + echo "# Content generated by 'make doc'. DO NOT EDIT.\n" > doc/openapi.yaml + cat doc/openapi_header.yaml >> doc/openapi.yaml + cat doc/paths_version.yaml >> doc/openapi.yaml + cat doc/paths_user.yaml >> doc/openapi.yaml + cat doc/paths_group.yaml >> doc/openapi.yaml + widdershins --language_tabs 'shell:Shell' 'http:HTTP' --summary doc/openapi.yaml -o doc/openapi.md BUILD_TIME := $(shell date -u +"%FT%TZ") BUILD_COMMIT := $(shell git rev-parse HEAD) diff --git a/README.md b/README.md index 97c786e..73aa842 100644 --- a/README.md +++ b/README.md @@ -10,4 +10,4 @@ ## Documentation (WIP) -[API 文档](https://github.com/teambition/urbs-setting/blob/master/doc/api.md) +[API 文档](https://github.com/teambition/urbs-setting/blob/master/doc/openapi.md) diff --git a/doc/api.md b/doc/api.md deleted file mode 100644 index d6df34d..0000000 --- a/doc/api.md +++ /dev/null @@ -1,521 +0,0 @@ ---- -title: urbs-setting -language_tabs: - - shell: Shell - - http: HTTP -toc_footers: [] -includes: [] -search: true -highlight_theme: darkula -headingLevel: 2 - ---- - -

urbs-setting v1.2.0

- -> Scroll down for code samples, example requests and responses. Select a language for code samples from the tabs above or the mobile navigation menu. - -Urbs 灰度平台灰度策略服务 - -Base URLs: - -* https://urbs-setting:8443 - -

Default

- -## 服务健康检查接口 - -> Code samples - -```shell -# You can also use wget -curl -X GET https://urbs-setting:8443/healthz \ - -H 'Accept: application/json' - -``` - -```http -GET https://urbs-setting:8443/healthz HTTP/1.1 -Host: urbs-setting:8443 -Accept: application/json - -``` - -`GET /healthz` - -> Example responses - -> 200 Response - -```json -{ - "db_connect": true -} -``` - -

Responses

- -|Status|Meaning|Description|Schema| -|---|---|---|---| -|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|请求成功|[Healthz](#schemahealthz)| - - - -

Version

- -获取 urbs-setting 服务版本信息 - -## 获取版本信息 - -> Code samples - -```shell -# You can also use wget -curl -X GET https://urbs-setting:8443/version \ - -H 'Accept: application/json' - -``` - -```http -GET https://urbs-setting:8443/version HTTP/1.1 -Host: urbs-setting:8443 -Accept: application/json - -``` - -`GET /version` - -> Example responses - -> 200 Response - -```json -{ - "name": "urbs-setting", - "version": "v1.2.0", - "gitSHA1": "cd7e82a", - "buildTime": "2020-03-25T11:44:33.996Z" -} -``` - -

Responses

- -|Status|Meaning|Description|Schema| -|---|---|---|---| -|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|请求成功|[Version](#schemaversion)| - - - -

User

- -User 用户相关接口 - -## 该接口用于灰度网关。获取指定 uid 用户灰度标签在指定 product 产品下的所有(未分页,最多 400 条)灰度标签,包括从 group 群组继承的灰度标签,按照 label 指派时间反序。网关只会取匹配 client 和 channel 的第一条。标签列表不是实时数据,会被服务缓存,缓存时间在 config.cache_label_expire 配置,默认为 1 分钟 - -> Code samples - -```shell -# You can also use wget -curl -X GET https://urbs-setting:8443/users/{uid}/labels:cache?product=string \ - -H 'Accept: application/json' - -``` - -```http -GET https://urbs-setting:8443/users/{uid}/labels:cache?product=string HTTP/1.1 -Host: urbs-setting:8443 -Accept: application/json - -``` - -`GET /users/{uid}/labels:cache` - -

Parameters

- -|Name|In|Type|Required|Description| -|---|---|---|---|---| -|uid|path|string|true|用户 UID,当 uid 对应用户不存在时,该接口会返回空灰度标签列表| -|product|query|string|true|产品名称,当 product 对应产品不存在时,该接口会返回空灰度标签列表| - -> Example responses - -> 200 Response - -```json -{ - "timestamp": 1585129360, - "result": [ - { - "l": "beta", - "cls": [ - "ios", - "android", - "web" - ], - "chs": [ - "stable", - "beta", - "dev" - ] - } - ] -} -``` - -

Responses

- -|Status|Meaning|Description|Schema| -|---|---|---|---| -|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|请求成功|Inline| - -

Response Schema

- - - -## 获取指定 uid 用户所有灰度标签,不包括从群组继承的灰度标签,支持分页。考虑到灰度标签不会很多,暂未支持根据 product 过滤 - -> Code samples - -```shell -# You can also use wget -curl -X GET https://urbs-setting:8443/v1/users/{uid}/labels \ - -H 'Accept: application/json' \ - -H 'Authorization: string' - -``` - -```http -GET https://urbs-setting:8443/v1/users/{uid}/labels HTTP/1.1 -Host: urbs-setting:8443 -Accept: application/json -Authorization: string - -``` - -`GET /v1/users/{uid}/labels` - -

Parameters

- -|Name|In|Type|Required|Description| -|---|---|---|---|---| -|Authorization|header|string|true|请求 JWT token, 格式如: `Bearer xxx`| -|uid|path|string|true|用户 UID,当 uid 对应用户不存在时,该接口会返回 404 错误| -|pageSize|query|integer(int32)|false|分页大小,默认为 10,(1-1000]| -|pageToken|query|string|false|分页请求标记,来自于响应结果的 nextPageToken| - -> Example responses - -> 200 Response - -```json -{ - "totalSize": 99, - "nextPageToken": "", - "result": [ - { - "hid": "AwAAAAAAAAB25V_QnbhCuRwF", - "product": "teambition", - "name": "beta", - "desc": "string", - "channels": [ - "beta" - ], - "clients": [ - "web" - ], - "status": 0, - "created_at": "2020-03-25T11:44:34.000Z", - "updated_at": "2020-03-25T11:44:34.000Z", - "offline_at": null - } - ] -} -``` - -

Responses

- -|Status|Meaning|Description|Schema| -|---|---|---|---| -|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|请求成功|[LabelsInfoRes](#schemalabelsinfores)| -|401|[Unauthorized](https://tools.ietf.org/html/rfc7235#section-3.1)|请求失败|[ErrorResponse](#schemaerrorresponse)| -|404|[Not Found](https://tools.ietf.org/html/rfc7231#section-6.5.4)|请求失败|[ErrorResponse](#schemaerrorresponse)| - - - -## 强制刷新指定用户的灰度标签列表缓存 - -> Code samples - -```shell -# You can also use wget -curl -X PUT https://urbs-setting:8443/v1/users/{uid}/labels:cache \ - -H 'Accept: application/json' \ - -H 'Authorization: string' - -``` - -```http -PUT https://urbs-setting:8443/v1/users/{uid}/labels:cache HTTP/1.1 -Host: urbs-setting:8443 -Accept: application/json -Authorization: string - -``` - -`PUT /v1/users/{uid}/labels:cache` - -

Parameters

- -|Name|In|Type|Required|Description| -|---|---|---|---|---| -|Authorization|header|string|true|请求 JWT token, 格式如: `Bearer xxx`| -|uid|path|string|true|用户 UID,当 uid 对应用户不存在时,该接口会返回 404 错误| - -> Example responses - -> 200 Response - -```json -{ - "result": true -} -``` - -

Responses

- -|Status|Meaning|Description|Schema| -|---|---|---|---| -|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|请求成功|[BoolRes](#schemaboolres)| -|401|[Unauthorized](https://tools.ietf.org/html/rfc7235#section-3.1)|请求失败|[ErrorResponse](#schemaerrorresponse)| -|404|[Not Found](https://tools.ietf.org/html/rfc7231#section-6.5.4)|请求失败|[ErrorResponse](#schemaerrorresponse)| - - - -# Schemas - -

NextPageToken

- - - -```json -"" - -``` - -*nextPageToken* - -### Properties - -|Name|Type|Required|Restrictions|Description| -|---|---|---|---|---| -|nextPageToken|string|false|none|用于分页查询时用于获取下一页数据的 token,当为空值时表示没有下一页了| - -

TotalSize

- - - -```json -99 - -``` - -*totalSize* - -### Properties - -|Name|Type|Required|Restrictions|Description| -|---|---|---|---|---| -|totalSize|integer(int64)|false|none|当前分页查询的总数据量| - -

ErrorResponse

- - - -```json -{ - "error": "NotFound", - "message": "user 50c32afae8cf1439d35a87e6 not found" -} - -``` - -### Properties - -|Name|Type|Required|Restrictions|Description| -|---|---|---|---|---| -|error|string|false|none|错误代号| -|message|string|false|none|错误详情| - -

BoolRes

- - - -```json -{ - "result": true -} - -``` - -### Properties - -|Name|Type|Required|Restrictions|Description| -|---|---|---|---|---| -|result|boolean|false|none|是否成功| - -

Version

- - - -```json -{ - "name": "urbs-setting", - "version": "v1.2.0", - "gitSHA1": "cd7e82a", - "buildTime": "2020-03-25T11:44:34.001Z" -} - -``` - -### Properties - -|Name|Type|Required|Restrictions|Description| -|---|---|---|---|---| -|name|string|false|none|服务名称| -|version|string|false|none|当前版本| -|gitSHA1|string|false|none|git commit hash| -|buildTime|string(date-time)|false|none|打包构建时间| - -

Healthz

- - - -```json -{ - "db_connect": true -} - -``` - -### Properties - -|Name|Type|Required|Restrictions|Description| -|---|---|---|---|---| -|db_connect|boolean|false|none|是否连接了数据库| - -

CacheLabelInfo

- - - -```json -{ - "l": "beta", - "cls": [ - "ios", - "android", - "web" - ], - "chs": [ - "stable", - "beta", - "dev" - ] -} - -``` - -### Properties - -|Name|Type|Required|Restrictions|Description| -|---|---|---|---|---| -|l|string|false|none|灰度标签名称| -|cls|[string]|false|none|灰度标签适用的 Clients 客户端类型列表,当列表为空时表示全适用| -|chs|[string]|false|none|灰度标签适用的 Channels 版本通道列表,当列表为空时表示全适用| - -

LabelsInfoRes

- - - -```json -{ - "totalSize": 99, - "nextPageToken": "", - "result": [ - { - "hid": "AwAAAAAAAAB25V_QnbhCuRwF", - "product": "teambition", - "name": "beta", - "desc": "string", - "channels": [ - "beta" - ], - "clients": [ - "web" - ], - "status": 0, - "created_at": "2020-03-25T11:44:34.002Z", - "updated_at": "2020-03-25T11:44:34.002Z", - "offline_at": null - } - ] -} - -``` - -### Properties - -|Name|Type|Required|Restrictions|Description| -|---|---|---|---|---| -|totalSize|[TotalSize](#schematotalsize)|false|none|当前分页查询的总数据量| -|nextPageToken|[NextPageToken](#schemanextpagetoken)|false|none|用于分页查询时用于获取下一页数据的 token,当为空值时表示没有下一页了| -|result|[[LabelInfo](#schemalabelinfo)]|false|none|none| - -

LabelInfo

- - - -```json -{ - "hid": "AwAAAAAAAAB25V_QnbhCuRwF", - "product": "teambition", - "name": "beta", - "desc": "string", - "channels": [ - "beta" - ], - "clients": [ - "web" - ], - "status": 0, - "created_at": "2020-03-25T11:44:34.002Z", - "updated_at": "2020-03-25T11:44:34.002Z", - "offline_at": null -} - -``` - -### Properties - -|Name|Type|Required|Restrictions|Description| -|---|---|---|---|---| -|hid|string|false|none|灰度标签的 HID| -|product|string|false|none|灰度标签所属的产品名称| -|name|string|false|none|灰度标签名称,同一产品下唯一(不能重名)| -|desc|string|false|none|灰度标签描述| -|channels|[string]|false|none|灰度标签适用版本通道| -|clients|[string]|false|none|灰度标签适用客户端类型| -|status|integer(int64)|false|none|灰度标签状态(暂未支持)| -|created_at|string(date-time)|false|none|灰度标签创建时间| -|updated_at|string(date-time)|false|none|灰度标签更新时间| -|offline_at|string(date-time)|false|none|灰度标签下线时间| - diff --git a/doc/openapi.md b/doc/openapi.md new file mode 100644 index 0000000..2eabd7b --- /dev/null +++ b/doc/openapi.md @@ -0,0 +1,2247 @@ +--- +title: urbs-setting +language_tabs: + - shell: Shell + - http: HTTP +toc_footers: [] +includes: [] +search: true +highlight_theme: darkula +headingLevel: 2 + +--- + +

urbs-setting v1.2.0

+ +> Scroll down for code samples, example requests and responses. Select a language for code samples from the tabs above or the mobile navigation menu. + +Urbs 灰度平台灰度策略服务 + +Base URLs: + +* https://urbs-setting:8443 + +# Authentication + +- HTTP Authentication, scheme: bearer + +

Version

+ +获取 urbs-setting 服务版本信息 + +## 获取版本信息 + +> Code samples + +```shell +# You can also use wget +curl -X GET https://urbs-setting:8443/version \ + -H 'Accept: application/json' + +``` + +```http +GET https://urbs-setting:8443/version HTTP/1.1 +Host: urbs-setting:8443 +Accept: application/json + +``` + +`GET /version` + +> Example responses + +> 200 Response + +```json +{ + "name": "urbs-setting", + "version": "v1.2.0", + "gitSHA1": "cd7e82a", + "buildTime": "2020-04-01T09:49:45.217Z" +} +``` + +

Responses

+ +|Status|Meaning|Description|Schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|version 返回结果|[Version](#schemaversion)| + + + +## 服务健康检查接口 + +> Code samples + +```shell +# You can also use wget +curl -X GET https://urbs-setting:8443/healthz \ + -H 'Accept: application/json' + +``` + +```http +GET https://urbs-setting:8443/healthz HTTP/1.1 +Host: urbs-setting:8443 +Accept: application/json + +``` + +`GET /healthz` + +> Example responses + +> 200 Response + +```json +{ + "db_connect": true +} +``` + +

Responses

+ +|Status|Meaning|Description|Schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|Healthz 返回结果|Inline| + +

Response Schema

+ +Status Code **200** + +|Name|Type|Required|Restrictions|Description| +|---|---|---|---|---| +|» db_connect|boolean|false|none|是否连接了数据库| + + + +

User

+ +User 用户相关接口 + +## 该接口为灰度网关提供用户的灰度信息,用于服务端灰度。获取指定 uid 用户在指定 product 产品下的所有(未分页,最多 400 条)灰度标签,包括从 group 群组继承的灰度标签,按照 label 指派时间反序。网关只会取匹配 client 和 channel 的第一条。标签列表不是实时数据,会被服务缓存,缓存时间在 config.cache_label_expire 配置,默认为 1 分钟,建议生产配置为 5 分钟。当 uid 对应用户不存在或 product 对应产品不存在时,该接口会返回空灰度标签列表 + +> Code samples + +```shell +# You can also use wget +curl -X GET https://urbs-setting:8443/users/{uid}/labels:cache?product=string \ + -H 'Accept: application/json' + +``` + +```http +GET https://urbs-setting:8443/users/{uid}/labels:cache?product=string HTTP/1.1 +Host: urbs-setting:8443 +Accept: application/json + +``` + +`GET /users/{uid}/labels:cache` + +

Parameters

+ +|Name|In|Type|Required|Description| +|---|---|---|---|---| +|uid|path|string|true|用户/群组 uid| +|product|query|string|true|产品名称| + +> Example responses + +> 200 Response + +```json +{ + "timestamp": 1585129360, + "result": [ + { + "l": "beta", + "cls": [ + "ios", + "android", + "web" + ], + "chs": [ + "stable", + "beta", + "dev" + ] + } + ] +} +``` + +

Responses

+ +|Status|Meaning|Description|Schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|用于网关的用户灰度标签列表返回结果|Inline| + +

Response Schema

+ +Status Code **200** + +|Name|Type|Required|Restrictions|Description| +|---|---|---|---|---| +|» timestamp|integer(int64)|false|none|灰度标签列表缓存生成时间,1970 以来的秒数| +|» result|[[CacheLabelInfo](#schemacachelabelinfo)]|false|none|灰度标签列表| +|»» l|string|false|none|灰度标签名称| +|»» cls|[string]|false|none|灰度标签适用的 Clients 客户端类型列表,当列表为空时表示全适用| +|»» chs|[string]|false|none|灰度标签适用的 Channels 版本通道列表,当列表为空时表示全适用| + + + +## 该接口为客户端提供用户的产品功能模块配置项信息,用于客户端功能灰度。获取指定 uid 用户在指定 product 产品下的功能模块配置项信息列表,包括从 group 群组继承的配置项信息列表,按照 setting 值更新时间 updated_at 反序。该 API 支持分页,默认获取最新更新的前 10 条,分页参数 nextPageToken 为更新时间 updated_at 值(进行了 encodeURI 转义)。如果客户端本地缓存了 setting 列表,可以判断 nextPageToken 的值,如果 **为空** 或者其值小于本地缓存的最大 updated_at 值,就不用读取下一页了。该 API 还支持 channel 和 client 参数,让客户端只读取匹配 client 和 channel 的 setting 列表。当 uid 对应用户不存在时,该接口会返回空配置项列表 + +> Code samples + +```shell +# You can also use wget +curl -X GET https://urbs-setting:8443/v1/users/{uid}/settings:unionAll?product=string \ + -H 'Accept: application/json' \ + -H 'Authorization: string' + +``` + +```http +GET https://urbs-setting:8443/v1/users/{uid}/settings:unionAll?product=string HTTP/1.1 +Host: urbs-setting:8443 +Accept: application/json +Authorization: string + +``` + +`GET /v1/users/{uid}/settings:unionAll` + +

Parameters

+ +|Name|In|Type|Required|Description| +|---|---|---|---|---| +|Authorization|header|string|true|请求 JWT token, 格式如: `Bearer xxx`| +|uid|path|string|true|用户/群组 uid| +|product|query|string|true|产品名称| +|channel|query|string|false|版本通道,必须为服务端配置的有效值,只返回匹配 channel 的 setting 列表| +|client|query|string|false|客户端类型,必须为服务端配置的有效值,只返回匹配 client 的 setting 列表| +|pageSize|query|integer(int32)|false|分页大小,默认为 10,(1-1000]| +|pageToken|query|string|false|分页请求标记,来自于响应结果的 nextPageToken| + +> Example responses + +> 200 Response + +```json +{ + "nextPageToken": "", + "result": [ + { + "hid": "AwAAAAAAAAB25V_QnbhCuRwF", + "module": "task", + "name": "task-share", + "value": "disable", + "last_value": "", + "created_at": "2020-04-01T09:49:45.223Z", + "updated_at": "2020-04-01T09:49:45.223Z" + } + ] +} +``` + +

Responses

+ +|Status|Meaning|Description|Schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|用户或群组被指派的配置项列表返回结果|Inline| +|401|[Unauthorized](https://tools.ietf.org/html/rfc7235#section-3.1)|标准错误返回结果|Inline| +|404|[Not Found](https://tools.ietf.org/html/rfc7231#section-6.5.4)|标准错误返回结果|Inline| + +

Response Schema

+ +Status Code **200** + +|Name|Type|Required|Restrictions|Description| +|---|---|---|---|---| +|» nextPageToken|[NextPageToken](#schemanextpagetoken)|false|none|用于分页查询时用于获取下一页数据的 token,当为空值时表示没有下一页了| +|» result|[[MySetting](#schemamysetting)]|false|none|none| +|»» hid|string|false|none|配置项的 hid| +|»» module|string|false|none|配置项所属的功能模块名称| +|»» name|string|false|none|配置项名称,同一产品功能模块下唯一(不能重名)| +|»» value|string|false|none|配置项值| +|»» last_value|string|false|none|配置项值| +|»» created_at|string(date-time)|false|none|灰度标签创建时间| +|»» updated_at|string(date-time)|false|none|灰度标签更新时间| + +Status Code **401** + +|Name|Type|Required|Restrictions|Description| +|---|---|---|---|---| +|» error|string|false|none|错误代号| +|» message|string|false|none|错误详情| + +Status Code **404** + +|Name|Type|Required|Restrictions|Description| +|---|---|---|---|---| +|» error|string|false|none|错误代号| +|» message|string|false|none|错误详情| + + + +## 获取指定 uid 用户灰度标签列表,不包括从群组继承的灰度标签,支持分页,按照标签指派时间正序。考虑到灰度标签不会很多,暂未支持根据 product 过滤 + +> Code samples + +```shell +# You can also use wget +curl -X GET https://urbs-setting:8443/v1/users/{uid}/labels \ + -H 'Accept: application/json' \ + -H 'Authorization: string' + +``` + +```http +GET https://urbs-setting:8443/v1/users/{uid}/labels HTTP/1.1 +Host: urbs-setting:8443 +Accept: application/json +Authorization: string + +``` + +`GET /v1/users/{uid}/labels` + +

Parameters

+ +|Name|In|Type|Required|Description| +|---|---|---|---|---| +|Authorization|header|string|true|请求 JWT token, 格式如: `Bearer xxx`| +|uid|path|string|true|用户/群组 uid| +|pageSize|query|integer(int32)|false|分页大小,默认为 10,(1-1000]| +|pageToken|query|string|false|分页请求标记,来自于响应结果的 nextPageToken| + +> Example responses + +> 200 Response + +```json +{ + "totalSize": 1, + "nextPageToken": "", + "result": [ + { + "hid": "AwAAAAAAAAB25V_QnbhCuRwF", + "product": "teambition", + "name": "beta", + "desc": "string", + "channels": [ + "beta" + ], + "clients": [ + "web" + ], + "status": 0, + "created_at": "2020-04-01T09:49:45.223Z", + "updated_at": "2020-04-01T09:49:45.223Z", + "offline_at": null + } + ] +} +``` + +

Responses

+ +|Status|Meaning|Description|Schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|用户或群组被指派的标签列表返回结果|Inline| +|401|[Unauthorized](https://tools.ietf.org/html/rfc7235#section-3.1)|标准错误返回结果|Inline| +|404|[Not Found](https://tools.ietf.org/html/rfc7231#section-6.5.4)|标准错误返回结果|Inline| + +

Response Schema

+ +Status Code **200** + +|Name|Type|Required|Restrictions|Description| +|---|---|---|---|---| +|» totalSize|[TotalSize](#schematotalsize)(int64)|false|none|当前分页查询的总数据量| +|» nextPageToken|[NextPageToken](#schemanextpagetoken)|false|none|用于分页查询时用于获取下一页数据的 token,当为空值时表示没有下一页了| +|» result|[[LabelInfo](#schemalabelinfo)]|false|none|none| +|»» hid|string|false|none|灰度标签的 hid| +|»» product|string|false|none|灰度标签所属的产品名称| +|»» name|string|false|none|灰度标签名称,同一产品下唯一(不能重名)| +|»» desc|string|false|none|灰度标签描述| +|»» channels|[string]|false|none|灰度标签适用版本通道| +|»» clients|[string]|false|none|灰度标签适用客户端类型| +|»» status|integer(int64)|false|none|灰度标签状态(暂未支持)| +|»» created_at|string(date-time)|false|none|灰度标签创建时间| +|»» updated_at|string(date-time)|false|none|灰度标签更新时间| +|»» offline_at|string(date-time)|false|none|灰度标签下线时间| + +Status Code **401** + +|Name|Type|Required|Restrictions|Description| +|---|---|---|---|---| +|» error|string|false|none|错误代号| +|» message|string|false|none|错误详情| + +Status Code **404** + +|Name|Type|Required|Restrictions|Description| +|---|---|---|---|---| +|» error|string|false|none|错误代号| +|» message|string|false|none|错误详情| + + + +## 强制刷新指定用户的灰度标签列表缓存 + +> Code samples + +```shell +# You can also use wget +curl -X PUT https://urbs-setting:8443/v1/users/{uid}/labels:cache \ + -H 'Accept: application/json' \ + -H 'Authorization: string' + +``` + +```http +PUT https://urbs-setting:8443/v1/users/{uid}/labels:cache HTTP/1.1 +Host: urbs-setting:8443 +Accept: application/json +Authorization: string + +``` + +`PUT /v1/users/{uid}/labels:cache` + +

Parameters

+ +|Name|In|Type|Required|Description| +|---|---|---|---|---| +|Authorization|header|string|true|请求 JWT token, 格式如: `Bearer xxx`| +|uid|path|string|true|用户/群组 uid| + +> Example responses + +> 200 Response + +```json +{ + "result": true +} +``` + +

Responses

+ +|Status|Meaning|Description|Schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|标准 Boolean 类返回结果|Inline| +|401|[Unauthorized](https://tools.ietf.org/html/rfc7235#section-3.1)|标准错误返回结果|Inline| +|404|[Not Found](https://tools.ietf.org/html/rfc7231#section-6.5.4)|标准错误返回结果|Inline| + +

Response Schema

+ +Status Code **200** + +|Name|Type|Required|Restrictions|Description| +|---|---|---|---|---| +|» result|boolean|false|none|是否成功| + +Status Code **401** + +|Name|Type|Required|Restrictions|Description| +|---|---|---|---|---| +|» error|string|false|none|错误代号| +|» message|string|false|none|错误详情| + +Status Code **404** + +|Name|Type|Required|Restrictions|Description| +|---|---|---|---|---| +|» error|string|false|none|错误代号| +|» message|string|false|none|错误详情| + + + +## 获取指定 uid 用户在指定产品线下的功能模块配置项列表,不包括从群组继承的配置项,支持分页,按照配置项指派时间正序 + +> Code samples + +```shell +# You can also use wget +curl -X GET https://urbs-setting:8443/v1/users/{uid}/settings \ + -H 'Accept: application/json' \ + -H 'Authorization: string' + +``` + +```http +GET https://urbs-setting:8443/v1/users/{uid}/settings HTTP/1.1 +Host: urbs-setting:8443 +Accept: application/json +Authorization: string + +``` + +`GET /v1/users/{uid}/settings` + +

Parameters

+ +|Name|In|Type|Required|Description| +|---|---|---|---|---| +|Authorization|header|string|true|请求 JWT token, 格式如: `Bearer xxx`| +|uid|path|string|true|用户/群组 uid| +|pageSize|query|integer(int32)|false|分页大小,默认为 10,(1-1000]| +|pageToken|query|string|false|分页请求标记,来自于响应结果的 nextPageToken| + +> Example responses + +> 200 Response + +```json +{ + "nextPageToken": "", + "result": [ + { + "hid": "AwAAAAAAAAB25V_QnbhCuRwF", + "module": "task", + "name": "task-share", + "value": "disable", + "last_value": "", + "created_at": "2020-04-01T09:49:45.224Z", + "updated_at": "2020-04-01T09:49:45.224Z" + } + ] +} +``` + +

Responses

+ +|Status|Meaning|Description|Schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|用户或群组被指派的配置项列表返回结果|Inline| +|401|[Unauthorized](https://tools.ietf.org/html/rfc7235#section-3.1)|标准错误返回结果|Inline| +|404|[Not Found](https://tools.ietf.org/html/rfc7231#section-6.5.4)|标准错误返回结果|Inline| + +

Response Schema

+ +Status Code **200** + +|Name|Type|Required|Restrictions|Description| +|---|---|---|---|---| +|» nextPageToken|[NextPageToken](#schemanextpagetoken)|false|none|用于分页查询时用于获取下一页数据的 token,当为空值时表示没有下一页了| +|» result|[[MySetting](#schemamysetting)]|false|none|none| +|»» hid|string|false|none|配置项的 hid| +|»» module|string|false|none|配置项所属的功能模块名称| +|»» name|string|false|none|配置项名称,同一产品功能模块下唯一(不能重名)| +|»» value|string|false|none|配置项值| +|»» last_value|string|false|none|配置项值| +|»» created_at|string(date-time)|false|none|灰度标签创建时间| +|»» updated_at|string(date-time)|false|none|灰度标签更新时间| + +Status Code **401** + +|Name|Type|Required|Restrictions|Description| +|---|---|---|---|---| +|» error|string|false|none|错误代号| +|» message|string|false|none|错误详情| + +Status Code **404** + +|Name|Type|Required|Restrictions|Description| +|---|---|---|---|---| +|» error|string|false|none|错误代号| +|» message|string|false|none|错误详情| + + + +## 判断指定 uid 用户是否存在 + +> Code samples + +```shell +# You can also use wget +curl -X GET https://urbs-setting:8443/v1/users/{uid}/exists \ + -H 'Accept: application/json' \ + -H 'Authorization: string' + +``` + +```http +GET https://urbs-setting:8443/v1/users/{uid}/exists HTTP/1.1 +Host: urbs-setting:8443 +Accept: application/json +Authorization: string + +``` + +`GET /v1/users/{uid}/exists` + +

Parameters

+ +|Name|In|Type|Required|Description| +|---|---|---|---|---| +|Authorization|header|string|true|请求 JWT token, 格式如: `Bearer xxx`| +|uid|path|string|true|用户/群组 uid| + +> Example responses + +> 200 Response + +```json +{ + "result": true +} +``` + +

Responses

+ +|Status|Meaning|Description|Schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|标准 Boolean 类返回结果|Inline| +|401|[Unauthorized](https://tools.ietf.org/html/rfc7235#section-3.1)|标准错误返回结果|Inline| + +

Response Schema

+ +Status Code **200** + +|Name|Type|Required|Restrictions|Description| +|---|---|---|---|---| +|» result|boolean|false|none|是否成功| + +Status Code **401** + +|Name|Type|Required|Restrictions|Description| +|---|---|---|---|---| +|» error|string|false|none|错误代号| +|» message|string|false|none|错误详情| + + + +## 批量添加用户,忽略已存在的用户 + +> Code samples + +```shell +# You can also use wget +curl -X POST https://urbs-setting:8443/v1/users:batch \ + -H 'Content-Type: application/json' \ + -H 'Accept: application/json' \ + -H 'Authorization: string' + +``` + +```http +POST https://urbs-setting:8443/v1/users:batch HTTP/1.1 +Host: urbs-setting:8443 +Content-Type: application/json +Accept: application/json +Authorization: string + +``` + +`POST /v1/users:batch` + +> Body parameter + +```json +{ + "users": [ + "50c32afae8cf1439d35a87e6", + "5e69a9bd6ac3cd00213ea969" + ] +} +``` + +

Parameters

+ +|Name|In|Type|Required|Description| +|---|---|---|---|---| +|Authorization|header|string|true|请求 JWT token, 格式如: `Bearer xxx`| +|body|body|[UsersBody](#schemausersbody)|true|批量添加用户请求数据| +|» users|body|[string]|false|用户 uid 数组| + +> Example responses + +> 200 Response + +```json +{ + "result": true +} +``` + +

Responses

+ +|Status|Meaning|Description|Schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|标准 Boolean 类返回结果|Inline| +|400|[Bad Request](https://tools.ietf.org/html/rfc7231#section-6.5.1)|标准错误返回结果|Inline| +|401|[Unauthorized](https://tools.ietf.org/html/rfc7235#section-3.1)|标准错误返回结果|Inline| + +

Response Schema

+ +Status Code **200** + +|Name|Type|Required|Restrictions|Description| +|---|---|---|---|---| +|» result|boolean|false|none|是否成功| + +Status Code **400** + +|Name|Type|Required|Restrictions|Description| +|---|---|---|---|---| +|» error|string|false|none|错误代号| +|» message|string|false|none|错误详情| + +Status Code **401** + +|Name|Type|Required|Restrictions|Description| +|---|---|---|---|---| +|» error|string|false|none|错误代号| +|» message|string|false|none|错误详情| + + + +## 移除指定 uid 用户的指定 hid 灰度标签 + +> Code samples + +```shell +# You can also use wget +curl -X DELETE https://urbs-setting:8443/v1/users/{uid}/labels/{hid} \ + -H 'Accept: application/json' \ + -H 'Authorization: string' + +``` + +```http +DELETE https://urbs-setting:8443/v1/users/{uid}/labels/{hid} HTTP/1.1 +Host: urbs-setting:8443 +Accept: application/json +Authorization: string + +``` + +`DELETE /v1/users/{uid}/labels/{hid}` + +

Parameters

+ +|Name|In|Type|Required|Description| +|---|---|---|---|---| +|Authorization|header|string|true|请求 JWT token, 格式如: `Bearer xxx`| +|uid|path|string|true|用户/群组 uid| + +> Example responses + +> 200 Response + +```json +{ + "result": true +} +``` + +

Responses

+ +|Status|Meaning|Description|Schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|标准 Boolean 类返回结果|Inline| +|401|[Unauthorized](https://tools.ietf.org/html/rfc7235#section-3.1)|标准错误返回结果|Inline| +|404|[Not Found](https://tools.ietf.org/html/rfc7231#section-6.5.4)|标准错误返回结果|Inline| + +

Response Schema

+ +Status Code **200** + +|Name|Type|Required|Restrictions|Description| +|---|---|---|---|---| +|» result|boolean|false|none|是否成功| + +Status Code **401** + +|Name|Type|Required|Restrictions|Description| +|---|---|---|---|---| +|» error|string|false|none|错误代号| +|» message|string|false|none|错误详情| + +Status Code **404** + +|Name|Type|Required|Restrictions|Description| +|---|---|---|---|---| +|» error|string|false|none|错误代号| +|» message|string|false|none|错误详情| + + + +## 回滚指定 uid 用户的指定 hid 配置项值到上一个,只能回退到上一个值,不能到上上个值 + +> Code samples + +```shell +# You can also use wget +curl -X PUT https://urbs-setting:8443/v1/users/{uid}/settings/{hid}:rollback \ + -H 'Accept: application/json' \ + -H 'Authorization: string' + +``` + +```http +PUT https://urbs-setting:8443/v1/users/{uid}/settings/{hid}:rollback HTTP/1.1 +Host: urbs-setting:8443 +Accept: application/json +Authorization: string + +``` + +`PUT /v1/users/{uid}/settings/{hid}:rollback` + +

Parameters

+ +|Name|In|Type|Required|Description| +|---|---|---|---|---| +|Authorization|header|string|true|请求 JWT token, 格式如: `Bearer xxx`| +|uid|path|string|true|用户/群组 uid| + +> Example responses + +> 200 Response + +```json +{ + "result": true +} +``` + +

Responses

+ +|Status|Meaning|Description|Schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|标准 Boolean 类返回结果|Inline| +|401|[Unauthorized](https://tools.ietf.org/html/rfc7235#section-3.1)|标准错误返回结果|Inline| +|404|[Not Found](https://tools.ietf.org/html/rfc7231#section-6.5.4)|标准错误返回结果|Inline| + +

Response Schema

+ +Status Code **200** + +|Name|Type|Required|Restrictions|Description| +|---|---|---|---|---| +|» result|boolean|false|none|是否成功| + +Status Code **401** + +|Name|Type|Required|Restrictions|Description| +|---|---|---|---|---| +|» error|string|false|none|错误代号| +|» message|string|false|none|错误详情| + +Status Code **404** + +|Name|Type|Required|Restrictions|Description| +|---|---|---|---|---| +|» error|string|false|none|错误代号| +|» message|string|false|none|错误详情| + + + +## 移除指定 uid 用户的指定 hid 配置项 + +> Code samples + +```shell +# You can also use wget +curl -X DELETE https://urbs-setting:8443/v1/users/{uid}/settings/{hid} \ + -H 'Accept: application/json' \ + -H 'Authorization: string' + +``` + +```http +DELETE https://urbs-setting:8443/v1/users/{uid}/settings/{hid} HTTP/1.1 +Host: urbs-setting:8443 +Accept: application/json +Authorization: string + +``` + +`DELETE /v1/users/{uid}/settings/{hid}` + +

Parameters

+ +|Name|In|Type|Required|Description| +|---|---|---|---|---| +|Authorization|header|string|true|请求 JWT token, 格式如: `Bearer xxx`| +|uid|path|string|true|用户/群组 uid| + +> Example responses + +> 200 Response + +```json +{ + "result": true +} +``` + +

Responses

+ +|Status|Meaning|Description|Schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|标准 Boolean 类返回结果|Inline| +|401|[Unauthorized](https://tools.ietf.org/html/rfc7235#section-3.1)|标准错误返回结果|Inline| +|404|[Not Found](https://tools.ietf.org/html/rfc7231#section-6.5.4)|标准错误返回结果|Inline| + +

Response Schema

+ +Status Code **200** + +|Name|Type|Required|Restrictions|Description| +|---|---|---|---|---| +|» result|boolean|false|none|是否成功| + +Status Code **401** + +|Name|Type|Required|Restrictions|Description| +|---|---|---|---|---| +|» error|string|false|none|错误代号| +|» message|string|false|none|错误详情| + +Status Code **404** + +|Name|Type|Required|Restrictions|Description| +|---|---|---|---|---| +|» error|string|false|none|错误代号| +|» message|string|false|none|错误详情| + + + +

Group

+ +Group 群组相关接口 + +## 获取指定 uid 群组灰度标签列表,支持分页,按照标签指派时间正序。考虑到灰度标签不会很多,暂未支持根据 product 过滤 + +> Code samples + +```shell +# You can also use wget +curl -X GET https://urbs-setting:8443/v1/groups/{uid}/labels \ + -H 'Accept: application/json' \ + -H 'Authorization: string' + +``` + +```http +GET https://urbs-setting:8443/v1/groups/{uid}/labels HTTP/1.1 +Host: urbs-setting:8443 +Accept: application/json +Authorization: string + +``` + +`GET /v1/groups/{uid}/labels` + +

Parameters

+ +|Name|In|Type|Required|Description| +|---|---|---|---|---| +|Authorization|header|string|true|请求 JWT token, 格式如: `Bearer xxx`| +|uid|path|string|true|用户/群组 uid| +|pageSize|query|integer(int32)|false|分页大小,默认为 10,(1-1000]| +|pageToken|query|string|false|分页请求标记,来自于响应结果的 nextPageToken| + +> Example responses + +> 200 Response + +```json +{ + "totalSize": 1, + "nextPageToken": "", + "result": [ + { + "hid": "AwAAAAAAAAB25V_QnbhCuRwF", + "product": "teambition", + "name": "beta", + "desc": "string", + "channels": [ + "beta" + ], + "clients": [ + "web" + ], + "status": 0, + "created_at": "2020-04-01T09:49:45.226Z", + "updated_at": "2020-04-01T09:49:45.226Z", + "offline_at": null + } + ] +} +``` + +

Responses

+ +|Status|Meaning|Description|Schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|用户或群组被指派的标签列表返回结果|Inline| +|401|[Unauthorized](https://tools.ietf.org/html/rfc7235#section-3.1)|标准错误返回结果|Inline| +|404|[Not Found](https://tools.ietf.org/html/rfc7231#section-6.5.4)|标准错误返回结果|Inline| + +

Response Schema

+ +Status Code **200** + +|Name|Type|Required|Restrictions|Description| +|---|---|---|---|---| +|» totalSize|[TotalSize](#schematotalsize)(int64)|false|none|当前分页查询的总数据量| +|» nextPageToken|[NextPageToken](#schemanextpagetoken)|false|none|用于分页查询时用于获取下一页数据的 token,当为空值时表示没有下一页了| +|» result|[[LabelInfo](#schemalabelinfo)]|false|none|none| +|»» hid|string|false|none|灰度标签的 hid| +|»» product|string|false|none|灰度标签所属的产品名称| +|»» name|string|false|none|灰度标签名称,同一产品下唯一(不能重名)| +|»» desc|string|false|none|灰度标签描述| +|»» channels|[string]|false|none|灰度标签适用版本通道| +|»» clients|[string]|false|none|灰度标签适用客户端类型| +|»» status|integer(int64)|false|none|灰度标签状态(暂未支持)| +|»» created_at|string(date-time)|false|none|灰度标签创建时间| +|»» updated_at|string(date-time)|false|none|灰度标签更新时间| +|»» offline_at|string(date-time)|false|none|灰度标签下线时间| + +Status Code **401** + +|Name|Type|Required|Restrictions|Description| +|---|---|---|---|---| +|» error|string|false|none|错误代号| +|» message|string|false|none|错误详情| + +Status Code **404** + +|Name|Type|Required|Restrictions|Description| +|---|---|---|---|---| +|» error|string|false|none|错误代号| +|» message|string|false|none|错误详情| + + + +## 获取指定 uid 群组在指定产品线下的功能模块配置项列表,支持分页,按照配置项指派时间正序 + +> Code samples + +```shell +# You can also use wget +curl -X GET https://urbs-setting:8443/v1/groups/{uid}/settings \ + -H 'Accept: application/json' \ + -H 'Authorization: string' + +``` + +```http +GET https://urbs-setting:8443/v1/groups/{uid}/settings HTTP/1.1 +Host: urbs-setting:8443 +Accept: application/json +Authorization: string + +``` + +`GET /v1/groups/{uid}/settings` + +

Parameters

+ +|Name|In|Type|Required|Description| +|---|---|---|---|---| +|Authorization|header|string|true|请求 JWT token, 格式如: `Bearer xxx`| +|uid|path|string|true|用户/群组 uid| +|pageSize|query|integer(int32)|false|分页大小,默认为 10,(1-1000]| +|pageToken|query|string|false|分页请求标记,来自于响应结果的 nextPageToken| + +> Example responses + +> 200 Response + +```json +{ + "nextPageToken": "", + "result": [ + { + "hid": "AwAAAAAAAAB25V_QnbhCuRwF", + "module": "task", + "name": "task-share", + "value": "disable", + "last_value": "", + "created_at": "2020-04-01T09:49:45.227Z", + "updated_at": "2020-04-01T09:49:45.227Z" + } + ] +} +``` + +

Responses

+ +|Status|Meaning|Description|Schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|用户或群组被指派的配置项列表返回结果|Inline| +|401|[Unauthorized](https://tools.ietf.org/html/rfc7235#section-3.1)|标准错误返回结果|Inline| +|404|[Not Found](https://tools.ietf.org/html/rfc7231#section-6.5.4)|标准错误返回结果|Inline| + +

Response Schema

+ +Status Code **200** + +|Name|Type|Required|Restrictions|Description| +|---|---|---|---|---| +|» nextPageToken|[NextPageToken](#schemanextpagetoken)|false|none|用于分页查询时用于获取下一页数据的 token,当为空值时表示没有下一页了| +|» result|[[MySetting](#schemamysetting)]|false|none|none| +|»» hid|string|false|none|配置项的 hid| +|»» module|string|false|none|配置项所属的功能模块名称| +|»» name|string|false|none|配置项名称,同一产品功能模块下唯一(不能重名)| +|»» value|string|false|none|配置项值| +|»» last_value|string|false|none|配置项值| +|»» created_at|string(date-time)|false|none|灰度标签创建时间| +|»» updated_at|string(date-time)|false|none|灰度标签更新时间| + +Status Code **401** + +|Name|Type|Required|Restrictions|Description| +|---|---|---|---|---| +|» error|string|false|none|错误代号| +|» message|string|false|none|错误详情| + +Status Code **404** + +|Name|Type|Required|Restrictions|Description| +|---|---|---|---|---| +|» error|string|false|none|错误代号| +|» message|string|false|none|错误详情| + + + +## 读取群组列表,支持分页,按照创建时间正序。 + +> Code samples + +```shell +# You can also use wget +curl -X GET https://urbs-setting:8443/v1/groups \ + -H 'Accept: application/json' \ + -H 'Authorization: string' + +``` + +```http +GET https://urbs-setting:8443/v1/groups HTTP/1.1 +Host: urbs-setting:8443 +Accept: application/json +Authorization: string + +``` + +`GET /v1/groups` + +

Parameters

+ +|Name|In|Type|Required|Description| +|---|---|---|---|---| +|Authorization|header|string|true|请求 JWT token, 格式如: `Bearer xxx`| +|kind|query|string|false|查询指定 kind 类型的群组,未提供则查询所有类型| +|pageSize|query|integer(int32)|false|分页大小,默认为 10,(1-1000]| +|pageToken|query|string|false|分页请求标记,来自于响应结果的 nextPageToken| + +> Example responses + +> 200 Response + +```json +{ + "totalSize": 1, + "nextPageToken": "", + "result": [ + { + "uid": "5e82d747fe02a50021d339f3", + "user": "organization", + "desc": "string", + "sync_at": 1585636012, + "created_at": "2020-04-01T09:49:45.227Z", + "updated_at": "2020-04-01T09:49:45.227Z" + } + ] +} +``` + +

Responses

+ +|Status|Meaning|Description|Schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|群组列表返回结果|Inline| +|401|[Unauthorized](https://tools.ietf.org/html/rfc7235#section-3.1)|标准错误返回结果|Inline| + +

Response Schema

+ +Status Code **200** + +|Name|Type|Required|Restrictions|Description| +|---|---|---|---|---| +|» totalSize|[TotalSize](#schematotalsize)(int64)|false|none|当前分页查询的总数据量| +|» nextPageToken|[NextPageToken](#schemanextpagetoken)|false|none|用于分页查询时用于获取下一页数据的 token,当为空值时表示没有下一页了| +|» result|[[Group](#schemagroup)]|false|none|none| +|»» uid|string|false|none|群组的 uid| +|»» user|string|false|none|群组类型| +|»» desc|string|false|none|群组的描述| +|»» sync_at|integer(int64)|false|none|群组成员同步时间点,1970 以来的秒数| +|»» created_at|string(date-time)|false|none|灰度标签创建时间| +|»» updated_at|string(date-time)|false|none|灰度标签更新时间| + +Status Code **401** + +|Name|Type|Required|Restrictions|Description| +|---|---|---|---|---| +|» error|string|false|none|错误代号| +|» message|string|false|none|错误详情| + + + +## 判断指定 uid 群组是否存在 + +> Code samples + +```shell +# You can also use wget +curl -X GET https://urbs-setting:8443/v1/groups/{uid}/exists \ + -H 'Accept: application/json' \ + -H 'Authorization: string' + +``` + +```http +GET https://urbs-setting:8443/v1/groups/{uid}/exists HTTP/1.1 +Host: urbs-setting:8443 +Accept: application/json +Authorization: string + +``` + +`GET /v1/groups/{uid}/exists` + +

Parameters

+ +|Name|In|Type|Required|Description| +|---|---|---|---|---| +|Authorization|header|string|true|请求 JWT token, 格式如: `Bearer xxx`| +|uid|path|string|true|用户/群组 uid| + +> Example responses + +> 200 Response + +```json +{ + "result": true +} +``` + +

Responses

+ +|Status|Meaning|Description|Schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|标准 Boolean 类返回结果|Inline| +|401|[Unauthorized](https://tools.ietf.org/html/rfc7235#section-3.1)|标准错误返回结果|Inline| + +

Response Schema

+ +Status Code **200** + +|Name|Type|Required|Restrictions|Description| +|---|---|---|---|---| +|» result|boolean|false|none|是否成功| + +Status Code **401** + +|Name|Type|Required|Restrictions|Description| +|---|---|---|---|---| +|» error|string|false|none|错误代号| +|» message|string|false|none|错误详情| + + + +## 批量添加群组,忽略已存在的群组,群组 uid 必须唯一 + +> Code samples + +```shell +# You can also use wget +curl -X POST https://urbs-setting:8443/v1/groups:batch \ + -H 'Content-Type: application/json' \ + -H 'Accept: application/json' \ + -H 'Authorization: string' + +``` + +```http +POST https://urbs-setting:8443/v1/groups:batch HTTP/1.1 +Host: urbs-setting:8443 +Content-Type: application/json +Accept: application/json +Authorization: string + +``` + +`POST /v1/groups:batch` + +> Body parameter + +```json +{ + "groups": [ + { + "uid": "50c32afae8cf1439d35a87e6", + "kind": "organization" + } + ] +} +``` + +

Parameters

+ +|Name|In|Type|Required|Description| +|---|---|---|---|---| +|Authorization|header|string|true|请求 JWT token, 格式如: `Bearer xxx`| +|body|body|[GroupsBody](#schemagroupsbody)|true|批量添加群组请求数据| +|» groups|body|[object]|false|群组信息数组| +|»» uid|body|string|false|群组 uid| +|»» kind|body|string|false|群组类型| +|»» desc|body|string|false|群组描述| + +> Example responses + +> 200 Response + +```json +{ + "result": true +} +``` + +

Responses

+ +|Status|Meaning|Description|Schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|标准 Boolean 类返回结果|Inline| +|400|[Bad Request](https://tools.ietf.org/html/rfc7231#section-6.5.1)|标准错误返回结果|Inline| +|401|[Unauthorized](https://tools.ietf.org/html/rfc7235#section-3.1)|标准错误返回结果|Inline| + +

Response Schema

+ +Status Code **200** + +|Name|Type|Required|Restrictions|Description| +|---|---|---|---|---| +|» result|boolean|false|none|是否成功| + +Status Code **400** + +|Name|Type|Required|Restrictions|Description| +|---|---|---|---|---| +|» error|string|false|none|错误代号| +|» message|string|false|none|错误详情| + +Status Code **401** + +|Name|Type|Required|Restrictions|Description| +|---|---|---|---|---| +|» error|string|false|none|错误代号| +|» message|string|false|none|错误详情| + + + +## 更新指定 uid 群组 + +> Code samples + +```shell +# You can also use wget +curl -X PUT https://urbs-setting:8443/v1/groups/{uid} \ + -H 'Content-Type: application/json' \ + -H 'Accept: application/json' \ + -H 'Authorization: string' + +``` + +```http +PUT https://urbs-setting:8443/v1/groups/{uid} HTTP/1.1 +Host: urbs-setting:8443 +Content-Type: application/json +Accept: application/json +Authorization: string + +``` + +`PUT /v1/groups/{uid}` + +> Body parameter + +```json +{ + "sync_at": 1585638012 +} +``` + +

Parameters

+ +|Name|In|Type|Required|Description| +|---|---|---|---|---| +|Authorization|header|string|true|请求 JWT token, 格式如: `Bearer xxx`| +|uid|path|string|true|用户/群组 uid| +|body|body|[GroupUpdateBody](#schemagroupupdatebody)|true|更新群组请求数据| +|» sync_at|body|integer(int64)|false|群组成员同步时间点,1970 以来的秒数| +|» desc|body|string|false|群组描述| + +> Example responses + +> 200 Response + +```json +{ + "result": { + "uid": "5e82d747fe02a50021d339f3", + "user": "organization", + "desc": "string", + "sync_at": 1585636012, + "created_at": "2020-04-01T09:49:45.229Z", + "updated_at": "2020-04-01T09:49:45.229Z" + } +} +``` + +

Responses

+ +|Status|Meaning|Description|Schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|单个群组返回结果|Inline| +|401|[Unauthorized](https://tools.ietf.org/html/rfc7235#section-3.1)|标准错误返回结果|Inline| + +

Response Schema

+ +Status Code **200** + +|Name|Type|Required|Restrictions|Description| +|---|---|---|---|---| +|» result|[Group](#schemagroup)|false|none|none| +|»» uid|string|false|none|群组的 uid| +|»» user|string|false|none|群组类型| +|»» desc|string|false|none|群组的描述| +|»» sync_at|integer(int64)|false|none|群组成员同步时间点,1970 以来的秒数| +|»» created_at|string(date-time)|false|none|灰度标签创建时间| +|»» updated_at|string(date-time)|false|none|灰度标签更新时间| + +Status Code **401** + +|Name|Type|Required|Restrictions|Description| +|---|---|---|---|---| +|» error|string|false|none|错误代号| +|» message|string|false|none|错误详情| + + + +## 删除指定 uid 群组 + +> Code samples + +```shell +# You can also use wget +curl -X DELETE https://urbs-setting:8443/v1/groups/{uid} \ + -H 'Accept: application/json' \ + -H 'Authorization: string' + +``` + +```http +DELETE https://urbs-setting:8443/v1/groups/{uid} HTTP/1.1 +Host: urbs-setting:8443 +Accept: application/json +Authorization: string + +``` + +`DELETE /v1/groups/{uid}` + +

Parameters

+ +|Name|In|Type|Required|Description| +|---|---|---|---|---| +|Authorization|header|string|true|请求 JWT token, 格式如: `Bearer xxx`| +|uid|path|string|true|用户/群组 uid| + +> Example responses + +> 200 Response + +```json +{ + "result": true +} +``` + +

Responses

+ +|Status|Meaning|Description|Schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|标准 Boolean 类返回结果|Inline| +|401|[Unauthorized](https://tools.ietf.org/html/rfc7235#section-3.1)|标准错误返回结果|Inline| +|404|[Not Found](https://tools.ietf.org/html/rfc7231#section-6.5.4)|标准错误返回结果|Inline| + +

Response Schema

+ +Status Code **200** + +|Name|Type|Required|Restrictions|Description| +|---|---|---|---|---| +|» result|boolean|false|none|是否成功| + +Status Code **401** + +|Name|Type|Required|Restrictions|Description| +|---|---|---|---|---| +|» error|string|false|none|错误代号| +|» message|string|false|none|错误详情| + +Status Code **404** + +|Name|Type|Required|Restrictions|Description| +|---|---|---|---|---| +|» error|string|false|none|错误代号| +|» message|string|false|none|错误详情| + + + +## 移除指定 uid 群组的指定 hid 灰度标签 + +> Code samples + +```shell +# You can also use wget +curl -X DELETE https://urbs-setting:8443/v1/groups/{uid}/labels/{hid} \ + -H 'Accept: application/json' \ + -H 'Authorization: string' + +``` + +```http +DELETE https://urbs-setting:8443/v1/groups/{uid}/labels/{hid} HTTP/1.1 +Host: urbs-setting:8443 +Accept: application/json +Authorization: string + +``` + +`DELETE /v1/groups/{uid}/labels/{hid}` + +

Parameters

+ +|Name|In|Type|Required|Description| +|---|---|---|---|---| +|Authorization|header|string|true|请求 JWT token, 格式如: `Bearer xxx`| +|uid|path|string|true|用户/群组 uid| + +> Example responses + +> 200 Response + +```json +{ + "result": true +} +``` + +

Responses

+ +|Status|Meaning|Description|Schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|标准 Boolean 类返回结果|Inline| +|401|[Unauthorized](https://tools.ietf.org/html/rfc7235#section-3.1)|标准错误返回结果|Inline| +|404|[Not Found](https://tools.ietf.org/html/rfc7231#section-6.5.4)|标准错误返回结果|Inline| + +

Response Schema

+ +Status Code **200** + +|Name|Type|Required|Restrictions|Description| +|---|---|---|---|---| +|» result|boolean|false|none|是否成功| + +Status Code **401** + +|Name|Type|Required|Restrictions|Description| +|---|---|---|---|---| +|» error|string|false|none|错误代号| +|» message|string|false|none|错误详情| + +Status Code **404** + +|Name|Type|Required|Restrictions|Description| +|---|---|---|---|---| +|» error|string|false|none|错误代号| +|» message|string|false|none|错误详情| + + + +## 回滚指定 uid 群组的指定 hid 配置项值到上一个,只能回退到上一个值,不能到上上个值 + +> Code samples + +```shell +# You can also use wget +curl -X PUT https://urbs-setting:8443/v1/groups/{uid}/settings/{hid}:rollback \ + -H 'Accept: application/json' \ + -H 'Authorization: string' + +``` + +```http +PUT https://urbs-setting:8443/v1/groups/{uid}/settings/{hid}:rollback HTTP/1.1 +Host: urbs-setting:8443 +Accept: application/json +Authorization: string + +``` + +`PUT /v1/groups/{uid}/settings/{hid}:rollback` + +

Parameters

+ +|Name|In|Type|Required|Description| +|---|---|---|---|---| +|Authorization|header|string|true|请求 JWT token, 格式如: `Bearer xxx`| +|uid|path|string|true|用户/群组 uid| + +> Example responses + +> 200 Response + +```json +{ + "result": true +} +``` + +

Responses

+ +|Status|Meaning|Description|Schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|标准 Boolean 类返回结果|Inline| +|401|[Unauthorized](https://tools.ietf.org/html/rfc7235#section-3.1)|标准错误返回结果|Inline| +|404|[Not Found](https://tools.ietf.org/html/rfc7231#section-6.5.4)|标准错误返回结果|Inline| + +

Response Schema

+ +Status Code **200** + +|Name|Type|Required|Restrictions|Description| +|---|---|---|---|---| +|» result|boolean|false|none|是否成功| + +Status Code **401** + +|Name|Type|Required|Restrictions|Description| +|---|---|---|---|---| +|» error|string|false|none|错误代号| +|» message|string|false|none|错误详情| + +Status Code **404** + +|Name|Type|Required|Restrictions|Description| +|---|---|---|---|---| +|» error|string|false|none|错误代号| +|» message|string|false|none|错误详情| + + + +## 移除指定 uid 群组的指定 hid 配置项 + +> Code samples + +```shell +# You can also use wget +curl -X DELETE https://urbs-setting:8443/v1/groups/{uid}/settings/{hid} \ + -H 'Accept: application/json' \ + -H 'Authorization: string' + +``` + +```http +DELETE https://urbs-setting:8443/v1/groups/{uid}/settings/{hid} HTTP/1.1 +Host: urbs-setting:8443 +Accept: application/json +Authorization: string + +``` + +`DELETE /v1/groups/{uid}/settings/{hid}` + +

Parameters

+ +|Name|In|Type|Required|Description| +|---|---|---|---|---| +|Authorization|header|string|true|请求 JWT token, 格式如: `Bearer xxx`| +|uid|path|string|true|用户/群组 uid| + +> Example responses + +> 200 Response + +```json +{ + "result": true +} +``` + +

Responses

+ +|Status|Meaning|Description|Schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|标准 Boolean 类返回结果|Inline| +|401|[Unauthorized](https://tools.ietf.org/html/rfc7235#section-3.1)|标准错误返回结果|Inline| +|404|[Not Found](https://tools.ietf.org/html/rfc7231#section-6.5.4)|标准错误返回结果|Inline| + +

Response Schema

+ +Status Code **200** + +|Name|Type|Required|Restrictions|Description| +|---|---|---|---|---| +|» result|boolean|false|none|是否成功| + +Status Code **401** + +|Name|Type|Required|Restrictions|Description| +|---|---|---|---|---| +|» error|string|false|none|错误代号| +|» message|string|false|none|错误详情| + +Status Code **404** + +|Name|Type|Required|Restrictions|Description| +|---|---|---|---|---| +|» error|string|false|none|错误代号| +|» message|string|false|none|错误详情| + + + +## 批量添加群组成员,如果群组成员已存在,则会更新成员的 sync_at 值为 group 的 sync_at 值 + +> Code samples + +```shell +# You can also use wget +curl -X POST https://urbs-setting:8443/v1/groups/{uid}/members:batch \ + -H 'Content-Type: application/json' \ + -H 'Accept: application/json' \ + -H 'Authorization: string' + +``` + +```http +POST https://urbs-setting:8443/v1/groups/{uid}/members:batch HTTP/1.1 +Host: urbs-setting:8443 +Content-Type: application/json +Accept: application/json +Authorization: string + +``` + +`POST /v1/groups/{uid}/members:batch` + +> Body parameter + +```json +{ + "users": [ + "50c32afae8cf1439d35a87e6", + "5e69a9bd6ac3cd00213ea969" + ] +} +``` + +

Parameters

+ +|Name|In|Type|Required|Description| +|---|---|---|---|---| +|Authorization|header|string|true|请求 JWT token, 格式如: `Bearer xxx`| +|body|body|[UsersBody](#schemausersbody)|true|批量添加用户请求数据| +|» users|body|[string]|false|用户 uid 数组| + +> Example responses + +> 200 Response + +```json +{ + "result": true +} +``` + +

Responses

+ +|Status|Meaning|Description|Schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|标准 Boolean 类返回结果|Inline| +|400|[Bad Request](https://tools.ietf.org/html/rfc7231#section-6.5.1)|标准错误返回结果|Inline| +|401|[Unauthorized](https://tools.ietf.org/html/rfc7235#section-3.1)|标准错误返回结果|Inline| + +

Response Schema

+ +Status Code **200** + +|Name|Type|Required|Restrictions|Description| +|---|---|---|---|---| +|» result|boolean|false|none|是否成功| + +Status Code **400** + +|Name|Type|Required|Restrictions|Description| +|---|---|---|---|---| +|» error|string|false|none|错误代号| +|» message|string|false|none|错误详情| + +Status Code **401** + +|Name|Type|Required|Restrictions|Description| +|---|---|---|---|---| +|» error|string|false|none|错误代号| +|» message|string|false|none|错误详情| + + + +## 获取指定 uid 群组的成员列表,支持分页,按照成员添加时间正序 + +> Code samples + +```shell +# You can also use wget +curl -X GET https://urbs-setting:8443/v1/groups/{uid}/members \ + -H 'Accept: application/json' \ + -H 'Authorization: string' + +``` + +```http +GET https://urbs-setting:8443/v1/groups/{uid}/members HTTP/1.1 +Host: urbs-setting:8443 +Accept: application/json +Authorization: string + +``` + +`GET /v1/groups/{uid}/members` + +

Parameters

+ +|Name|In|Type|Required|Description| +|---|---|---|---|---| +|Authorization|header|string|true|请求 JWT token, 格式如: `Bearer xxx`| +|uid|path|string|true|用户/群组 uid| +|pageSize|query|integer(int32)|false|分页大小,默认为 10,(1-1000]| +|pageToken|query|string|false|分页请求标记,来自于响应结果的 nextPageToken| + +> Example responses + +> 200 Response + +```json +{ + "totalSize": 1, + "nextPageToken": "", + "result": [ + { + "user": "5e82d747fe02a50021d339f3", + "sync_at": 1585636012, + "created_at": "2020-04-01T09:49:45.231Z" + } + ] +} +``` + +

Responses

+ +|Status|Meaning|Description|Schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|群组成员列表返回结果|Inline| +|401|[Unauthorized](https://tools.ietf.org/html/rfc7235#section-3.1)|标准错误返回结果|Inline| +|404|[Not Found](https://tools.ietf.org/html/rfc7231#section-6.5.4)|标准错误返回结果|Inline| + +

Response Schema

+ +Status Code **200** + +|Name|Type|Required|Restrictions|Description| +|---|---|---|---|---| +|» totalSize|[TotalSize](#schematotalsize)(int64)|false|none|当前分页查询的总数据量| +|» nextPageToken|[NextPageToken](#schemanextpagetoken)|false|none|用于分页查询时用于获取下一页数据的 token,当为空值时表示没有下一页了| +|» result|[[GroupMember](#schemagroupmember)]|false|none|none| +|»» user|string|false|none|群组成员的用户 uid| +|»» sync_at|integer(int64)|false|none|该群组成员同步时间,1970 以来的秒数| +|»» created_at|string(date-time)|false|none|该群组成员添加时间| + +Status Code **401** + +|Name|Type|Required|Restrictions|Description| +|---|---|---|---|---| +|» error|string|false|none|错误代号| +|» message|string|false|none|错误详情| + +Status Code **404** + +|Name|Type|Required|Restrictions|Description| +|---|---|---|---|---| +|» error|string|false|none|错误代号| +|» message|string|false|none|错误详情| + + + +## 移除群组指定 user 的成员或批量移除同步时间点小于 sync_lt 的成员 + +> Code samples + +```shell +# You can also use wget +curl -X DELETE https://urbs-setting:8443/v1/groups/{uid}/members \ + -H 'Accept: application/json' \ + -H 'Authorization: string' + +``` + +```http +DELETE https://urbs-setting:8443/v1/groups/{uid}/members HTTP/1.1 +Host: urbs-setting:8443 +Accept: application/json +Authorization: string + +``` + +`DELETE /v1/groups/{uid}/members` + +

Parameters

+ +|Name|In|Type|Required|Description| +|---|---|---|---|---| +|Authorization|header|string|true|请求 JWT token, 格式如: `Bearer xxx`| +|uid|path|string|true|用户/群组 uid| +|user|query|string|false|移除群组指定 user 的成员| +|sync_lt|query|string(date-time)|false|批量移除同步时间点小于 sync_lt 的成员| + +> Example responses + +> 200 Response + +```json +{ + "result": true +} +``` + +

Responses

+ +|Status|Meaning|Description|Schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|标准 Boolean 类返回结果|Inline| +|401|[Unauthorized](https://tools.ietf.org/html/rfc7235#section-3.1)|标准错误返回结果|Inline| +|404|[Not Found](https://tools.ietf.org/html/rfc7231#section-6.5.4)|标准错误返回结果|Inline| + +

Response Schema

+ +Status Code **200** + +|Name|Type|Required|Restrictions|Description| +|---|---|---|---|---| +|» result|boolean|false|none|是否成功| + +Status Code **401** + +|Name|Type|Required|Restrictions|Description| +|---|---|---|---|---| +|» error|string|false|none|错误代号| +|» message|string|false|none|错误详情| + +Status Code **404** + +|Name|Type|Required|Restrictions|Description| +|---|---|---|---|---| +|» error|string|false|none|错误代号| +|» message|string|false|none|错误详情| + + + +# Schemas + +

NextPageToken

+ + + +```json +"" + +``` + +*nextPageToken* + +### Properties + +|Name|Type|Required|Restrictions|Description| +|---|---|---|---|---| +|nextPageToken|string|false|none|用于分页查询时用于获取下一页数据的 token,当为空值时表示没有下一页了| + +

TotalSize

+ + + +```json +1 + +``` + +*totalSize* + +### Properties + +|Name|Type|Required|Restrictions|Description| +|---|---|---|---|---| +|totalSize|integer(int64)|false|none|当前分页查询的总数据量| + +

Version

+ + + +```json +{ + "name": "urbs-setting", + "version": "v1.2.0", + "gitSHA1": "cd7e82a", + "buildTime": "2020-04-01T09:49:45.233Z" +} + +``` + +### Properties + +|Name|Type|Required|Restrictions|Description| +|---|---|---|---|---| +|name|string|false|none|服务名称| +|version|string|false|none|当前版本| +|gitSHA1|string|false|none|git commit hash| +|buildTime|string(date-time)|false|none|打包构建时间| + +

CacheLabelInfo

+ + + +```json +{ + "l": "beta", + "cls": [ + "ios", + "android", + "web" + ], + "chs": [ + "stable", + "beta", + "dev" + ] +} + +``` + +### Properties + +|Name|Type|Required|Restrictions|Description| +|---|---|---|---|---| +|l|string|false|none|灰度标签名称| +|cls|[string]|false|none|灰度标签适用的 Clients 客户端类型列表,当列表为空时表示全适用| +|chs|[string]|false|none|灰度标签适用的 Channels 版本通道列表,当列表为空时表示全适用| + +

LabelInfo

+ + + +```json +{ + "hid": "AwAAAAAAAAB25V_QnbhCuRwF", + "product": "teambition", + "name": "beta", + "desc": "string", + "channels": [ + "beta" + ], + "clients": [ + "web" + ], + "status": 0, + "created_at": "2020-04-01T09:49:45.233Z", + "updated_at": "2020-04-01T09:49:45.233Z", + "offline_at": null +} + +``` + +### Properties + +|Name|Type|Required|Restrictions|Description| +|---|---|---|---|---| +|hid|string|false|none|灰度标签的 hid| +|product|string|false|none|灰度标签所属的产品名称| +|name|string|false|none|灰度标签名称,同一产品下唯一(不能重名)| +|desc|string|false|none|灰度标签描述| +|channels|[string]|false|none|灰度标签适用版本通道| +|clients|[string]|false|none|灰度标签适用客户端类型| +|status|integer(int64)|false|none|灰度标签状态(暂未支持)| +|created_at|string(date-time)|false|none|灰度标签创建时间| +|updated_at|string(date-time)|false|none|灰度标签更新时间| +|offline_at|string(date-time)|false|none|灰度标签下线时间| + +

MySetting

+ + + +```json +{ + "hid": "AwAAAAAAAAB25V_QnbhCuRwF", + "module": "task", + "name": "task-share", + "value": "disable", + "last_value": "", + "created_at": "2020-04-01T09:49:45.233Z", + "updated_at": "2020-04-01T09:49:45.233Z" +} + +``` + +### Properties + +|Name|Type|Required|Restrictions|Description| +|---|---|---|---|---| +|hid|string|false|none|配置项的 hid| +|module|string|false|none|配置项所属的功能模块名称| +|name|string|false|none|配置项名称,同一产品功能模块下唯一(不能重名)| +|value|string|false|none|配置项值| +|last_value|string|false|none|配置项值| +|created_at|string(date-time)|false|none|灰度标签创建时间| +|updated_at|string(date-time)|false|none|灰度标签更新时间| + +

Group

+ + + +```json +{ + "uid": "5e82d747fe02a50021d339f3", + "user": "organization", + "desc": "string", + "sync_at": 1585636012, + "created_at": "2020-04-01T09:49:45.233Z", + "updated_at": "2020-04-01T09:49:45.233Z" +} + +``` + +### Properties + +|Name|Type|Required|Restrictions|Description| +|---|---|---|---|---| +|uid|string|false|none|群组的 uid| +|user|string|false|none|群组类型| +|desc|string|false|none|群组的描述| +|sync_at|integer(int64)|false|none|群组成员同步时间点,1970 以来的秒数| +|created_at|string(date-time)|false|none|灰度标签创建时间| +|updated_at|string(date-time)|false|none|灰度标签更新时间| + +

GroupMember

+ + + +```json +{ + "user": "5e82d747fe02a50021d339f3", + "sync_at": 1585636012, + "created_at": "2020-04-01T09:49:45.234Z" +} + +``` + +### Properties + +|Name|Type|Required|Restrictions|Description| +|---|---|---|---|---| +|user|string|false|none|群组成员的用户 uid| +|sync_at|integer(int64)|false|none|该群组成员同步时间,1970 以来的秒数| +|created_at|string(date-time)|false|none|该群组成员添加时间| + diff --git a/doc/openapi.yaml b/doc/openapi.yaml new file mode 100644 index 0000000..16a607c --- /dev/null +++ b/doc/openapi.yaml @@ -0,0 +1,927 @@ +# Content generated by 'make doc'. DO NOT EDIT. + +openapi: 3.0.0 +info: + description: |- + Urbs 灰度平台灰度策略服务 + version: 1.2.0 + title: urbs-setting +servers: + - url: https://urbs-setting:8443 + description: 这是内部服务,请替换为实际 URL +tags: + - name: Version + description: 获取 urbs-setting 服务版本信息 + - name: User + description: User 用户相关接口 + - name: Group + description: Group 群组相关接口 + - name: Product + description: Product 产品相关接口 + - name: Label + description: Label 灰度标签相关接口 + - name: Module + description: Module 产品模块相关接口 + - name: Setting + description: Setting 产品模块配置项相关接口 +components: + parameters: + HeaderAuthorization: + in: header + name: Authorization + description: '请求 JWT token, 格式如: `Bearer xxx`' + required: true + schema: + type: string + PathUID: + in: path + name: uid + description: 用户/群组 uid + required: true + schema: + type: string + PathHID: + in: path + name: uid + description: 标签/配置项 hid + required: true + schema: + type: string + QueryProduct: + in: query + name: product + description: 产品名称 + required: true + schema: + type: string + QueryPageSize: + in: query + name: pageSize + description: 分页大小,默认为 10,(1-1000] + required: false + schema: + type: integer + format: int32 + default: 10 + example: 20 + QueryPageToken: + in: query + name: pageToken + description: 分页请求标记,来自于响应结果的 nextPageToken + required: false + schema: + title: pageToken + type: string + default: "" + example: "2020-03-13T11%3A59%3A48Z" + securitySchemes: + HeaderAuthorizationJWT: + name: Authorization + type: http + scheme: bearer + bearerFormat: JWT + in: header + + schemas: + NextPageToken: + title: nextPageToken + type: string + description: 用于分页查询时用于获取下一页数据的 token,当为空值时表示没有下一页了 + example: "" + TotalSize: + title: totalSize + type: integer + format: int64 + description: 当前分页查询的总数据量 + example: 1 + Version: + type: object + properties: + name: + type: string + description: 服务名称 + example: urbs-setting + version: + type: string + description: 当前版本 + example: v1.2.0 + gitSHA1: + type: string + description: git commit hash + example: cd7e82a + buildTime: + type: string + format: date-time + description: 打包构建时间 + example: 2020-03-25T06:24:25Z + CacheLabelInfo: + type: object + properties: + l: + type: string + description: 灰度标签名称 + example: beta + cls: + type: array + description: 灰度标签适用的 Clients 客户端类型列表,当列表为空时表示全适用 + example: ["ios", "android", "web"] + items: + type: string + chs: + type: array + description: 灰度标签适用的 Channels 版本通道列表,当列表为空时表示全适用 + example: ["stable", "beta", "dev"] + items: + type: string + LabelInfo: + type: object + properties: + hid: + type: string + description: 灰度标签的 hid + example: AwAAAAAAAAB25V_QnbhCuRwF + product: + type: string + description: 灰度标签所属的产品名称 + example: teambition + name: + type: string + description: 灰度标签名称,同一产品下唯一(不能重名) + example: beta + desc: + type: string + description: 灰度标签描述 + channels: + type: array + description: 灰度标签适用版本通道 + example: ["beta"] + items: + type: string + clients: + type: array + description: 灰度标签适用客户端类型 + example: ["web"] + items: + type: string + status: + type: integer + format: int64 + description: 灰度标签状态(暂未支持) + example: 0 + created_at: + type: string + format: date-time + description: 灰度标签创建时间 + example: 2020-03-25T06:24:25Z + updated_at: + type: string + format: date-time + description: 灰度标签更新时间 + example: 2020-03-25T06:24:25Z + offline_at: + type: string + format: date-time + description: 灰度标签下线时间 + default: null + example: null + MySetting: + type: object + properties: + hid: + type: string + description: 配置项的 hid + example: AwAAAAAAAAB25V_QnbhCuRwF + module: + type: string + description: 配置项所属的功能模块名称 + example: task + name: + type: string + description: 配置项名称,同一产品功能模块下唯一(不能重名) + example: task-share + value: + type: string + description: 配置项值 + example: disable + last_value: + type: string + description: 配置项值 + example: "" + created_at: + type: string + format: date-time + description: 灰度标签创建时间 + example: 2020-03-25T06:24:25Z + updated_at: + type: string + format: date-time + description: 灰度标签更新时间 + example: 2020-03-25T06:24:25Z + Group: + type: object + properties: + uid: + type: string + description: 群组的 uid + example: 5e82d747fe02a50021d339f3 + user: + type: string + description: 群组类型 + example: organization + desc: + type: string + description: 群组的描述 + sync_at: + type: integer + format: int64 + description: 群组成员同步时间点,1970 以来的秒数 + example: 1585636012 + created_at: + type: string + format: date-time + description: 灰度标签创建时间 + example: 2020-03-25T06:24:25Z + updated_at: + type: string + format: date-time + description: 灰度标签更新时间 + example: 2020-03-25T06:24:25Z + GroupMember: + type: object + properties: + user: + type: string + description: 群组成员的用户 uid + example: 5e82d747fe02a50021d339f3 + sync_at: + type: integer + format: int64 + description: 该群组成员同步时间,1970 以来的秒数 + example: 1585636012 + created_at: + type: string + format: date-time + description: 该群组成员添加时间 + example: 2020-03-25T06:24:25Z + + requestBodies: + UsersBody: + required: true + description: 批量添加用户请求数据 + content: + application/json: + schema: + type: object + properties: + users: + type: array + description: 用户 uid 数组 + required: true + example: ["50c32afae8cf1439d35a87e6", "5e69a9bd6ac3cd00213ea969"] + items: + type: string + GroupsBody: + required: true + description: 批量添加群组请求数据 + content: + application/json: + schema: + type: object + properties: + groups: + type: array + description: 群组信息数组 + required: true + example: [{"uid": "50c32afae8cf1439d35a87e6", "kind": "organization"}] + items: + type: object + properties: + uid: + type: string + description: 群组 uid + required: true + kind: + type: string + description: 群组类型 + required: true + desc: + type: string + description: 群组描述 + required: false + GroupUpdateBody: + required: true + description: 更新群组请求数据 + content: + application/json: + schema: + type: object + properties: + sync_at: + type: integer + title: sync_at + format: int64 + description: 群组成员同步时间点,1970 以来的秒数 + desc: + type: string + title: desc + description: 群组描述 + example: {"sync_at": 1585638012} + + responses: + ErrorResponse: + description: 标准错误返回结果 + content: + application/json: + schema: + type: object + properties: + error: + type: string + description: 错误代号 + example: NotFound + message: + type: string + description: 错误详情 + example: some thing not found + BoolRes: + description: 标准 Boolean 类返回结果 + content: + application/json: + schema: + type: object + properties: + result: + type: boolean + description: 是否成功 + example: true + Version: + description: version 返回结果 + content: + application/json: + schema: + $ref: "#/components/schemas/Version" + Healthz: + description: Healthz 返回结果 + content: + application/json: + schema: + type: object + properties: + db_connect: + type: boolean + description: 是否连接了数据库 + example: true + CacheLabelsInfo: + description: 用于网关的用户灰度标签列表返回结果 + content: + application/json: + schema: + type: object + properties: + timestamp: + type: integer + format: int64 + description: 灰度标签列表缓存生成时间,1970 以来的秒数 + example: 1585129360 + result: + type: array + description: 灰度标签列表 + items: + $ref: "#/components/schemas/CacheLabelInfo" + LabelsInfoRes: + description: 用户或群组被指派的标签列表返回结果 + content: + application/json: + schema: + type: object + properties: + totalSize: + $ref: "#/components/schemas/TotalSize" + nextPageToken: + $ref: "#/components/schemas/NextPageToken" + result: + type: array + items: + $ref: "#/components/schemas/LabelInfo" + MySettingsRes: + description: 用户或群组被指派的配置项列表返回结果 + content: + application/json: + schema: + type: object + properties: + nextPageToken: + $ref: "#/components/schemas/NextPageToken" + result: + type: array + items: + $ref: "#/components/schemas/MySetting" + GroupsRes: + description: 群组列表返回结果 + content: + application/json: + schema: + type: object + properties: + totalSize: + $ref: "#/components/schemas/TotalSize" + nextPageToken: + $ref: "#/components/schemas/NextPageToken" + result: + type: array + items: + $ref: "#/components/schemas/Group" + GroupRes: + description: 单个群组返回结果 + content: + application/json: + schema: + type: object + properties: + result: + $ref: "#/components/schemas/Group" + GroupMembersRes: + description: 群组成员列表返回结果 + content: + application/json: + schema: + type: object + properties: + totalSize: + $ref: "#/components/schemas/TotalSize" + nextPageToken: + $ref: "#/components/schemas/NextPageToken" + result: + type: array + items: + $ref: "#/components/schemas/GroupMember" +paths: + /version: + get: + tags: + - Version + summary: 获取版本信息 + responses: + '200': + $ref: '#/components/responses/Version' + + /healthz: + get: + tags: + - Version + summary: 服务健康检查接口 + responses: + '200': + $ref: '#/components/responses/Healthz' # User API + /users/{uid}/labels:cache: + get: + tags: + - User + summary: 该接口为灰度网关提供用户的灰度信息,用于服务端灰度。获取指定 uid 用户在指定 product 产品下的所有(未分页,最多 400 条)灰度标签,包括从 group 群组继承的灰度标签,按照 label 指派时间反序。网关只会取匹配 client 和 channel 的第一条。标签列表不是实时数据,会被服务缓存,缓存时间在 config.cache_label_expire 配置,默认为 1 分钟,建议生产配置为 5 分钟。当 uid 对应用户不存在或 product 对应产品不存在时,该接口会返回空灰度标签列表 + parameters: + - $ref: "#/components/parameters/PathUID" + - $ref: "#/components/parameters/QueryProduct" + responses: + '200': + $ref: "#/components/responses/CacheLabelsInfo" + + /v1/users/{uid}/settings:unionAll: + get: + tags: + - User + summary: 该接口为客户端提供用户的产品功能模块配置项信息,用于客户端功能灰度。获取指定 uid 用户在指定 product 产品下的功能模块配置项信息列表,包括从 group 群组继承的配置项信息列表,按照 setting 值更新时间 updated_at 反序。该 API 支持分页,默认获取最新更新的前 10 条,分页参数 nextPageToken 为更新时间 updated_at 值(进行了 encodeURI 转义)。如果客户端本地缓存了 setting 列表,可以判断 nextPageToken 的值,如果 **为空** 或者其值小于本地缓存的最大 updated_at 值,就不用读取下一页了。该 API 还支持 channel 和 client 参数,让客户端只读取匹配 client 和 channel 的 setting 列表。当 uid 对应用户不存在时,该接口会返回空配置项列表 + security: + - HeaderAuthorizationJWT: {} + parameters: + - $ref: '#/components/parameters/HeaderAuthorization' + - $ref: "#/components/parameters/PathUID" + - $ref: "#/components/parameters/QueryProduct" + - in: query + name: channel + description: 版本通道,必须为服务端配置的有效值,只返回匹配 channel 的 setting 列表 + required: false + schema: + type: string + example: beta + - in: query + name: client + description: 客户端类型,必须为服务端配置的有效值,只返回匹配 client 的 setting 列表 + required: false + schema: + type: string + example: ios + - $ref: "#/components/parameters/QueryPageSize" + - $ref: "#/components/parameters/QueryPageToken" + responses: + '200': + $ref: "#/components/responses/MySettingsRes" + '401': + $ref: '#/components/responses/ErrorResponse' + '404': + $ref: '#/components/responses/ErrorResponse' + + /v1/users/{uid}/labels: + get: + tags: + - User + summary: 获取指定 uid 用户灰度标签列表,不包括从群组继承的灰度标签,支持分页,按照标签指派时间正序。考虑到灰度标签不会很多,暂未支持根据 product 过滤 + security: + - HeaderAuthorizationJWT: {} + parameters: + - $ref: '#/components/parameters/HeaderAuthorization' + - $ref: "#/components/parameters/PathUID" + - $ref: "#/components/parameters/QueryPageSize" + - $ref: "#/components/parameters/QueryPageToken" + responses: + '200': + $ref: '#/components/responses/LabelsInfoRes' + '401': + $ref: '#/components/responses/ErrorResponse' + '404': + $ref: '#/components/responses/ErrorResponse' + + /v1/users/{uid}/labels:cache: + put: + tags: + - User + summary: 强制刷新指定用户的灰度标签列表缓存 + security: + - HeaderAuthorizationJWT: {} + parameters: + - $ref: '#/components/parameters/HeaderAuthorization' + - $ref: "#/components/parameters/PathUID" + responses: + '200': + $ref: '#/components/responses/BoolRes' + '401': + $ref: '#/components/responses/ErrorResponse' + '404': + $ref: '#/components/responses/ErrorResponse' + + /v1/users/{uid}/settings: + get: + tags: + - User + summary: 获取指定 uid 用户在指定产品线下的功能模块配置项列表,不包括从群组继承的配置项,支持分页,按照配置项指派时间正序 + security: + - HeaderAuthorizationJWT: {} + parameters: + - $ref: '#/components/parameters/HeaderAuthorization' + - $ref: "#/components/parameters/PathUID" + - $ref: "#/components/parameters/QueryPageSize" + - $ref: "#/components/parameters/QueryPageToken" + responses: + '200': + $ref: '#/components/responses/MySettingsRes' + '401': + $ref: '#/components/responses/ErrorResponse' + '404': + $ref: '#/components/responses/ErrorResponse' + + /v1/users/{uid}/exists: + get: + tags: + - User + summary: 判断指定 uid 用户是否存在 + security: + - HeaderAuthorizationJWT: {} + parameters: + - $ref: '#/components/parameters/HeaderAuthorization' + - $ref: "#/components/parameters/PathUID" + responses: + '200': + $ref: '#/components/responses/BoolRes' + '401': + $ref: '#/components/responses/ErrorResponse' + + /v1/users:batch: + post: + tags: + - User + summary: 批量添加用户,忽略已存在的用户 + security: + - HeaderAuthorizationJWT: {} + parameters: + - $ref: '#/components/parameters/HeaderAuthorization' + requestBody: + $ref: '#/components/requestBodies/UsersBody' + responses: + '200': + $ref: '#/components/responses/BoolRes' + '401': + $ref: '#/components/responses/ErrorResponse' + '400': + $ref: '#/components/responses/ErrorResponse' + + /v1/users/{uid}/labels/{hid}: + delete: + tags: + - User + summary: 移除指定 uid 用户的指定 hid 灰度标签 + security: + - HeaderAuthorizationJWT: {} + parameters: + - $ref: '#/components/parameters/HeaderAuthorization' + - $ref: "#/components/parameters/PathUID" + - $ref: "#/components/parameters/PathHID" + responses: + '200': + $ref: '#/components/responses/BoolRes' + '401': + $ref: '#/components/responses/ErrorResponse' + '404': + $ref: '#/components/responses/ErrorResponse' + + /v1/users/{uid}/settings/{hid}:rollback: + put: + tags: + - User + summary: 回滚指定 uid 用户的指定 hid 配置项值到上一个,只能回退到上一个值,不能到上上个值 + security: + - HeaderAuthorizationJWT: {} + parameters: + - $ref: '#/components/parameters/HeaderAuthorization' + - $ref: "#/components/parameters/PathUID" + - $ref: "#/components/parameters/PathHID" + responses: + '200': + $ref: '#/components/responses/BoolRes' + '401': + $ref: '#/components/responses/ErrorResponse' + '404': + $ref: '#/components/responses/ErrorResponse' + + /v1/users/{uid}/settings/{hid}: + delete: + tags: + - User + summary: 移除指定 uid 用户的指定 hid 配置项 + security: + - HeaderAuthorizationJWT: {} + parameters: + - $ref: '#/components/parameters/HeaderAuthorization' + - $ref: "#/components/parameters/PathUID" + - $ref: "#/components/parameters/PathHID" + responses: + '200': + $ref: '#/components/responses/BoolRes' + '401': + $ref: '#/components/responses/ErrorResponse' + '404': + $ref: '#/components/responses/ErrorResponse' # Group API + /v1/groups/{uid}/labels: + get: + tags: + - Group + summary: 获取指定 uid 群组灰度标签列表,支持分页,按照标签指派时间正序。考虑到灰度标签不会很多,暂未支持根据 product 过滤 + security: + - HeaderAuthorizationJWT: {} + parameters: + - $ref: '#/components/parameters/HeaderAuthorization' + - $ref: "#/components/parameters/PathUID" + - $ref: "#/components/parameters/QueryPageSize" + - $ref: "#/components/parameters/QueryPageToken" + responses: + '200': + $ref: '#/components/responses/LabelsInfoRes' + '401': + $ref: '#/components/responses/ErrorResponse' + '404': + $ref: '#/components/responses/ErrorResponse' + + /v1/groups/{uid}/settings: + get: + tags: + - Group + summary: 获取指定 uid 群组在指定产品线下的功能模块配置项列表,支持分页,按照配置项指派时间正序 + security: + - HeaderAuthorizationJWT: {} + parameters: + - $ref: '#/components/parameters/HeaderAuthorization' + - $ref: "#/components/parameters/PathUID" + - $ref: "#/components/parameters/QueryPageSize" + - $ref: "#/components/parameters/QueryPageToken" + responses: + '200': + $ref: '#/components/responses/MySettingsRes' + '401': + $ref: '#/components/responses/ErrorResponse' + '404': + $ref: '#/components/responses/ErrorResponse' + + /v1/groups: + get: + tags: + - Group + summary: 读取群组列表,支持分页,按照创建时间正序。 + security: + - HeaderAuthorizationJWT: {} + parameters: + - $ref: '#/components/parameters/HeaderAuthorization' + - in: query + name: kind + description: 查询指定 kind 类型的群组,未提供则查询所有类型 + required: false + schema: + type: string + - $ref: "#/components/parameters/QueryPageSize" + - $ref: "#/components/parameters/QueryPageToken" + responses: + '200': + $ref: '#/components/responses/GroupsRes' + '401': + $ref: '#/components/responses/ErrorResponse' + + /v1/groups/{uid}/exists: + get: + tags: + - Group + summary: 判断指定 uid 群组是否存在 + security: + - HeaderAuthorizationJWT: {} + parameters: + - $ref: '#/components/parameters/HeaderAuthorization' + - $ref: "#/components/parameters/PathUID" + responses: + '200': + $ref: '#/components/responses/BoolRes' + '401': + $ref: '#/components/responses/ErrorResponse' + + /v1/groups:batch: + post: + tags: + - Group + summary: 批量添加群组,忽略已存在的群组,群组 uid 必须唯一 + security: + - HeaderAuthorizationJWT: {} + parameters: + - $ref: '#/components/parameters/HeaderAuthorization' + requestBody: + $ref: '#/components/requestBodies/GroupsBody' + responses: + '200': + $ref: '#/components/responses/BoolRes' + '401': + $ref: '#/components/responses/ErrorResponse' + '400': + $ref: '#/components/responses/ErrorResponse' + + /v1/groups/{uid}: + put: + tags: + - Group + summary: 更新指定 uid 群组 + security: + - HeaderAuthorizationJWT: {} + parameters: + - $ref: '#/components/parameters/HeaderAuthorization' + - $ref: "#/components/parameters/PathUID" + requestBody: + $ref: '#/components/requestBodies/GroupUpdateBody' + responses: + '200': + $ref: '#/components/responses/GroupRes' + '401': + $ref: '#/components/responses/ErrorResponse' + delete: + tags: + - Group + summary: 删除指定 uid 群组 + security: + - HeaderAuthorizationJWT: {} + parameters: + - $ref: '#/components/parameters/HeaderAuthorization' + - $ref: "#/components/parameters/PathUID" + responses: + '200': + $ref: '#/components/responses/BoolRes' + '401': + $ref: '#/components/responses/ErrorResponse' + '404': + $ref: '#/components/responses/ErrorResponse' + + /v1/groups/{uid}/labels/{hid}: + delete: + tags: + - Group + summary: 移除指定 uid 群组的指定 hid 灰度标签 + security: + - HeaderAuthorizationJWT: {} + parameters: + - $ref: '#/components/parameters/HeaderAuthorization' + - $ref: "#/components/parameters/PathUID" + - $ref: "#/components/parameters/PathHID" + responses: + '200': + $ref: '#/components/responses/BoolRes' + '401': + $ref: '#/components/responses/ErrorResponse' + '404': + $ref: '#/components/responses/ErrorResponse' + + /v1/groups/{uid}/settings/{hid}:rollback: + put: + tags: + - Group + summary: 回滚指定 uid 群组的指定 hid 配置项值到上一个,只能回退到上一个值,不能到上上个值 + security: + - HeaderAuthorizationJWT: {} + parameters: + - $ref: '#/components/parameters/HeaderAuthorization' + - $ref: "#/components/parameters/PathUID" + - $ref: "#/components/parameters/PathHID" + responses: + '200': + $ref: '#/components/responses/BoolRes' + '401': + $ref: '#/components/responses/ErrorResponse' + '404': + $ref: '#/components/responses/ErrorResponse' + + /v1/groups/{uid}/settings/{hid}: + delete: + tags: + - Group + summary: 移除指定 uid 群组的指定 hid 配置项 + security: + - HeaderAuthorizationJWT: {} + parameters: + - $ref: '#/components/parameters/HeaderAuthorization' + - $ref: "#/components/parameters/PathUID" + - $ref: "#/components/parameters/PathHID" + responses: + '200': + $ref: '#/components/responses/BoolRes' + '401': + $ref: '#/components/responses/ErrorResponse' + '404': + $ref: '#/components/responses/ErrorResponse' + + /v1/groups/{uid}/members:batch: + post: + tags: + - Group + summary: 批量添加群组成员,如果群组成员已存在,则会更新成员的 sync_at 值为 group 的 sync_at 值 + security: + - HeaderAuthorizationJWT: {} + parameters: + - $ref: '#/components/parameters/HeaderAuthorization' + requestBody: + $ref: '#/components/requestBodies/UsersBody' + responses: + '200': + $ref: '#/components/responses/BoolRes' + '401': + $ref: '#/components/responses/ErrorResponse' + '400': + $ref: '#/components/responses/ErrorResponse' + + /v1/groups/{uid}/members: + get: + tags: + - Group + summary: 获取指定 uid 群组的成员列表,支持分页,按照成员添加时间正序 + security: + - HeaderAuthorizationJWT: {} + parameters: + - $ref: '#/components/parameters/HeaderAuthorization' + - $ref: "#/components/parameters/PathUID" + - $ref: "#/components/parameters/QueryPageSize" + - $ref: "#/components/parameters/QueryPageToken" + responses: + '200': + $ref: '#/components/responses/GroupMembersRes' + '401': + $ref: '#/components/responses/ErrorResponse' + '404': + $ref: '#/components/responses/ErrorResponse' + delete: + tags: + - Group + summary: 移除群组指定 user 的成员或批量移除同步时间点小于 sync_lt 的成员 + security: + - HeaderAuthorizationJWT: {} + parameters: + - $ref: '#/components/parameters/HeaderAuthorization' + - $ref: "#/components/parameters/PathUID" + - in: query + name: user + description: 移除群组指定 user 的成员 + required: false + schema: + type: string + - in: query + name: sync_lt + description: 批量移除同步时间点小于 sync_lt 的成员 + required: false + schema: + type: string + format: date-time + responses: + '200': + $ref: '#/components/responses/BoolRes' + '401': + $ref: '#/components/responses/ErrorResponse' + '404': + $ref: '#/components/responses/ErrorResponse' \ No newline at end of file diff --git a/doc/openapi_header.yaml b/doc/openapi_header.yaml new file mode 100644 index 0000000..96f2397 --- /dev/null +++ b/doc/openapi_header.yaml @@ -0,0 +1,456 @@ +openapi: 3.0.0 +info: + description: |- + Urbs 灰度平台灰度策略服务 + version: 1.2.0 + title: urbs-setting +servers: + - url: https://urbs-setting:8443 + description: 这是内部服务,请替换为实际 URL +tags: + - name: Version + description: 获取 urbs-setting 服务版本信息 + - name: User + description: User 用户相关接口 + - name: Group + description: Group 群组相关接口 + - name: Product + description: Product 产品相关接口 + - name: Label + description: Label 灰度标签相关接口 + - name: Module + description: Module 产品模块相关接口 + - name: Setting + description: Setting 产品模块配置项相关接口 +components: + parameters: + HeaderAuthorization: + in: header + name: Authorization + description: '请求 JWT token, 格式如: `Bearer xxx`' + required: true + schema: + type: string + PathUID: + in: path + name: uid + description: 用户/群组 uid + required: true + schema: + type: string + PathHID: + in: path + name: uid + description: 标签/配置项 hid + required: true + schema: + type: string + QueryProduct: + in: query + name: product + description: 产品名称 + required: true + schema: + type: string + QueryPageSize: + in: query + name: pageSize + description: 分页大小,默认为 10,(1-1000] + required: false + schema: + type: integer + format: int32 + default: 10 + example: 20 + QueryPageToken: + in: query + name: pageToken + description: 分页请求标记,来自于响应结果的 nextPageToken + required: false + schema: + title: pageToken + type: string + default: "" + example: "2020-03-13T11%3A59%3A48Z" + securitySchemes: + HeaderAuthorizationJWT: + name: Authorization + type: http + scheme: bearer + bearerFormat: JWT + in: header + + schemas: + NextPageToken: + title: nextPageToken + type: string + description: 用于分页查询时用于获取下一页数据的 token,当为空值时表示没有下一页了 + example: "" + TotalSize: + title: totalSize + type: integer + format: int64 + description: 当前分页查询的总数据量 + example: 1 + Version: + type: object + properties: + name: + type: string + description: 服务名称 + example: urbs-setting + version: + type: string + description: 当前版本 + example: v1.2.0 + gitSHA1: + type: string + description: git commit hash + example: cd7e82a + buildTime: + type: string + format: date-time + description: 打包构建时间 + example: 2020-03-25T06:24:25Z + CacheLabelInfo: + type: object + properties: + l: + type: string + description: 灰度标签名称 + example: beta + cls: + type: array + description: 灰度标签适用的 Clients 客户端类型列表,当列表为空时表示全适用 + example: ["ios", "android", "web"] + items: + type: string + chs: + type: array + description: 灰度标签适用的 Channels 版本通道列表,当列表为空时表示全适用 + example: ["stable", "beta", "dev"] + items: + type: string + LabelInfo: + type: object + properties: + hid: + type: string + description: 灰度标签的 hid + example: AwAAAAAAAAB25V_QnbhCuRwF + product: + type: string + description: 灰度标签所属的产品名称 + example: teambition + name: + type: string + description: 灰度标签名称,同一产品下唯一(不能重名) + example: beta + desc: + type: string + description: 灰度标签描述 + channels: + type: array + description: 灰度标签适用版本通道 + example: ["beta"] + items: + type: string + clients: + type: array + description: 灰度标签适用客户端类型 + example: ["web"] + items: + type: string + status: + type: integer + format: int64 + description: 灰度标签状态(暂未支持) + example: 0 + created_at: + type: string + format: date-time + description: 灰度标签创建时间 + example: 2020-03-25T06:24:25Z + updated_at: + type: string + format: date-time + description: 灰度标签更新时间 + example: 2020-03-25T06:24:25Z + offline_at: + type: string + format: date-time + description: 灰度标签下线时间 + default: null + example: null + MySetting: + type: object + properties: + hid: + type: string + description: 配置项的 hid + example: AwAAAAAAAAB25V_QnbhCuRwF + module: + type: string + description: 配置项所属的功能模块名称 + example: task + name: + type: string + description: 配置项名称,同一产品功能模块下唯一(不能重名) + example: task-share + value: + type: string + description: 配置项值 + example: disable + last_value: + type: string + description: 配置项值 + example: "" + created_at: + type: string + format: date-time + description: 灰度标签创建时间 + example: 2020-03-25T06:24:25Z + updated_at: + type: string + format: date-time + description: 灰度标签更新时间 + example: 2020-03-25T06:24:25Z + Group: + type: object + properties: + uid: + type: string + description: 群组的 uid + example: 5e82d747fe02a50021d339f3 + user: + type: string + description: 群组类型 + example: organization + desc: + type: string + description: 群组的描述 + sync_at: + type: integer + format: int64 + description: 群组成员同步时间点,1970 以来的秒数 + example: 1585636012 + created_at: + type: string + format: date-time + description: 灰度标签创建时间 + example: 2020-03-25T06:24:25Z + updated_at: + type: string + format: date-time + description: 灰度标签更新时间 + example: 2020-03-25T06:24:25Z + GroupMember: + type: object + properties: + user: + type: string + description: 群组成员的用户 uid + example: 5e82d747fe02a50021d339f3 + sync_at: + type: integer + format: int64 + description: 该群组成员同步时间,1970 以来的秒数 + example: 1585636012 + created_at: + type: string + format: date-time + description: 该群组成员添加时间 + example: 2020-03-25T06:24:25Z + + requestBodies: + UsersBody: + required: true + description: 批量添加用户请求数据 + content: + application/json: + schema: + type: object + properties: + users: + type: array + description: 用户 uid 数组 + required: true + example: ["50c32afae8cf1439d35a87e6", "5e69a9bd6ac3cd00213ea969"] + items: + type: string + GroupsBody: + required: true + description: 批量添加群组请求数据 + content: + application/json: + schema: + type: object + properties: + groups: + type: array + description: 群组信息数组 + required: true + example: [{"uid": "50c32afae8cf1439d35a87e6", "kind": "organization"}] + items: + type: object + properties: + uid: + type: string + description: 群组 uid + required: true + kind: + type: string + description: 群组类型 + required: true + desc: + type: string + description: 群组描述 + required: false + GroupUpdateBody: + required: true + description: 更新群组请求数据 + content: + application/json: + schema: + type: object + properties: + sync_at: + type: integer + title: sync_at + format: int64 + description: 群组成员同步时间点,1970 以来的秒数 + desc: + type: string + title: desc + description: 群组描述 + example: {"sync_at": 1585638012} + + responses: + ErrorResponse: + description: 标准错误返回结果 + content: + application/json: + schema: + type: object + properties: + error: + type: string + description: 错误代号 + example: NotFound + message: + type: string + description: 错误详情 + example: some thing not found + BoolRes: + description: 标准 Boolean 类返回结果 + content: + application/json: + schema: + type: object + properties: + result: + type: boolean + description: 是否成功 + example: true + Version: + description: version 返回结果 + content: + application/json: + schema: + $ref: "#/components/schemas/Version" + Healthz: + description: Healthz 返回结果 + content: + application/json: + schema: + type: object + properties: + db_connect: + type: boolean + description: 是否连接了数据库 + example: true + CacheLabelsInfo: + description: 用于网关的用户灰度标签列表返回结果 + content: + application/json: + schema: + type: object + properties: + timestamp: + type: integer + format: int64 + description: 灰度标签列表缓存生成时间,1970 以来的秒数 + example: 1585129360 + result: + type: array + description: 灰度标签列表 + items: + $ref: "#/components/schemas/CacheLabelInfo" + LabelsInfoRes: + description: 用户或群组被指派的标签列表返回结果 + content: + application/json: + schema: + type: object + properties: + totalSize: + $ref: "#/components/schemas/TotalSize" + nextPageToken: + $ref: "#/components/schemas/NextPageToken" + result: + type: array + items: + $ref: "#/components/schemas/LabelInfo" + MySettingsRes: + description: 用户或群组被指派的配置项列表返回结果 + content: + application/json: + schema: + type: object + properties: + nextPageToken: + $ref: "#/components/schemas/NextPageToken" + result: + type: array + items: + $ref: "#/components/schemas/MySetting" + GroupsRes: + description: 群组列表返回结果 + content: + application/json: + schema: + type: object + properties: + totalSize: + $ref: "#/components/schemas/TotalSize" + nextPageToken: + $ref: "#/components/schemas/NextPageToken" + result: + type: array + items: + $ref: "#/components/schemas/Group" + GroupRes: + description: 单个群组返回结果 + content: + application/json: + schema: + type: object + properties: + result: + $ref: "#/components/schemas/Group" + GroupMembersRes: + description: 群组成员列表返回结果 + content: + application/json: + schema: + type: object + properties: + totalSize: + $ref: "#/components/schemas/TotalSize" + nextPageToken: + $ref: "#/components/schemas/NextPageToken" + result: + type: array + items: + $ref: "#/components/schemas/GroupMember" +paths: diff --git a/doc/paths_group.yaml b/doc/paths_group.yaml new file mode 100644 index 0000000..79a36ee --- /dev/null +++ b/doc/paths_group.yaml @@ -0,0 +1,257 @@ + # Group API + /v1/groups/{uid}/labels: + get: + tags: + - Group + summary: 获取指定 uid 群组灰度标签列表,支持分页,按照标签指派时间正序。考虑到灰度标签不会很多,暂未支持根据 product 过滤 + security: + - HeaderAuthorizationJWT: {} + parameters: + - $ref: '#/components/parameters/HeaderAuthorization' + - $ref: "#/components/parameters/PathUID" + - $ref: "#/components/parameters/QueryPageSize" + - $ref: "#/components/parameters/QueryPageToken" + responses: + '200': + $ref: '#/components/responses/LabelsInfoRes' + '401': + $ref: '#/components/responses/ErrorResponse' + '404': + $ref: '#/components/responses/ErrorResponse' + + /v1/groups/{uid}/settings: + get: + tags: + - Group + summary: 获取指定 uid 群组在指定产品线下的功能模块配置项列表,支持分页,按照配置项指派时间正序 + security: + - HeaderAuthorizationJWT: {} + parameters: + - $ref: '#/components/parameters/HeaderAuthorization' + - $ref: "#/components/parameters/PathUID" + - $ref: "#/components/parameters/QueryPageSize" + - $ref: "#/components/parameters/QueryPageToken" + responses: + '200': + $ref: '#/components/responses/MySettingsRes' + '401': + $ref: '#/components/responses/ErrorResponse' + '404': + $ref: '#/components/responses/ErrorResponse' + + /v1/groups: + get: + tags: + - Group + summary: 读取群组列表,支持分页,按照创建时间正序。 + security: + - HeaderAuthorizationJWT: {} + parameters: + - $ref: '#/components/parameters/HeaderAuthorization' + - in: query + name: kind + description: 查询指定 kind 类型的群组,未提供则查询所有类型 + required: false + schema: + type: string + - $ref: "#/components/parameters/QueryPageSize" + - $ref: "#/components/parameters/QueryPageToken" + responses: + '200': + $ref: '#/components/responses/GroupsRes' + '401': + $ref: '#/components/responses/ErrorResponse' + + /v1/groups/{uid}/exists: + get: + tags: + - Group + summary: 判断指定 uid 群组是否存在 + security: + - HeaderAuthorizationJWT: {} + parameters: + - $ref: '#/components/parameters/HeaderAuthorization' + - $ref: "#/components/parameters/PathUID" + responses: + '200': + $ref: '#/components/responses/BoolRes' + '401': + $ref: '#/components/responses/ErrorResponse' + + /v1/groups:batch: + post: + tags: + - Group + summary: 批量添加群组,忽略已存在的群组,群组 uid 必须唯一 + security: + - HeaderAuthorizationJWT: {} + parameters: + - $ref: '#/components/parameters/HeaderAuthorization' + requestBody: + $ref: '#/components/requestBodies/GroupsBody' + responses: + '200': + $ref: '#/components/responses/BoolRes' + '401': + $ref: '#/components/responses/ErrorResponse' + '400': + $ref: '#/components/responses/ErrorResponse' + + /v1/groups/{uid}: + put: + tags: + - Group + summary: 更新指定 uid 群组 + security: + - HeaderAuthorizationJWT: {} + parameters: + - $ref: '#/components/parameters/HeaderAuthorization' + - $ref: "#/components/parameters/PathUID" + requestBody: + $ref: '#/components/requestBodies/GroupUpdateBody' + responses: + '200': + $ref: '#/components/responses/GroupRes' + '401': + $ref: '#/components/responses/ErrorResponse' + delete: + tags: + - Group + summary: 删除指定 uid 群组 + security: + - HeaderAuthorizationJWT: {} + parameters: + - $ref: '#/components/parameters/HeaderAuthorization' + - $ref: "#/components/parameters/PathUID" + responses: + '200': + $ref: '#/components/responses/BoolRes' + '401': + $ref: '#/components/responses/ErrorResponse' + '404': + $ref: '#/components/responses/ErrorResponse' + + /v1/groups/{uid}/labels/{hid}: + delete: + tags: + - Group + summary: 移除指定 uid 群组的指定 hid 灰度标签 + security: + - HeaderAuthorizationJWT: {} + parameters: + - $ref: '#/components/parameters/HeaderAuthorization' + - $ref: "#/components/parameters/PathUID" + - $ref: "#/components/parameters/PathHID" + responses: + '200': + $ref: '#/components/responses/BoolRes' + '401': + $ref: '#/components/responses/ErrorResponse' + '404': + $ref: '#/components/responses/ErrorResponse' + + /v1/groups/{uid}/settings/{hid}:rollback: + put: + tags: + - Group + summary: 回滚指定 uid 群组的指定 hid 配置项值到上一个,只能回退到上一个值,不能到上上个值 + security: + - HeaderAuthorizationJWT: {} + parameters: + - $ref: '#/components/parameters/HeaderAuthorization' + - $ref: "#/components/parameters/PathUID" + - $ref: "#/components/parameters/PathHID" + responses: + '200': + $ref: '#/components/responses/BoolRes' + '401': + $ref: '#/components/responses/ErrorResponse' + '404': + $ref: '#/components/responses/ErrorResponse' + + /v1/groups/{uid}/settings/{hid}: + delete: + tags: + - Group + summary: 移除指定 uid 群组的指定 hid 配置项 + security: + - HeaderAuthorizationJWT: {} + parameters: + - $ref: '#/components/parameters/HeaderAuthorization' + - $ref: "#/components/parameters/PathUID" + - $ref: "#/components/parameters/PathHID" + responses: + '200': + $ref: '#/components/responses/BoolRes' + '401': + $ref: '#/components/responses/ErrorResponse' + '404': + $ref: '#/components/responses/ErrorResponse' + + /v1/groups/{uid}/members:batch: + post: + tags: + - Group + summary: 批量添加群组成员,如果群组成员已存在,则会更新成员的 sync_at 值为 group 的 sync_at 值 + security: + - HeaderAuthorizationJWT: {} + parameters: + - $ref: '#/components/parameters/HeaderAuthorization' + requestBody: + $ref: '#/components/requestBodies/UsersBody' + responses: + '200': + $ref: '#/components/responses/BoolRes' + '401': + $ref: '#/components/responses/ErrorResponse' + '400': + $ref: '#/components/responses/ErrorResponse' + + /v1/groups/{uid}/members: + get: + tags: + - Group + summary: 获取指定 uid 群组的成员列表,支持分页,按照成员添加时间正序 + security: + - HeaderAuthorizationJWT: {} + parameters: + - $ref: '#/components/parameters/HeaderAuthorization' + - $ref: "#/components/parameters/PathUID" + - $ref: "#/components/parameters/QueryPageSize" + - $ref: "#/components/parameters/QueryPageToken" + responses: + '200': + $ref: '#/components/responses/GroupMembersRes' + '401': + $ref: '#/components/responses/ErrorResponse' + '404': + $ref: '#/components/responses/ErrorResponse' + delete: + tags: + - Group + summary: 移除群组指定 user 的成员或批量移除同步时间点小于 sync_lt 的成员 + security: + - HeaderAuthorizationJWT: {} + parameters: + - $ref: '#/components/parameters/HeaderAuthorization' + - $ref: "#/components/parameters/PathUID" + - in: query + name: user + description: 移除群组指定 user 的成员 + required: false + schema: + type: string + - in: query + name: sync_lt + description: 批量移除同步时间点小于 sync_lt 的成员 + required: false + schema: + type: string + format: date-time + responses: + '200': + $ref: '#/components/responses/BoolRes' + '401': + $ref: '#/components/responses/ErrorResponse' + '404': + $ref: '#/components/responses/ErrorResponse' \ No newline at end of file diff --git a/doc/paths_user.yaml b/doc/paths_user.yaml new file mode 100644 index 0000000..995a77f --- /dev/null +++ b/doc/paths_user.yaml @@ -0,0 +1,197 @@ + # User API + /users/{uid}/labels:cache: + get: + tags: + - User + summary: 该接口为灰度网关提供用户的灰度信息,用于服务端灰度。获取指定 uid 用户在指定 product 产品下的所有(未分页,最多 400 条)灰度标签,包括从 group 群组继承的灰度标签,按照 label 指派时间反序。网关只会取匹配 client 和 channel 的第一条。标签列表不是实时数据,会被服务缓存,缓存时间在 config.cache_label_expire 配置,默认为 1 分钟,建议生产配置为 5 分钟。当 uid 对应用户不存在或 product 对应产品不存在时,该接口会返回空灰度标签列表 + parameters: + - $ref: "#/components/parameters/PathUID" + - $ref: "#/components/parameters/QueryProduct" + responses: + '200': + $ref: "#/components/responses/CacheLabelsInfo" + + /v1/users/{uid}/settings:unionAll: + get: + tags: + - User + summary: 该接口为客户端提供用户的产品功能模块配置项信息,用于客户端功能灰度。获取指定 uid 用户在指定 product 产品下的功能模块配置项信息列表,包括从 group 群组继承的配置项信息列表,按照 setting 值更新时间 updated_at 反序。该 API 支持分页,默认获取最新更新的前 10 条,分页参数 nextPageToken 为更新时间 updated_at 值(进行了 encodeURI 转义)。如果客户端本地缓存了 setting 列表,可以判断 nextPageToken 的值,如果 **为空** 或者其值小于本地缓存的最大 updated_at 值,就不用读取下一页了。该 API 还支持 channel 和 client 参数,让客户端只读取匹配 client 和 channel 的 setting 列表。当 uid 对应用户不存在时,该接口会返回空配置项列表 + security: + - HeaderAuthorizationJWT: {} + parameters: + - $ref: '#/components/parameters/HeaderAuthorization' + - $ref: "#/components/parameters/PathUID" + - $ref: "#/components/parameters/QueryProduct" + - in: query + name: channel + description: 版本通道,必须为服务端配置的有效值,只返回匹配 channel 的 setting 列表 + required: false + schema: + type: string + example: beta + - in: query + name: client + description: 客户端类型,必须为服务端配置的有效值,只返回匹配 client 的 setting 列表 + required: false + schema: + type: string + example: ios + - $ref: "#/components/parameters/QueryPageSize" + - $ref: "#/components/parameters/QueryPageToken" + responses: + '200': + $ref: "#/components/responses/MySettingsRes" + '401': + $ref: '#/components/responses/ErrorResponse' + '404': + $ref: '#/components/responses/ErrorResponse' + + /v1/users/{uid}/labels: + get: + tags: + - User + summary: 获取指定 uid 用户灰度标签列表,不包括从群组继承的灰度标签,支持分页,按照标签指派时间正序。考虑到灰度标签不会很多,暂未支持根据 product 过滤 + security: + - HeaderAuthorizationJWT: {} + parameters: + - $ref: '#/components/parameters/HeaderAuthorization' + - $ref: "#/components/parameters/PathUID" + - $ref: "#/components/parameters/QueryPageSize" + - $ref: "#/components/parameters/QueryPageToken" + responses: + '200': + $ref: '#/components/responses/LabelsInfoRes' + '401': + $ref: '#/components/responses/ErrorResponse' + '404': + $ref: '#/components/responses/ErrorResponse' + + /v1/users/{uid}/labels:cache: + put: + tags: + - User + summary: 强制刷新指定用户的灰度标签列表缓存 + security: + - HeaderAuthorizationJWT: {} + parameters: + - $ref: '#/components/parameters/HeaderAuthorization' + - $ref: "#/components/parameters/PathUID" + responses: + '200': + $ref: '#/components/responses/BoolRes' + '401': + $ref: '#/components/responses/ErrorResponse' + '404': + $ref: '#/components/responses/ErrorResponse' + + /v1/users/{uid}/settings: + get: + tags: + - User + summary: 获取指定 uid 用户在指定产品线下的功能模块配置项列表,不包括从群组继承的配置项,支持分页,按照配置项指派时间正序 + security: + - HeaderAuthorizationJWT: {} + parameters: + - $ref: '#/components/parameters/HeaderAuthorization' + - $ref: "#/components/parameters/PathUID" + - $ref: "#/components/parameters/QueryPageSize" + - $ref: "#/components/parameters/QueryPageToken" + responses: + '200': + $ref: '#/components/responses/MySettingsRes' + '401': + $ref: '#/components/responses/ErrorResponse' + '404': + $ref: '#/components/responses/ErrorResponse' + + /v1/users/{uid}/exists: + get: + tags: + - User + summary: 判断指定 uid 用户是否存在 + security: + - HeaderAuthorizationJWT: {} + parameters: + - $ref: '#/components/parameters/HeaderAuthorization' + - $ref: "#/components/parameters/PathUID" + responses: + '200': + $ref: '#/components/responses/BoolRes' + '401': + $ref: '#/components/responses/ErrorResponse' + + /v1/users:batch: + post: + tags: + - User + summary: 批量添加用户,忽略已存在的用户 + security: + - HeaderAuthorizationJWT: {} + parameters: + - $ref: '#/components/parameters/HeaderAuthorization' + requestBody: + $ref: '#/components/requestBodies/UsersBody' + responses: + '200': + $ref: '#/components/responses/BoolRes' + '401': + $ref: '#/components/responses/ErrorResponse' + '400': + $ref: '#/components/responses/ErrorResponse' + + /v1/users/{uid}/labels/{hid}: + delete: + tags: + - User + summary: 移除指定 uid 用户的指定 hid 灰度标签 + security: + - HeaderAuthorizationJWT: {} + parameters: + - $ref: '#/components/parameters/HeaderAuthorization' + - $ref: "#/components/parameters/PathUID" + - $ref: "#/components/parameters/PathHID" + responses: + '200': + $ref: '#/components/responses/BoolRes' + '401': + $ref: '#/components/responses/ErrorResponse' + '404': + $ref: '#/components/responses/ErrorResponse' + + /v1/users/{uid}/settings/{hid}:rollback: + put: + tags: + - User + summary: 回滚指定 uid 用户的指定 hid 配置项值到上一个,只能回退到上一个值,不能到上上个值 + security: + - HeaderAuthorizationJWT: {} + parameters: + - $ref: '#/components/parameters/HeaderAuthorization' + - $ref: "#/components/parameters/PathUID" + - $ref: "#/components/parameters/PathHID" + responses: + '200': + $ref: '#/components/responses/BoolRes' + '401': + $ref: '#/components/responses/ErrorResponse' + '404': + $ref: '#/components/responses/ErrorResponse' + + /v1/users/{uid}/settings/{hid}: + delete: + tags: + - User + summary: 移除指定 uid 用户的指定 hid 配置项 + security: + - HeaderAuthorizationJWT: {} + parameters: + - $ref: '#/components/parameters/HeaderAuthorization' + - $ref: "#/components/parameters/PathUID" + - $ref: "#/components/parameters/PathHID" + responses: + '200': + $ref: '#/components/responses/BoolRes' + '401': + $ref: '#/components/responses/ErrorResponse' + '404': + $ref: '#/components/responses/ErrorResponse' \ No newline at end of file diff --git a/doc/paths_version.yaml b/doc/paths_version.yaml new file mode 100644 index 0000000..7167855 --- /dev/null +++ b/doc/paths_version.yaml @@ -0,0 +1,17 @@ + /version: + get: + tags: + - Version + summary: 获取版本信息 + responses: + '200': + $ref: '#/components/responses/Version' + + /healthz: + get: + tags: + - Version + summary: 服务健康检查接口 + responses: + '200': + $ref: '#/components/responses/Healthz' \ No newline at end of file diff --git a/doc/swagger.yaml b/doc/swagger.yaml deleted file mode 100644 index 4b5e835..0000000 --- a/doc/swagger.yaml +++ /dev/null @@ -1,387 +0,0 @@ -# Content generated by 'make doc'. DO NOT EDIT. - -openapi: 3.0.0 -info: - description: |- - Urbs 灰度平台灰度策略服务 - version: 1.2.0 - title: urbs-setting -servers: - - url: https://urbs-setting:8443 - description: 这是内部服务,请替换为实际 URL -tags: - - name: Version - description: 获取 urbs-setting 服务版本信息 - - name: User - description: User 用户相关接口 - - name: Group - description: Group 群组相关接口 - - name: Product - description: Product 产品相关接口 - - name: Label - description: Label 灰度标签相关接口 - - name: Module - description: Module 产品模块相关接口 - - name: Setting - description: Setting 产品模块配置项相关接口 -components: - schemas: - NextPageToken: - title: nextPageToken - type: string - description: 用于分页查询时用于获取下一页数据的 token,当为空值时表示没有下一页了 - example: "" - TotalSize: - title: totalSize - type: integer - format: int64 - description: 当前分页查询的总数据量 - example: 99 - ErrorResponse: - type: object - properties: - error: - type: string - description: 错误代号 - example: NotFound - message: - type: string - description: 错误详情 - example: user 50c32afae8cf1439d35a87e6 not found - BoolRes: - type: object - properties: - result: - type: boolean - description: 是否成功 - example: true - Version: - type: object - properties: - name: - type: string - description: 服务名称 - example: urbs-setting - version: - type: string - description: 当前版本 - example: v1.2.0 - gitSHA1: - type: string - description: git commit hash - example: cd7e82a - buildTime: - type: string - format: date-time - description: 打包构建时间 - example: 2020-03-25T06:24:25Z - Healthz: - type: object - properties: - db_connect: - type: boolean - description: 是否连接了数据库 - example: true - CacheLabelInfo: - type: object - properties: - l: - type: string - description: 灰度标签名称 - example: beta - cls: - type: array - description: 灰度标签适用的 Clients 客户端类型列表,当列表为空时表示全适用 - example: ["ios", "android", "web"] - items: - type: string - chs: - type: array - description: 灰度标签适用的 Channels 版本通道列表,当列表为空时表示全适用 - example: ["stable", "beta", "dev"] - items: - type: string - LabelsInfoRes: - type: object - properties: - totalSize: - $ref: "#/components/schemas/TotalSize" - nextPageToken: - $ref: "#/components/schemas/NextPageToken" - result: - type: array - items: - $ref: "#/components/schemas/LabelInfo" - LabelInfo: - type: object - properties: - hid: - type: string - description: 灰度标签的 HID - example: AwAAAAAAAAB25V_QnbhCuRwF - product: - type: string - description: 灰度标签所属的产品名称 - example: teambition - name: - type: string - description: 灰度标签名称,同一产品下唯一(不能重名) - example: beta - desc: - type: string - description: 灰度标签描述 - channels: - type: array - description: 灰度标签适用版本通道 - example: ["beta"] - items: - type: string - clients: - type: array - description: 灰度标签适用客户端类型 - example: ["web"] - items: - type: string - status: - type: integer - format: int64 - description: 灰度标签状态(暂未支持) - example: 0 - created_at: - type: string - format: date-time - description: 灰度标签创建时间 - example: 2020-03-25T06:24:25Z - updated_at: - type: string - format: date-time - description: 灰度标签更新时间 - example: 2020-03-25T06:24:25Z - offline_at: - type: string - format: date-time - description: 灰度标签下线时间 - default: null - example: null - -paths: - /version: - get: - tags: - - Version - summary: 获取版本信息 - responses: - '200': - description: 请求成功 - content: - application/json: - schema: - $ref: '#/components/schemas/Version' - /healthz: - get: - summary: 服务健康检查接口 - responses: - '200': - description: 请求成功 - content: - application/json: - schema: - $ref: '#/components/schemas/Healthz' - # User API - /users/{uid}/labels:cache: - get: - tags: - - User - summary: 该接口用于灰度网关。获取指定 uid 用户灰度标签在指定 product 产品下的所有(未分页,最多 400 条)灰度标签,包括从 group 群组继承的灰度标签,按照 label 指派时间反序。网关只会取匹配 client 和 channel 的第一条。标签列表不是实时数据,会被服务缓存,缓存时间在 config.cache_label_expire 配置,默认为 1 分钟 - parameters: - - in: path - name: uid - description: 用户 UID,当 uid 对应用户不存在时,该接口会返回空灰度标签列表 - required: true - schema: - type: string - - in: query - name: product - description: 产品名称,当 product 对应产品不存在时,该接口会返回空灰度标签列表 - required: true - schema: - type: string - responses: - '200': - description: 请求成功 - content: - application/json: - schema: - allOf: - - type: object - properties: - timestamp: - type: integer - format: int64 - description: 灰度标签列表生成时间,1970 以来的秒数 - example: 1585129360 - - type: object - properties: - result: - type: array - description: 灰度标签列表 - items: - $ref: "#/components/schemas/CacheLabelInfo" - - /v1/users/{uid}/labels: - get: - tags: - - User - summary: 获取指定 uid 用户所有灰度标签,不包括从群组继承的灰度标签,支持分页。考虑到灰度标签不会很多,暂未支持根据 product 过滤 - parameters: - - in: header - name: Authorization - description: '请求 JWT token, 格式如: `Bearer xxx`' - required: true - schema: - type: string - - in: path - name: uid - description: 用户 UID,当 uid 对应用户不存在时,该接口会返回 404 错误 - required: true - schema: - type: string - - in: query - name: pageSize - description: 分页大小,默认为 10,(1-1000] - required: false - schema: - type: integer - format: int32 - default: 10 - example: 20 - - in: query - name: pageToken - description: 分页请求标记,来自于响应结果的 nextPageToken - required: false - schema: - title: pageToken - type: string - default: "" - example: "" - responses: - '200': - description: 请求成功 - content: - application/json: - schema: - $ref: '#/components/schemas/LabelsInfoRes' - '401': - description: 请求失败 - content: - application/json: - schema: - $ref: '#/components/schemas/ErrorResponse' - '404': - description: 请求失败 - content: - application/json: - schema: - $ref: '#/components/schemas/ErrorResponse' - - /v1/users/{uid}/labels:cache: - put: - tags: - - User - summary: 强制刷新指定用户的灰度标签列表缓存 - parameters: - - in: header - name: Authorization - description: '请求 JWT token, 格式如: `Bearer xxx`' - required: true - schema: - type: string - - in: path - name: uid - description: 用户 UID,当 uid 对应用户不存在时,该接口会返回 404 错误 - required: true - schema: - type: string - responses: - '200': - description: 请求成功 - content: - application/json: - schema: - $ref: '#/components/schemas/BoolRes' - '401': - description: 请求失败 - content: - application/json: - schema: - $ref: '#/components/schemas/ErrorResponse' - '404': - description: 请求失败 - content: - application/json: - schema: - $ref: '#/components/schemas/ErrorResponse' - - /v1/users/{uid}/labels: - get: - tags: - - User - summary: 获取指定 uid 用户所有灰度标签,不包括从群组继承的灰度标签,支持分页。考虑到灰度标签不会很多,暂未支持根据 product 过滤 - parameters: - - in: header - name: Authorization - description: '请求 JWT token, 格式如: `Bearer xxx`' - required: true - schema: - type: string - - in: path - name: uid - description: 用户 UID,当 uid 对应用户不存在时,该接口会返回 404 错误 - required: true - schema: - type: string - - in: query - name: pageSize - description: 分页大小,默认为 10,(1-1000] - required: false - schema: - type: integer - format: int32 - default: 10 - example: 20 - - in: query - name: pageToken - description: 分页请求标记,来自于响应结果的 nextPageToken - required: false - schema: - title: pageToken - type: string - default: "" - example: "" - responses: - '200': - description: 请求成功 - content: - application/json: - schema: - $ref: '#/components/schemas/LabelsInfoRes' - '401': - description: 请求失败 - content: - application/json: - schema: - $ref: '#/components/schemas/ErrorResponse' - '404': - description: 请求失败 - content: - application/json: - schema: - $ref: '#/components/schemas/ErrorResponse' - - # requestBody: - # content: - # application/json: - # schema: - # $ref: '#/components/schemas/createCommentRequest' - # description: 动态信息 - # required: true diff --git a/doc/swagger_header.yaml b/doc/swagger_header.yaml index 54b289c..5ad1af8 100644 --- a/doc/swagger_header.yaml +++ b/doc/swagger_header.yaml @@ -23,6 +23,13 @@ tags: - name: Setting description: Setting 产品模块配置项相关接口 components: + securitySchemes: + HeaderAuthorizationJWT: + name: Authorization + type: http + scheme: bearer + bearerFormat: JWT + in: header schemas: NextPageToken: title: nextPageToken @@ -34,7 +41,7 @@ components: type: integer format: int64 description: 当前分页查询的总数据量 - example: 99 + example: 1 ErrorResponse: type: object properties: @@ -115,7 +122,7 @@ components: properties: hid: type: string - description: 灰度标签的 HID + description: 灰度标签的 hid example: AwAAAAAAAAB25V_QnbhCuRwF product: type: string @@ -161,7 +168,135 @@ components: description: 灰度标签下线时间 default: null example: null - + MySettingsRes: + type: object + properties: + nextPageToken: + $ref: "#/components/schemas/NextPageToken" + result: + type: array + items: + $ref: "#/components/schemas/MySetting" + MySetting: + type: object + properties: + hid: + type: string + description: 配置项的 hid + example: AwAAAAAAAAB25V_QnbhCuRwF + module: + type: string + description: 配置项所属的功能模块名称 + example: task + name: + type: string + description: 配置项名称,同一产品功能模块下唯一(不能重名) + example: task-share + value: + type: string + description: 配置项值 + example: disable + last_value: + type: string + description: 配置项值 + example: "" + created_at: + type: string + format: date-time + description: 灰度标签创建时间 + example: 2020-03-25T06:24:25Z + updated_at: + type: string + format: date-time + description: 灰度标签更新时间 + example: 2020-03-25T06:24:25Z + UsersBody: + type: object + properties: + users: + type: array + description: 用户 uid 数组 + items: + type: string + example: ["50c32afae8cf1439d35a87e6", "5e69a9bd6ac3cd00213ea969"] + GroupsRes: + type: object + properties: + totalSize: + $ref: "#/components/schemas/TotalSize" + nextPageToken: + $ref: "#/components/schemas/NextPageToken" + result: + type: array + items: + $ref: "#/components/schemas/Group" + Group: + type: object + properties: + uid: + type: string + description: 群组的 uid + example: 5e82d747fe02a50021d339f3 + kind: + type: string + description: 群组类型 + example: organization + desc: + type: string + description: 群组的描述 + sync_at: + type: integer + format: int64 + description: 群组成员同步时间点,1970 以来的秒数 + example: 1585636012 + created_at: + type: string + format: date-time + description: 灰度标签创建时间 + example: 2020-03-25T06:24:25Z + updated_at: + type: string + format: date-time + description: 灰度标签更新时间 + example: 2020-03-25T06:24:25Z + GroupsBody: + type: object + properties: + groups: + type: array + description: 用户 uid 数组 + required: true + items: + type: object + properties: + uid: + type: string + description: 群组 uid + required: true + kind: + type: string + description: 群组类型 + required: true + desc: + type: string + description: 群组描述 + required: false + example: [{"uid": "50c32afae8cf1439d35a87e6", "kind": "organization"}] + GroupUpdateBody: + type: object + properties: + type: object + properties: + sync_at: + type: integer + title: sync_at + format: int64 + description: 群组成员同步时间点,1970 以来的秒数 + desc: + type: string + title: desc + description: 群组描述 + example: {"sync_at": 1585638012} paths: /version: get: diff --git a/doc/swagger_user.yaml b/doc/swagger_user.yaml deleted file mode 100644 index 8beaf64..0000000 --- a/doc/swagger_user.yaml +++ /dev/null @@ -1,198 +0,0 @@ - # User API - /users/{uid}/labels:cache: - get: - tags: - - User - summary: 该接口用于灰度网关。获取指定 uid 用户灰度标签在指定 product 产品下的所有(未分页,最多 400 条)灰度标签,包括从 group 群组继承的灰度标签,按照 label 指派时间反序。网关只会取匹配 client 和 channel 的第一条。标签列表不是实时数据,会被服务缓存,缓存时间在 config.cache_label_expire 配置,默认为 1 分钟 - parameters: - - in: path - name: uid - description: 用户 UID,当 uid 对应用户不存在时,该接口会返回空灰度标签列表 - required: true - schema: - type: string - - in: query - name: product - description: 产品名称,当 product 对应产品不存在时,该接口会返回空灰度标签列表 - required: true - schema: - type: string - responses: - '200': - description: 请求成功 - content: - application/json: - schema: - allOf: - - type: object - properties: - timestamp: - type: integer - format: int64 - description: 灰度标签列表生成时间,1970 以来的秒数 - example: 1585129360 - - type: object - properties: - result: - type: array - description: 灰度标签列表 - items: - $ref: "#/components/schemas/CacheLabelInfo" - - /v1/users/{uid}/labels: - get: - tags: - - User - summary: 获取指定 uid 用户所有灰度标签,不包括从群组继承的灰度标签,支持分页。考虑到灰度标签不会很多,暂未支持根据 product 过滤 - parameters: - - in: header - name: Authorization - description: '请求 JWT token, 格式如: `Bearer xxx`' - required: true - schema: - type: string - - in: path - name: uid - description: 用户 UID,当 uid 对应用户不存在时,该接口会返回 404 错误 - required: true - schema: - type: string - - in: query - name: pageSize - description: 分页大小,默认为 10,(1-1000] - required: false - schema: - type: integer - format: int32 - default: 10 - example: 20 - - in: query - name: pageToken - description: 分页请求标记,来自于响应结果的 nextPageToken - required: false - schema: - title: pageToken - type: string - default: "" - example: "" - responses: - '200': - description: 请求成功 - content: - application/json: - schema: - $ref: '#/components/schemas/LabelsInfoRes' - '401': - description: 请求失败 - content: - application/json: - schema: - $ref: '#/components/schemas/ErrorResponse' - '404': - description: 请求失败 - content: - application/json: - schema: - $ref: '#/components/schemas/ErrorResponse' - - /v1/users/{uid}/labels:cache: - put: - tags: - - User - summary: 强制刷新指定用户的灰度标签列表缓存 - parameters: - - in: header - name: Authorization - description: '请求 JWT token, 格式如: `Bearer xxx`' - required: true - schema: - type: string - - in: path - name: uid - description: 用户 UID,当 uid 对应用户不存在时,该接口会返回 404 错误 - required: true - schema: - type: string - responses: - '200': - description: 请求成功 - content: - application/json: - schema: - $ref: '#/components/schemas/BoolRes' - '401': - description: 请求失败 - content: - application/json: - schema: - $ref: '#/components/schemas/ErrorResponse' - '404': - description: 请求失败 - content: - application/json: - schema: - $ref: '#/components/schemas/ErrorResponse' - - /v1/users/{uid}/labels: - get: - tags: - - User - summary: 获取指定 uid 用户所有灰度标签,不包括从群组继承的灰度标签,支持分页。考虑到灰度标签不会很多,暂未支持根据 product 过滤 - parameters: - - in: header - name: Authorization - description: '请求 JWT token, 格式如: `Bearer xxx`' - required: true - schema: - type: string - - in: path - name: uid - description: 用户 UID,当 uid 对应用户不存在时,该接口会返回 404 错误 - required: true - schema: - type: string - - in: query - name: pageSize - description: 分页大小,默认为 10,(1-1000] - required: false - schema: - type: integer - format: int32 - default: 10 - example: 20 - - in: query - name: pageToken - description: 分页请求标记,来自于响应结果的 nextPageToken - required: false - schema: - title: pageToken - type: string - default: "" - example: "" - responses: - '200': - description: 请求成功 - content: - application/json: - schema: - $ref: '#/components/schemas/LabelsInfoRes' - '401': - description: 请求失败 - content: - application/json: - schema: - $ref: '#/components/schemas/ErrorResponse' - '404': - description: 请求失败 - content: - application/json: - schema: - $ref: '#/components/schemas/ErrorResponse' - - # requestBody: - # content: - # application/json: - # schema: - # $ref: '#/components/schemas/createCommentRequest' - # description: 动态信息 - # required: true diff --git a/src/api/router.go b/src/api/router.go index 1578dce..2797a15 100644 --- a/src/api/router.go +++ b/src/api/router.go @@ -64,11 +64,11 @@ func newRouters(apis *APIs) []*gear.Router { routerV1.Get("/users/:uid+:exists", apis.User.CheckExists) // 批量添加用户 routerV1.Post("/users:batch", apis.User.BatchAdd) - // 删除指定用户的指定灰度标签 + // 移除指定用户的指定灰度标签 routerV1.Delete("/users/:uid/labels/:hid", apis.User.RemoveLable) // 回滚指定用户的指定配置项 routerV1.Put("/users/:uid/settings/:hid+:rollback", apis.User.RollbackSetting) - // 删除指定用户的指定配置项 + // 移除指定用户的指定配置项 routerV1.Delete("/users/:uid/settings/:hid", apis.User.RemoveSetting) // ***** group ****** @@ -92,11 +92,11 @@ func newRouters(apis *APIs) []*gear.Router { routerV1.Post("/groups/:uid/members:batch", apis.Group.BatchAddMembers) // 指定群组根据条件清理成员 routerV1.Delete("/groups/:uid/members", apis.Group.RemoveMembers) - // 删除指定群组的指定灰度标签 + // 移除指定群组的指定灰度标签 routerV1.Delete("/groups/:uid/labels/:hid", apis.Group.RemoveLable) // 回滚指定群组的指定配置项 routerV1.Put("/groups/:uid/settings/:hid+:rollback", apis.Group.RollbackSetting) - // 删除指定群组的指定配置项 + // 移除指定群组的指定配置项 routerV1.Delete("/groups/:uid/settings/:hid", apis.Group.RemoveSetting) // ***** product ****** diff --git a/src/api/user_test.go b/src/api/user_test.go index ae8a030..2c8c375 100644 --- a/src/api/user_test.go +++ b/src/api/user_test.go @@ -456,6 +456,26 @@ func TestUserAPIs(t *testing.T) { assert.True(data.CreatedAt.After(time2020)) }) + t.Run(`"GET /v1/users/:uid/settings:unionAll" for invalid user`, func(t *testing.T) { + assert := assert.New(t) + + res, err := request.Get(fmt.Sprintf("%s/v1/users/%s/settings:unionAll?product=%s", tt.Host, tpl.RandUID(), product.Name)). + End() + assert.Nil(err) + assert.Equal(200, res.StatusCode) + + text, err := res.Text() + assert.Nil(err) + assert.False(strings.Contains(text, `"id"`)) + + json := tpl.MySettingsRes{} + _, err = res.JSON(&json) + + assert.Nil(err) + assert.Equal(0, len(json.Result)) + assert.Equal("", json.NextPageToken) + }) + t.Run(`"GET /v1/users/:uid/settings:unionAll" should work`, func(t *testing.T) { assert := assert.New(t) diff --git a/src/bll/user.go b/src/bll/user.go index 31cdd24..4f3c038 100644 --- a/src/bll/user.go +++ b/src/bll/user.go @@ -127,12 +127,13 @@ func (b *User) ListSettings(ctx context.Context, uid, productName string, pg tpl // ListSettingsUnionAll ... func (b *User) ListSettingsUnionAll(ctx context.Context, uid, productName, channel, client string, pg tpl.Pagination) (*tpl.MySettingsRes, error) { + res := &tpl.MySettingsRes{Result: []tpl.MySetting{}} user, err := b.ms.User.FindByUID(ctx, uid, "id") if err != nil { return nil, err } if user == nil { - return nil, gear.ErrNotFound.WithMsgf("user %s not found", uid) + return res, nil } product, err := b.ms.Product.FindByName(ctx, productName, "id, `offline_at`, `deleted_at`") @@ -140,7 +141,7 @@ func (b *User) ListSettingsUnionAll(ctx context.Context, uid, productName, chann return nil, err } if product == nil { - return nil, gear.ErrNotFound.WithMsgf("product %s not found", productName) + return res, gear.ErrNotFound.WithMsgf("product %s not found", productName) } if product.DeletedAt != nil { return nil, gear.ErrNotFound.WithMsgf("product %s was deleted", productName) @@ -164,7 +165,7 @@ func (b *User) ListSettingsUnionAll(ctx context.Context, uid, productName, chann return nil, err } - res := &tpl.MySettingsRes{Result: settings} + res.Result = settings if len(res.Result) > pg.PageSize { res.NextPageToken = tpl.TimeToPageToken(res.Result[pg.PageSize].UpdatedAt) res.Result = res.Result[:pg.PageSize]