## Background

APISIX's current Admin API includes multiple resource types.
Route, upstream, and plugins are undoubtedly the three most important ones.
The routes are the traffic entries, i.e. APISIX dispatches the traffic
based on the matching conditions of the route, e.g. URI, hosts, vars.
The route is also the container for upstreams and plugins. However,
service is an optional resource type for the time being.

## Issues

In fact, based on our operating experience with dozens of companies
over the past few years, the service is a top-level concept rather
than a specific route.

However, the current Service concept does not define the correct
reference relationship, which makes the mapping from API to business a
bit obscure.

In the new design, the Service object in APISIX is a logical
abstraction for a set of upstream services. You can attach policies to
the Service object to manage access to services within.

The Service object helps ensure a more resilient and scalable
architecture. Consider a scenario where there are a few backend
replicas configured as upstream services, in communication with a
frontend application. The Service object encapsulates upstream
services into a single entity so that the frontend application does
not need to interact with upstream services or track backend changes
individually.

## Solution

In the next major version (4.x.x) of APISIX, we will adjust the
relationship between services and routes.
One of the most important changes is that we have to create the
service first, and all routes and upstreams must belong to one
service.
In this way, APISIX configuration will be more meaningful, intuitive,
and reasonable for the business.
Of course, this is a breaking change, but it's not too late to fix it
in the next major version.

### New reference relationship

```
service
`--> upstream (embedded)
`--> route (service_id) --> plugins (embedded)
`--> plugins (embedded)
```

Note that the route can also contain plugins, which will override the
plugins defined on the service, so that specific routes can be
processed specifically, for example, some APIs require authentication.

### Breaking changes in admin API

1. add service_id field in upstream cfg
2. service_id is mandatory for upstream and route
3. plugin_config will not be supported

## Demo

```
# create service first
# the upstream is embedded in the service
curl http://127.0.0.1:9180/apisix/admin/services/1 \
-H 'X-API-KEY: edd1c9f034335f136f87ad84b625c8f1' -X PUT -d '{
    "upstream": {
        "nodes":[
            {
                "host":"httpbin.org",
                "port":80,
                "weight":1
            },
            {
                "host":"postman-echo.com",
                "port":80,
                "weight":1
            }
        ],
        "type":"roundrobin"
    }
}'

# create route within the service
# note that the service_id is mandatory!
curl http://127.0.0.1:9180/apisix/admin/routes/1 \
-H 'X-API-KEY: edd1c9f034335f136f87ad84b625c8f1' -X PUT -d '{
    "uri":"/get",
    "service_id": 1
}'

# test
curl http://127.0.0.1:9080/get -v
```

Reply via email to