1. Background

The new API design for the Admin API, which no longer relies on the etcd
data format. The current API design of Admin API, is no design, we use the
HTTP RESTful API of etcd v2 directly. It is not good for API Gateway case.
Here are some reasons:
1. Not support paging when fetching object list
2. Not support filters when fetching object list
3. The APISIX users need the route data, they don't care how it is stored.

1.1 Problem to be solved

The Admin API use the HTTP API of etcd v2 REST. It has been deprecated by
etcd. As APISIX grows, users expect the Admin API to be more powerful and
clear:
1. We need a more standardized and easy-to-understand Admin API interface.
2. Remove strong dependency on etcd data format.
3. Support pagination, search and other functions, making it easier for
users to find the APISIX data they need.

1.2 The benefits of solving this problem

When fetching data of different types:
1. Support paging to fetch data to avoid the response body being too large
due to a large number of certain types of data.
2. Remove the outermost nesting to make the response data structure simpler.
3. Support filtering by name, label, etc., allows the user to find the data
content that users are interested in quickly.


2. How to solve the problem

2.1 List of URIs that need to be updated

2.1.1 For SSL objects, the plural form should be used

API design: /apisix/admin/ssls/{id}

examples of put a ssl object:

```
curl http://127.0.0.1:9080/apisix/admin/ssls/1 -X PUT -d {
    "cert": ... ...,
    "key": ... ...,
    "snis": ["foo.com"],
}
```

examples of fetch ssl objects

```
curl http://127.0.0.1:9080/apisix/admin/ssls

{
    "count": 2,
    "list": [
      {...},
      {...},
    ]
}
```

2.1.2 For proto objects, the plural form should be used

API design: /apisix/admin/protos/{id}

examples of put a proto object:

```
curl http://127.0.0.1:9080/apisix/admin/protos/1 -X PUT -d {
    ... ...
}

```

examples of fetch proto objects:

```
curl http://127.0.0.1:9080/apisix/admin/protos

{
    "count": 2,
    "list": [
      {...},
      {...},
    ]
}
```

2.2 Response body format

2.2.1 Remove action field in response body, it is useless

2.2.2 Make the response body format simpler for list of object

fetch object, return the object information directly, examples:

```
curl  http://127.0.0.1:9080/apisix/admin/routes/12
{
    "key": "/apisix/routes/12",
    "createdIndex": 1655,
    "value": {
      "id": "12",
      "uri": "/hello",
      "create_time": 1653964280,
      "status": 1,
      "upstream": {
        "type": "roundrobin",
        "pass_host": "pass",
        "hash_on": "vars",
        "nodes": {
          "127.0.0.1:1980": 1
        },
        "scheme": "http"
      },
      "update_time": 1654519342
    },
    "modifiedIndex": 2289
}
```


fetch object list, return `count` and `list` field. Each item in the list
is the object(eg: route, service or upstream), examples:

```
curl  http://127.0.0.1:9080/apisix/admin/routes -H 'X-API-KEY:
edd1c9f034335f136f87ad84b625c8f1'
{
  "count": 2,
  "list": [
    {
      "createdIndex": 1655,
      "key": "/apisix/routes/1",
      "value": {
        "id": "1",
        "priority": 0,
        "uri": "/hello",
        "create_time": 1649143475,
        "upstream": {
          "type": "roundrobin",
          "pass_host": "pass",
          "hash_on": "vars",
          "nodes": {
            "127.0.0.1:1980": 1
          },
          "scheme": "http"
        },
        "update_time": 1653963881,
        "status": 1
      },
      "modifiedIndex": 2289
    },
    {
      "createdIndex": 2290,
      "key": "/apisix/routes/12",
      "value": {
        "id": "12",
        "priority": 0,
        "uri": "/hello",
        "create_time": 1653964280,
        "status": 1,
        "upstream": {
          "type": "roundrobin",
          "pass_host": "pass",
          "hash_on": "vars",
          "nodes": {
            "127.0.0.1:1980": 1
          },
          "scheme": "http"
        },
        "update_time": 1654519342
      },
      "modifiedIndex": 2325
    }
  ]
}
```

2.3 New feature for all Admin APIs

2.3.1 Supports paging to get a list of objects such as route

Avoid being unable to return all objects in a single request because there
are too many objects of a specific type.

More friendly to web applications. For administrators, the number of list
displayed on a single page is usually between 20 and 50.

- Feature: support new query arguments:
  - page: the current page number, the default value is 1, and the valid
value is a positive integer.
  - page_size: the page size, no paging by default, the valid value should
be from 10 to 500.

examples:

```
curl http://xxxx/apisix/admin/routes?page=1&page_size=10

{
  "count": 1,
  "list": [
    {
      ... ...
    }
  ]
}
```

- Object list that need to support paging:
routes
services
upstreams
consumers
schema
ssls
protos
global_rules
stream_routes
plugin_metadata
plugin_configs

Note:
The paging will be done on APISIX, not lua-resty-etcd.
APISIX will do some of the following:
1. get all routes data from memory (instead of querying from etcd)
2. sort all routes by update_time, the larger the update_time, the higher
the ranking(sorted by update_time in descending order)
3. get the corresponding routes according to the paging parameter
4. if there are no paging parameters, follow the default values in the
requirements.
5. return the paging parameters of the query in the response.


2.2 Supports filter when get a list of objects such as route

- Feature: filter fields supported by all objects
  - name: If the object's name contains the name string specified by the
user, the matching result is true; otherwise the matching result is false.
  - label: If the object's label is the same as the label specified by the
user, the matching result is true; otherwise the matching result is false.
- Feature: additional filter fields supported by the Route object
  - uri: If the route's uri contains the uri string specified by the user,
the matching result is true; otherwise the matching result is false.

When the user has enabled multiple filter fields, there is an and
relationship between the different fields. For example, the following
example is expected to return a list of routes: the route's name contains
the string "test", and the URI contains the string "foo". There is no
restriction on the route label because the input is an empty string.

examples:

```
curl http://xxxx/apisix/admin/routes?name=test&uri=foo&label=

{
  "count": 1,
  "list": [
    {...}
  ]
}
```

- Object list that need to support paging:
routes
services
upstreams
consumers
schema
ssls
protos
global_rules
stream_routes
plugin_metadata
plugin_configs

*ZhengSong Tu*
My GitHub: https://github.com/tzssangglass
Apache APISIX: https://github.com/apache/apisix

Reply via email to