You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@apisix.apache.org by me...@apache.org on 2020/03/15 14:42:14 UTC

[incubator-apisix] branch master updated: doc: add route/service/consumer/upstream/ssl definitions to Admin API (#1258)

This is an automated email from the ASF dual-hosted git repository.

membphis pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-apisix.git


The following commit(s) were added to refs/heads/master by this push:
     new cade206  doc: add route/service/consumer/upstream/ssl definitions to  Admin API (#1258)
cade206 is described below

commit cade206d5abceab359ce083347f7fbcc310e438b
Author: Yousa <sn...@gmail.com>
AuthorDate: Sun Mar 15 22:42:09 2020 +0800

    doc: add route/service/consumer/upstream/ssl definitions to  Admin API (#1258)
---
 doc/admin-api-cn.md        | 294 ++++++++++++++++++++++++++++++++++++++++++++-
 doc/admin-api.md           | 287 +++++++++++++++++++++++++++++++++++++++++++
 doc/architecture-design.md |   2 +
 3 files changed, 582 insertions(+), 1 deletion(-)

diff --git a/doc/admin-api-cn.md b/doc/admin-api-cn.md
index 1b61af1..890cb46 100644
--- a/doc/admin-api-cn.md
+++ b/doc/admin-api-cn.md
@@ -22,6 +22,10 @@
 ===
 
 * [Route](#route)
+* [Service](#service)
+* [Consumer](#consumer)
+* [Upstream](#upstream)
+* [SSL](#ssl)
 
 ## Route
 
@@ -71,7 +75,29 @@
 - 除了 `uri`/`uris` 是必选的之外,`plugins`、`upstream`/`upstream_id`、`service_id` 这三类必须选择其中至少一个。
 - 对于同一类参数比如 `uri`与 `uris`,`upstream` 与 `upstream_id`,`host` 与 `hosts`,`remote_addr` 与 `remote_addrs` 等,是不能同时存在,二者只能选择其一。如果同时启用,接口会报错。
 
-示例:
+route 对象 json 配置内容:
+
+```shell
+{
+    "id": "1",                  # id,非必填
+    "uri": "/release/a",        # uri 路径
+    "uris": ["/a","/b"],        # 一组 uri 路径, uri 与 uris 只需要有一个非空即可
+    "methods": ["GET","POST"],  # 可以填多个方法
+    "host": "aa.com",           # host 域名
+    "hosts": ["a.com","b.com"], # 一组 host 域名, host 与 hosts 只需要有一个非空即可
+    "plugins": {},              # 指定 route 绑定的插件
+    "priority": 0,              # apisix 支持多种匹配方式,可能会在一次匹配中同时匹配到多条路由,此时优先级高的优先匹配中
+    "desc": "hello world",
+    "remote_addr": "127.0.0.1", # 客户端请求 IP 地址
+    "remote_addrs": ["127.0.0.1"],  # 一组客户端请求 IP 地址, remote_addr 与 remote_addrs 只需要有一个非空即可
+    "vars": [],                 # 由一个或多个 {var, operator, val} 元素组成的列表
+    "upstream_id": "1",         # upstream 对象在 etcd 中的 id ,建议使用此值
+    "upstream": {},             # upstream 信息对象,建议尽量不要使用
+    "filter_func": "",          # 用户自定义的过滤函数,非必填
+}
+```
+
+具体示例:
 
 ```shell
 # 创建一个路由
@@ -147,3 +173,269 @@ curl http://127.0.0.1:9080/apisix/admin/routes/1 -H 'X-API-KEY: edd1c9f034335f13
 
 [Back to TOC](#目录)
 
+## Service
+
+*地址*:/apisix/admin/services/{id}
+
+*说明*:`Service` 是某类 API 的抽象(也可以理解为一组 Route 的抽象)。它通常与上游服务抽象是一一对应的,`Route`
+与 `Service` 之间,通常是 N:1 的关系。
+
+> 请求方法:
+
+|名字      |请求 uri|请求 body|说明        |
+|---------|-------------------------|--|------|
+|GET      |/apisix/admin/services/{id}|无|获取资源|
+|PUT      |/apisix/admin/services/{id}|{...}|根据 id 创建资源|
+|POST     |/apisix/admin/services     |{...}|创建资源,id 由后台服务自动生成|
+|DELETE   |/apisix/admin/services/{id}|无|删除资源|
+|PATCH    |/apisix/admin/services/{id}/{path}|{...}|修改已有 Service 的部分内容,其他不涉及部分会原样保留。|
+
+> body 请求参数:
+
+|名字      |可选项   |类型 |说明        |示例|
+|---------|---------|----|-----------|----|
+|plugins  |可选 |Plugin|详见 [Plugin](architecture-design-cn.md#plugin) ||
+|upstream | upstream 或 upstream_id 两个选一个 |Upstream|启用的 Upstream 配置,详见 [Upstream](architecture-design-cn.md#upstream)||
+|upstream_id| upstream 或 upstream_id 两个选一个 |Upstream|启用的 upstream id,详见 [Upstream](architecture-design-cn.md#upstream)||
+|desc     |可选 |辅助   |标识服务名称、使用场景等。||
+
+serivce 对象 json 配置内容:
+
+```shell
+{
+    "id": "1",              # id
+    "plugins": {},          # 指定 service 绑定的插件
+    "upstream_id": "1",     # upstream 对象在 etcd 中的 id ,建议使用此值
+    "upstream": {},         # upstream 信息对象,不建议使用
+    "desc": "hello world",  # service 描述
+}
+```
+
+具体示例:
+
+```shell
+# 创建一个Service
+$ curl http://127.0.0.1:9080/apisix/admin/services/201 -X PUT -i -d '
+{
+    "plugins": {
+        "limit-count": {
+            "count": 2,
+            "time_window": 60,
+            "rejected_code": 503,
+            "key": "remote_addr"
+        }
+    },
+    "upstream": {
+        "type": "roundrobin",
+        "nodes": {
+            "39.97.63.215:80": 1
+        }
+    }
+}'
+
+# 返回结果
+
+HTTP/1.1 201 Created
+Date: Thu, 26 Dec 2019 03:48:47 GMT
+Content-Type: text/plain
+Transfer-Encoding: chunked
+Connection: keep-alive
+Access-Control-Allow-Origin: *
+Access-Control-Allow-Credentials: true
+Access-Control-Expose-Headers: *
+Access-Control-Max-Age: 3600
+Server: APISIX web server
+
+{"node":{"value":{"upstream":{"nodes":{"39.97.63.215:80":1},"type":"roundrobin"},"plugins":{"limit-count":{"time_window":60,"count":2,"rejected_code":503,"key":"remote_addr","policy":"local"}}},"createdIndex":60,"key":"\/apisix\/services\/201","modifiedIndex":60},"action":"set"}
+```
+
+> 应答参数
+
+目前是直接返回与 etcd 交互后的结果。
+
+[Back to TOC](#目录)
+
+## Consumer
+
+*地址*:/apisix/admin/consumers/{id}
+
+*说明*:Consumer 是某类服务的消费者,需与用户认证体系配合才能使用。
+
+> 请求方法:
+
+|名字      |请求 uri|请求 body|说明        |
+|---------|-------------------------|--|------|
+|GET      |/apisix/admin/consumers/{id}|无|获取资源|
+|PUT      |/apisix/admin/consumers/{id}|{...}|根据 id 创建资源|
+|POST     |/apisix/admin/consumers     |{...}|创建资源,id 由后台服务自动生成|
+|DELETE   |/apisix/admin/consumers/{id}|无|删除资源|
+
+> body 请求参数:
+
+|名字      |可选项   |类型 |说明        |示例|
+|---------|---------|----|-----------|----|
+|username|必需|辅助|Consumer 名称。||
+|plugins|可选|Plugin|该 Consumer 对应的插件配置,它的优先级是最高的:Consumer > Route > Service。对于具体插件配置,可以参考 [Plugins](#plugin) 章节。||
+|desc     |可选 |辅助|consumer描述||
+
+consumer 对象 json 配置内容:
+
+```shell
+{
+    "id": "1",              # id
+    "plugins": {},          # 指定 consumer 绑定的插件
+    "username": "name",     # 必填
+    "desc": "hello world",  # consumer 描述
+}
+```
+
+绑定认证授权插件有些特别,当它需要与 consumer 联合使用时,需要提供用户名、密码等信息;另一方面,当它与 route/service 绑定时,是不需要任何参数的。因为这时候是根据用户请求数据来反向推出用户对应的是哪个 consumer
+
+示例:
+
+```shell
+# 创建 Consumer ,指定认证插件 key-auth ,并开启特定插件 limit-count
+$ curl http://127.0.0.1:9080/apisix/admin/consumers/2 -X PUT -i -d '
+{
+    "username": "jack",
+    "plugins": {
+        "key-auth": {
+            "key": "auth-one"
+        },
+        "limit-count": {
+            "count": 2,
+            "time_window": 60,
+            "rejected_code": 503,
+            "key": "remote_addr"
+        }
+    }
+}'
+HTTP/1.1 200 OK
+Date: Thu, 26 Dec 2019 08:17:49 GMT
+...
+
+{"node":{"value":{"username":"jack","plugins":{"key-auth":{"key":"auth-one"},"limit-count":{"time_window":60,"count":2,"rejected_code":503,"key":"remote_addr","policy":"local"}}},"createdIndex":64,"key":"\/apisix\/consumers\/jack","modifiedIndex":64},"prevNode":{"value":"{\"username\":\"jack\",\"plugins\":{\"key-auth\":{\"key\":\"auth-one\"},\"limit-count\":{\"time_window\":60,\"count\":2,\"rejected_code\":503,\"key\":\"remote_addr\",\"policy\":\"local\"}}}","createdIndex":63,"key":"\/ap [...]
+```
+
+> 应答参数
+
+目前是直接返回与 etcd 交互后的结果。
+
+[Back to TOC](#目录)
+
+## Upstream
+
+*地址*:/apisix/admin/upstreams/{id}
+
+*说明*:Upstream 是虚拟主机抽象,对给定的多个服务节点按照配置规则进行负载均衡。Upstream 的地址信息可以直接配置到 `Route`(或 `Service`) 上,当 Upstream 有重复时,就需要用“引用”方式避免重复了。
+
+> 请求方法:
+
+|名字      |请求 uri|请求 body|说明        |
+|---------|-------------------------|--|------|
+|GET      |/apisix/admin/upstreams/{id}|无|获取资源|
+|PUT      |/apisix/admin/upstreams/{id}|{...}|根据 id 创建资源|
+|POST     |/apisix/admin/upstreams     |{...}|创建资源,id 由后台服务自动生成|
+|DELETE   |/apisix/admin/upstreams/{id}|无|删除资源|
+|PATCH    |/apisix/admin/upstreams/{id}/{path}|{...}|修改已有 Route 的部分内容,其他不涉及部分会原样保留。|
+
+> body 请求参数:
+
+APISIX 的 Upstream 除了基本的复杂均衡算法选择外,还支持对上游做主被动健康检查、重试等逻辑,具体看下面表格。
+
+|名字      |可选项   |类型 |说明        |示例|
+|---------|---------|----|-----------|----|
+|nodes           |必需|Node|哈希表,内部元素的 key 是上游机器地址列表,格式为`地址 + Port`,其中地址部分可以是 IP 也可以是域名,比如 `192.168.1.100:80`、`foo.com:80`等。value 则是节点的权重,特别的,当权重值为 `0` 有特殊含义,通常代表该上游节点失效,永远不希望被选中。|`192.168.1.100:80`|
+|type            |必需|枚举|`roundrobin` 支持权重的负载,`chash` 一致性哈希,两者是二选一的|`roundrobin`||
+|key             |条件必需|匹配类型|该选项只有类型是 `chash` 才有效。根据 `key` 来查找对应的 node `id`,相同的 `key` 在同一个对象中,永远返回相同 id,目前支持的 Nginx 内置变量有 `uri, server_name, server_addr, request_uri, remote_port, remote_addr, query_string, host, hostname, arg_***`,其中 `arg_***` 是来自URL的请求参数,[Nginx 变量列表](http://nginx.org/en/docs/varindex.html)||
+|checks          |可选|health_checker|配置健康检查的参数,详细可参考[health-check](health-check.md)||
+|retries         |可选|整型|使用底层的 Nginx 重试机制将请求传递给下一个上游,默认不启用重试机制||
+|timeout         |可选|超时时间对象|设置连接、发送消息、接收消息的超时时间||
+|enable_websocket     |可选 |辅助|是否允许启用 websocket 能力||
+|hash_on     |可选 |辅助|该参数作为一致性 hash 的入参||
+|desc     |可选 |辅助|标识服务名称、使用场景等。||
+
+upstream 对象 json 配置内容:
+
+```shell
+{
+    "id": "1",                  # id
+    "retries": 0,               # 请求重试次数
+    "timeout": {                # 设置连接、发送消息、接收消息的超时时间
+        "connect":15,
+        "send":15,
+        "read":15,
+    },
+    "enable_websocket": true,
+    "nodes": {"host:80": 100},  # 上游机器地址列表,格式为`地址 + Port`
+    "type":"roundrobin",        # chash or roundrobin
+    "checks": {},               # 配置健康检查的参数
+    "hash_on": "",
+    "key": "",
+    "desc": "hello world",      # upstream 描述
+}
+```
+
+具体示例:
+
+```shell
+# 创建一个upstream
+$ curl http://127.0.0.1:9080/apisix/admin/upstreams/100 -i -X PUT -d '
+> {
+>     "type": "roundrobin",
+>     "nodes": {
+>         "127.0.0.1:80": 1,
+>         "127.0.0.2:80": 2,
+>         "foo.com:80": 3
+>     }
+> }'
+HTTP/1.1 201 Created
+Date: Thu, 26 Dec 2019 04:19:34 GMT
+Content-Type: text/plain
+...
+
+{"node":{"value":{"nodes":{"127.0.0.1:80":1,"foo.com:80":3,"127.0.0.2:80":2},"type":"roundrobin"},"createdIndex":61,"key":"\/apisix\/upstreams\/100","modifiedIndex":61},"action":"set"}
+
+```
+
+> 应答参数
+
+目前是直接返回与 etcd 交互后的结果。
+
+[Back to TOC](#目录)
+
+## SSL
+
+*地址*:/apisix/admin/ssl/{id}
+
+*说明*:SSL.
+
+> 请求方法:
+
+|名字      |请求 uri|请求 body|说明        |
+|---------|-------------------------|--|------|
+|GET      |/apisix/admin/ssl/{id}|无|获取资源|
+|PUT      |/apisix/admin/ssl/{id}|{...}|根据 id 创建资源|
+|POST     |/apisix/admin/ssl     |{...}|创建资源,id 由后台服务自动生成|
+|DELETE   |/apisix/admin/ssl/{id}|无|删除资源|
+
+> body 请求参数:
+
+|名字      |可选项   |类型 |说明        |示例|
+|---------|---------|----|-----------|----|
+|cert|必需|公钥|https 证书公钥||
+|key|必需|私钥|https 证书私钥||
+|sni|必需|匹配规则|https 证书SNI||
+
+ssl 对象 json 配置内容:
+
+```shell
+{
+    "id": "1",          # id
+    "cert": "cert",     # 公钥
+    "key": "key",       # 私钥
+    "sni": "sni"        # host 域名
+}
+```
+
+[Back to TOC](#目录)
diff --git a/doc/admin-api.md b/doc/admin-api.md
index c14f0ac..f22021f 100644
--- a/doc/admin-api.md
+++ b/doc/admin-api.md
@@ -22,6 +22,10 @@ Table of contents
 ===
 
 * [Route](#route)
+* [Service](#service)
+* [Consumer](#consumer)
+* [Upstream](#upstream)
+* [SSL](#ssl)
 
 ## Route
 
@@ -67,6 +71,28 @@ Table of contents
 
 For the same type of parameters, such as `host` and `hosts`, `remote_addr` and `remote_addrs` cannot exist at the same time, only one of them can be selected. If enabled at the same time, the API will response an error.
 
+Config Example:
+
+```shell
+{
+    "id": "1",                  # id, unnecessary.
+    "uri": "/release/a",        # uri
+    "uris": ["/a","/b"],        # A set of uri, uri and uris need only have a non-empty one.
+    "methods": ["GET","POST"],  # Can fill multiple methods
+    "host": "aa.com",           # host
+    "hosts": ["a.com","b.com"], # A set of host. Host and hosts only need to be non-empty one.
+    "plugins": {},              # Bound plugin
+    "priority": 0,              # If different routes contain the same `uri`, determine which route is matched first based on the attribute` priority`, the default value is 0.
+    "desc": "hello world",
+    "remote_addr": "127.0.0.1", # Client IP
+    "remote_addrs": ["127.0.0.1"], # A set of Client IP. Remote_addr and remo-te_addrs only need to be non-empty one.
+    "vars": [],                 # A list of one or more `{var, operator, val}` elements
+    "upstream_id": "1",         # upstream id, recommended
+    "upstream": {},             # upstream, not recommended
+    "filter_func": "",          # User-defined filtering function
+}
+```
+
 Example:
 
 ```shell
@@ -142,3 +168,264 @@ curl http://127.0.0.1:9080/apisix/admin/routes/1 -H 'X-API-KEY: edd1c9f034335f13
 ```
 
 [Back to TOC](#table-of-contents)
+
+## Service
+
+*API*:/apisix/admin/services/{id}
+
+*Description*:A `Service` is an abstraction of an API (which can also be understood as a set of Route abstractions). It usually corresponds to the upstream service abstraction. Between `Route` and `Service`, usually the relationship of N:1.
+
+> Request Methods:
+
+|Method      |Request URI|Request Body|Description        |
+|---------|-------------------------|--|------|
+|GET      |/apisix/admin/services/{id}|NULL|Fetch resource|
+|PUT      |/apisix/admin/services/{id}|{...}|Create resource by ID|
+|POST     |/apisix/admin/services     |{...}|Create resource, and ID is generated by server|
+|DELETE   |/apisix/admin/services/{id}|NULL|Remove resource|
+|PATCH    |/apisix/admin/routes/{id}/{path}|{...}|Update targeted content|
+
+> Request Body Parameters:
+
+|Parameter      |Required   |Type |Description        |Example|
+|---------|---------|----|-----------|----|
+|plugins  |False |Plugin|See [Plugin](architecture-design.md#plugin) for more ||
+|upstream |False |Upstream|Enabled Upstream configuration, see [Upstream](architecture-design.md#upstream) for more||
+|upstream_id|False |Upstream|Enabled upstream id, see [Upstream](architecture-design.md#upstream) for more ||
+|desc     |False |Auxiliary   |Identifies route names, usage scenarios, and more.|customer xxxx|
+
+Config Example:
+
+```shell
+{
+    "id": "1",          # id
+    "plugins": {},      # Bound plugin
+    "upstream_id": "1", # upstream id, recommended
+    "upstream": {},     # upstream, not recommended
+    "desc": "hello world",
+}
+```
+
+Example:
+
+```shell
+$ curl http://127.0.0.1:9080/apisix/admin/services/201 -X PUT -i -d '
+{
+    "plugins": {
+        "limit-count": {
+            "count": 2,
+            "time_window": 60,
+            "rejected_code": 503,
+            "key": "remote_addr"
+        }
+    },
+    "upstream": {
+        "type": "roundrobin",
+        "nodes": {
+            "39.97.63.215:80": 1
+        }
+    }
+}'
+
+HTTP/1.1 201 Created
+Date: Thu, 26 Dec 2019 03:48:47 GMT
+Content-Type: text/plain
+Transfer-Encoding: chunked
+Connection: keep-alive
+Access-Control-Allow-Origin: *
+Access-Control-Allow-Credentials: true
+Access-Control-Expose-Headers: *
+Access-Control-Max-Age: 3600
+Server: APISIX web server
+
+{"node":{"value":{"upstream":{"nodes":{"39.97.63.215:80":1},"type":"roundrobin"},"plugins":{"limit-count":{"time_window":60,"count":2,"rejected_code":503,"key":"remote_addr","policy":"local"}}},"createdIndex":60,"key":"\/apisix\/services\/201","modifiedIndex":60},"action":"set"}
+```
+
+> Response Parameters
+
+Return response from etcd currently.
+
+[Back to TOC](#table-of-contents)
+
+## Consumer
+
+*API*:/apisix/admin/consumers/{id}
+
+*Description*:Consumers are consumers of certain types of services and can only be used in conjunction with a user authentication system.
+
+> Request Methods:
+
+|Method      |Request URI|Request Body|Description        |
+|---------|-------------------------|--|------|
+|GET      |/apisix/admin/consumers/{id}|NULL|Fetch resource|
+|PUT      |/apisix/admin/consumers/{id}|{...}|Create resource by ID|
+|POST     |/apisix/admin/consumers     |{...}|Create resource, and ID is generated by server|
+|DELETE   |/apisix/admin/consumers/{id}|NULL|Remove resource|
+
+> Request Body Parameters:
+
+|Parameter      |Required   |Type |Description        |Example|
+|---------|---------|----|-----------|----|
+|username|True|Name|Consumer name||
+|plugins  |False |Plugin|See [Plugin](architecture-design.md#plugin) for more ||
+|desc     |False |Auxiliary   |Identifies route names, usage scenarios, and more.|customer xxxx|
+
+Config Example:
+
+```shell
+{
+    "id": "1",              # id
+    "plugins": {},          # Bound plugin
+    "username": "name",     # Consumer name
+    "desc": "hello world",  # Consumer desc
+}
+```
+
+The binding authentication and authorization plug-in is a bit special. When it needs to be used in conjunction with the consumer, it needs to provide user name, password and other information; on the other hand, when it is bound with route / service, it does not require any parameters. Because at this time, it is based on the user request data to infer which consumer the user corresponds to.
+
+Example:
+
+```shell
+$ curl http://127.0.0.1:9080/apisix/admin/consumers/2 -X PUT -i -d '
+{
+    "username": "jack",
+    "plugins": {
+        "key-auth": {
+            "key": "auth-one"
+        },
+        "limit-count": {
+            "count": 2,
+            "time_window": 60,
+            "rejected_code": 503,
+            "key": "remote_addr"
+        }
+    }
+}'
+HTTP/1.1 200 OK
+Date: Thu, 26 Dec 2019 08:17:49 GMT
+...
+
+{"node":{"value":{"username":"jack","plugins":{"key-auth":{"key":"auth-one"},"limit-count":{"time_window":60,"count":2,"rejected_code":503,"key":"remote_addr","policy":"local"}}},"createdIndex":64,"key":"\/apisix\/consumers\/jack","modifiedIndex":64},"prevNode":{"value":"{\"username\":\"jack\",\"plugins\":{\"key-auth\":{\"key\":\"auth-one\"},\"limit-count\":{\"time_window\":60,\"count\":2,\"rejected_code\":503,\"key\":\"remote_addr\",\"policy\":\"local\"}}}","createdIndex":63,"key":"\/ap [...]
+```
+
+> Response Parameters
+
+Return response from etcd currently.
+
+[Back to TOC](#table-of-contents)
+
+## Upstream
+
+*API*:/apisix/admin/upstreams/{id}
+
+*Description*:Upstream configuration can be directly bound to the specified `Route` or it can be bound to `Service`, but the configuration in `Route` has a higher priority. The priority behavior here is very similar to `Plugin`.
+
+> Request Methods:
+
+|Method      |Request URI|Request Body|Description        |
+|---------|-------------------------|--|------|
+|GET      |/apisix/admin/upstreams/{id}|NULL|Fetch resource|
+|PUT      |/apisix/admin/upstreams/{id}|{...}|Create resource by ID|
+|POST     |/apisix/admin/upstreams     |{...}|Create resource, and ID is generated by server|
+|DELETE   |/apisix/admin/upstreams/{id}|NULL|Remove resource|
+|PATCH    |/apisix/admin/upstreams/{id}/{path}|{...}|Update targeted content|
+
+> Request Body Parameters:
+
+In addition to the basic complex equalization algorithm selection, APISIX's Upstream also supports logic for upstream passive health check and retry, see the table below.
+
+|Name    |Optional|Description|
+|-------         |-----|------|
+|type            |required|`roundrobin` supports the weight of the load, `chash` consistency hash, pick one of them.|
+|nodes           |required|Hash table, the key of the internal element is the upstream machine address list, the format is `Address + Port`, where the address part can be IP or domain name, such as `192.168.1.100:80`, `foo.com:80`, etc. Value is the weight of the node. In particular, when the weight value is `0`, it has a special meaning, which usually means that the upstream node is invalid and never wants to be selected.|
+|hash_on         |optional|This option is only valid if the `type` is `chash`. Supported types `vars`(Nginx variables), `header`(custom header), `cookie`, `consumer`, the default value is `vars`.|
+|key             |required|This option is only valid if the `type` is `chash`. Find the corresponding node `id` according to `hash_on` and `key`. When `hash_on` is set as `vars`, `key` is the required parameter, for now, it support nginx built-in variables like `uri, server_name, server_addr, request_uri, remote_port, remote_addr, query_string, host, hostname, arg_***`, `arg_***` is arguments in the request line, [Nginx variables list](http://nginx.org/en/docs/varindex.html). When `hash_ [...]
+|checks          |optional|Configure the parameters of the health check. For details, refer to [health-check](health-check.md).|
+|retries         |optional|Pass the request to the next upstream using the underlying Nginx retry mechanism, the retry mechanism is enabled by default and set the number of retries according to the number of backend nodes. If `retries` option is explicitly set, it will override the default value.|
+|enable_websocket|optional| enable `websocket`(boolean), default `false`.|
+|timeout|optional| Set the timeout for connection, sending and receiving messages. |
+|desc     |optional|Identifies route names, usage scenarios, and more.|
+
+Config Example:
+
+```shell
+{
+    "id": "1",                  # id
+    "retries": 0,               # retry time
+    "timeout": {                # Set the timeout for connection, sending and receiving messages.
+        "connect":15,
+        "send":15,
+        "read":15,
+    },
+    "enable_websocket": true,
+    "nodes": {"host:80": 100},  # Upstream machine address list, the format is `Address + Port`
+    "type":"roundrobin",        # chash or roundrobin
+    "checks": {},               # Health check parameters
+    "hash_on": "",
+    "key": "",
+    "desc": "hello world",
+}
+```
+
+Example:
+
+```shell
+$ curl http://127.0.0.1:9080/apisix/admin/upstreams/100 -i -X PUT -d '
+> {
+>     "type": "roundrobin",
+>     "nodes": {
+>         "127.0.0.1:80": 1,
+>         "127.0.0.2:80": 2,
+>         "foo.com:80": 3
+>     }
+> }'
+HTTP/1.1 201 Created
+Date: Thu, 26 Dec 2019 04:19:34 GMT
+Content-Type: text/plain
+...
+
+{"node":{"value":{"nodes":{"127.0.0.1:80":1,"foo.com:80":3,"127.0.0.2:80":2},"type":"roundrobin"},"createdIndex":61,"key":"\/apisix\/upstreams\/100","modifiedIndex":61},"action":"set"}
+
+```
+
+> Response Parameters
+
+Return response from etcd currently.
+
+[Back to TOC](#table-of-contents)
+
+## SSL
+
+*API*:/apisix/admin/ssl/{id}
+
+*Description*:SSL.
+
+> Request Methods:
+
+|Method      |Request URI|Request Body|Description        |
+|---------|-------------------------|--|------|
+|GET      |/apisix/admin/ssl/{id}|NULL|Fetch resource|
+|PUT      |/apisix/admin/ssl/{id}|{...}|Create resource by ID|
+|POST     |/apisix/admin/ssl     |{...}|Create resource, and ID is generated by server|
+|DELETE   |/apisix/admin/ssl/{id}|NULL|Remove resource|
+
+> Request Body Parameters:
+
+|Parameter      |Required   |Type |Description        |Example|
+|---------|---------|----|-----------|----|
+|cert|True|Public key|https Public key||
+|key|True|Private key|https Private key||
+|sni|True|Match Rules|https SNI||
+
+Config Example:
+
+```shell
+{
+    "id": "1",      # id
+    "cert": "cert", # Public key
+    "key": "key",   # Private key
+    "sni": "sni"    # https SNI
+}
+```
+
+[Back to TOC](#table-of-contents)
diff --git a/doc/architecture-design.md b/doc/architecture-design.md
index d5e7645..84de71a 100644
--- a/doc/architecture-design.md
+++ b/doc/architecture-design.md
@@ -238,6 +238,8 @@ In addition to the basic complex equalization algorithm selection, APISIX's Upst
 |checks          |optional|Configure the parameters of the health check. For details, refer to [health-check](health-check.md).|
 |retries         |optional|Pass the request to the next upstream using the underlying Nginx retry mechanism, the retry mechanism is enabled by default and set the number of retries according to the number of backend nodes. If `retries` option is explicitly set, it will override the default value.|
 |enable_websocket|optional| enable `websocket`(boolean), default `false`.|
+|timeout|optional| Set the timeout for connection, sending and receiving messages. |
+|desc     |optional|Identifies route names, usage scenarios, and more.|
 
 Create an upstream object use case: