Skip to main content

Share plugins between routes

A service holds what several routes have in common: the backend nodes their requests go to and the plugins every one of them runs. This guide creates the service orders for the orders backend, gives it a request limit, and puts the routes orders-api and orders-v1 on it. At the end, both routes send to the same backend nodes, and one limit counts a client's requests over both of them.

Before you start​

  • This guide starts from orders-api as Route requests to a backend or Share a backend between routes leaves it, with no other plugin. A plugin from another guide that this page does not name can change the answers below; remove it first or work on a copy of the route.
  • A second route for the same backend, orders-v1, taking /api/v1/orders/*. Create it the way Route requests to a backend creates orders-api, with that name and that one path.
  • The address and port of each backend node, 10.0.1.10:8080 and 10.0.1.11:8080 here.
  • The requests below call /orders/42 on orders-api and /api/v1/orders/42 on orders-v1.
  • The host name of your gateway. In the console it is the first part of the Address line on a route's Overview tab, api.example.com in this page's examples; replace it in every request below.
  • The Editor or Environment administrator role in this environment.

Steps​

1. Open a new service and name it​

In the menu, select Services, then New service. Under General, set Name to orders. Set Description to The orders backend, for every route that reaches it, or to any text that says which backend it is.

Leave Hosts under Matching empty. A host listed there applies to every route on the service that lists none of its own, and such a route then answers no other host.

2. Send its requests to your two backend nodes​

Under Target, choose Nodes on this service. Select Add entry for each row.

HostPortWeight
10.0.1.1080801
10.0.1.1180801

If you created the upstream orders in Share a backend between routes, choose Upstream instead and pick it in Upstream.

The Target section of the new-service form, with Nodes on this service chosen and the two backend nodes filled in.

3. Create the service​

Select Create service. The console opens the service. Plugins are added on its Plugins tab, in the next step.

4. Add the limit every route on the service shares​

Open orders under Services, select its Plugins tab, then Add plugin at the top right of the tab. Open the Traffic category, or type limit-count in the search box. Select limit-count, then Configure. Fill in these fields and leave the rest as they are.

FieldValue
Count100
Time window60
Keyremote_addr, the default: one count for each client address
Rejected code, under Behavior429

Select Add plugin at the bottom of the panel. No route is on the service yet, so nobody is limited until the next step. The service is saved like this:

service · as the console saves it
{
"name": "orders",
"desc": "The orders backend, for every route that reaches it",
"upstream": {
"type": "roundrobin",
"nodes": {
"10.0.1.10:8080": 1,
"10.0.1.11:8080": 1
}
},
"plugins": {
"limit-count": {
"count": 100,
"time_window": 60,
"key": "remote_addr",
"rejected_code": 429
}
}
}

5. Put the routes on the service​

Open Routes, open orders-api and select Edit route. Under Target, choose Service and pick orders in Service. Select Save route.

The Target section of the route form, with Service chosen and orders picked.

Choosing a service removes the target the route had itself. From the moment you save, the route's requests go to the service's backend nodes and the service's limit counts them. The route keeps the plugins it carries itself.

Do the same for orders-v1. On a route's Plugins tab, the card Also applied lists the plugins it takes from the service.

The Plugins tab of orders-api, with the Also applied card listing limit-count from the service orders.

Check it​

Send a request to orders-api four times, then one to orders-v1.

curl
curl -i -L 'https://<gateway host>/orders/42'

Each answer from orders-api carries X-RateLimit-Limit: 100, from the service's limit-count, though the route carries no limit of its own. Then send the request to orders-v1.

curl
curl -i -L 'https://<gateway host>/api/v1/orders/42'
Then one to orders-v1
The same client on orders-v1 is counted in the same 100: after four requests to orders-api, its first request to orders-v1 is answered with X-RateLimit-Remaining: 95.

Give one route a limit of its own​

A route can carry the same plugin as its service, with settings of its own. Open orders-v1 under Routes, select its Plugins tab, then Add plugin at the top right of the tab. Choose limit-count as in step 4 and fill it in the same way, with Count at 20. Select Add plugin at the bottom of the panel.

Send the request to orders-v1 three times, then one to orders-api.

On orders-v1
Where orders-v1 carries a limit-count of its own, with a Count of 20, its answers carry X-RateLimit-Limit: 20: the route's copy is used instead of the service's.
Back on orders-api
Its requests are then counted apart from the service's: requests to orders-v1 do not lower the X-RateLimit-Remaining that orders-api answers with.

What to know​

  • Where a route carries the same plugin as its service, the route's copy is used on that route, with its own settings and its own count. The service's other plugins still run on that route.
  • A route on the service that lists no hosts of its own takes the service's hosts. A request for any other host is then answered 404.
  • Behind a load balancer every client arrives under the load balancer's address, so all of them would share the 100. See each client's own address shows the fix, and Limit requests on a route the other ways to count.
  • A service that routes still use cannot be deleted. Move each route to another target first.
G8 dev