Tutorial: Proxying and Managing API Requests via Plugins
This tutorial builds on the Quick Start and walks you through a realistic scenario: proxying API requests through API7 Gateway while applying authentication and rate limiting using plugins.
What you will learn:
- Create a service and route for a backend API
- Add the
key-authplugin to require API key authentication - Create a consumer with credentials
- Add the
limit-countplugin to enforce rate limits - Test the complete setup
Time to complete: ~15 minutes
Prerequisites: A running API7 Gateway instance. If you have not set one up yet, complete the Quick Start first. If you want to follow the Admin API examples, obtain a token from the Dashboard before you begin.
Step 1: Create a Service and Route
Create a service that proxies to the httpbin.org service. You can add it manually or import an OpenAPI specification to create the service and its routes.
- Dashboard
- Admin API
- ADC
- In the Dashboard sidebar, navigate to the default gateway group and click Services.
- Click Add Service, then Add Manually.
- Configure the service:
| Field | Value |
|---|---|
| Name | demo-api |
| Service Type | HTTP(Layer 7 protocol) |
| Upstream Scheme | HTTP |
| How to find the upstream | Use Nodes |
- Click Add Node and configure:
| Field | Value |
|---|---|
| Host | httpbin.org |
| Port | 80 |
| Weight | 100 |
- Click Add to create the service.
- Click the
demo-apiservice, then click Add Route. - Configure the route:
| Field | Value |
|---|---|
| Name | get-request |
| Path | /get |
| Methods | GET |
- Click Add.
# Create the service with the upstream
curl -k "https://localhost:7443/apisix/admin/services/demo-api?gateway_group_id={gateway_group_id}" -X PUT \
-H "X-API-KEY: ${API_KEY}" \
-H "Content-Type: application/json" \
-d '{
"name": "demo-api",
"upstream": {
"type": "roundrobin",
"scheme": "http",
"nodes": [
{ "host": "httpbin.org", "port": 80, "weight": 100 }
]
}
}'
# Create the route under that service
curl -k "https://localhost:7443/apisix/admin/routes/get-request?gateway_group_id={gateway_group_id}" -X PUT \
-H "X-API-KEY: ${API_KEY}" \
-H "Content-Type: application/json" \
-d '{
"name": "get-request",
"service_id": "demo-api",
"paths": ["/get"],
"methods": ["GET"]
}'
If you are not running locally, replace localhost with your Admin API host. The -k flag is required if the Admin API uses a self-signed TLS certificate. Replace {gateway_group_id} with the gateway group ID — use default for the gateway group created by the quickstart, or copy the ID from the Gateway Groups page in the Dashboard.
services:
- name: demo-api
upstream:
name: default
scheme: http
nodes:
- host: httpbin.org
port: 80
weight: 100
routes:
- name: get-request
uris:
- /get
methods:
- GET
labels:
docs-example: demo-api
Preview the changes owned by this example and confirm that the diff contains no unintended updates or deletions:
adc diff -f adc.yaml \
--include-resource-type service \
--label-selector docs-example=demo-api
Synchronize the reviewed configuration:
adc sync -f adc.yaml \
--include-resource-type service \
--label-selector docs-example=demo-api
Import OpenAPI Specification
The Dashboard can create a service and its routes from an OpenAPI 3.0 or 3.1 specification. For example, save the following as openapi.yaml:
openapi: 3.0.0
info:
title: demo-api
version: 1.0.0
paths:
/get:
get:
operationId: get-request
responses:
"200":
description: Successful response
In the Dashboard:
- In the default gateway group, navigate to Services and click Add Service.
- Select Import OpenAPI and upload
openapi.yamlin the OpenAPI Specification field. - Keep Service Type set to
HTTP(Layer 7 protocol), Upstream Scheme set toHTTP, and How to find the upstream set toUse Nodes. - Click Add Node and enter the upstream host, port, and weight. For this tutorial, use
httpbin.org,80, and100. - Click Next to review the service and routes created from the specification, then click Add.
The imported paths become routes in the service. Continue with Step 2 to verify the /get route, then configure the plugins on the imported service.
Step 2: Verify the Proxy
Test the route to validate the basic setup before adding plugins:
curl -i "http://localhost:9080/get"
You should receive a 200 OK response with the HTTPBin response body, confirming the proxy works.
Step 3: Enable Key Auth Plugin
The key-auth plugin requires consumers to provide a valid API key.
- Dashboard
- Admin API
- ADC
- In the default gateway group, navigate to Services and click the
demo-apiservice. - Click Plugins, then Enable Plugin.
- Search for
key-authand enable it. - Use the default configuration and click Submit.
# Replace the service definition with key-auth enabled
curl -k "https://localhost:7443/apisix/admin/services/demo-api?gateway_group_id={gateway_group_id}" -X PUT \
-H "X-API-KEY: ${API_KEY}" \
-H "Content-Type: application/json" \
-d '{
"name": "demo-api",
"upstream": {
"type": "roundrobin",
"scheme": "http",
"nodes": [
{ "host": "httpbin.org", "port": 80, "weight": 100 }
]
},
"plugins": {
"key-auth": {}
}
}'
services:
- name: demo-api
upstream:
name: default
scheme: http
nodes:
- host: httpbin.org
port: 80
weight: 100
routes:
- name: get-request
uris:
- /get
methods:
- GET
plugins:
key-auth: {}
labels:
docs-example: demo-api
This sync keeps services labeled for this example. Retain the upstream and route from the earlier step in this file. Other services stay in place. Preview the diff before synchronizing:
adc diff -f adc.yaml \
--include-resource-type service \
--label-selector docs-example=demo-api
Synchronize the reviewed configuration:
adc sync -f adc.yaml \
--include-resource-type service \
--label-selector docs-example=demo-api
Test Without a Key
curl -i "http://localhost:9080/get"
Expected response:
HTTP/1.1 401 Unauthorized
{"message":"Missing API key in request"}
Step 4: Create a Consumer
Create a consumer with an API key credential:
- Dashboard
- Admin API
- ADC
- In the Dashboard sidebar, navigate to Consumers, then click Create Consumer.
- Configure the consumer:
| Field | Value |
|---|---|
| Name | test-consumer |
- Click Submit to create the consumer.
- Click the
test-consumerconsumer to open it, then select the Credentials tab. - Click Create Credential and select
key-authas the type. - Configure the credential:
| Field | Value |
|---|---|
| Name | test-consumer-key |
| Key | my-secret-api-key |
- Click Submit.
# Create the consumer
curl -k "https://localhost:7443/apisix/admin/consumers/test-consumer?gateway_group_id={gateway_group_id}" -X PUT \
-H "X-API-KEY: ${API_KEY}" \
-H "Content-Type: application/json" \
-d '{
"username": "test-consumer"
}'
# Add the key-auth credential to the consumer
curl -k "https://localhost:7443/apisix/admin/consumers/test-consumer/credentials/test-consumer-key?gateway_group_id={gateway_group_id}" -X PUT \
-H "X-API-KEY: ${API_KEY}" \
-H "Content-Type: application/json" \
-d '{
"name": "test-consumer-key",
"plugins": {
"key-auth": {
"key": "my-secret-api-key"
}
}
}'
On API7 Enterprise, authentication keys live on a credential resource attached to the consumer, not inline on the consumer itself. The Admin API rejects inline key-auth plugin configuration on a consumer with the error adding new key-auth plugin in consumer is not allowed, please use it in credential.
consumers:
- username: test-consumer
credentials:
- name: test-consumer-key
type: key-auth
config:
key: my-secret-api-key
labels:
docs-example: test-consumer
Preview the changes owned by this example and confirm that the diff contains no unintended updates or deletions:
adc diff -f adc.yaml \
--include-resource-type consumer \
--label-selector docs-example=test-consumer
Synchronize the reviewed configuration:
adc sync -f adc.yaml \
--include-resource-type consumer \
--label-selector docs-example=test-consumer
Test With the API Key
curl -i "http://localhost:9080/get" -H "apikey: my-secret-api-key"
Expected response: 200 OK.
Step 5: Enable Rate Limiting
Add the limit-count plugin to restrict the number of requests a consumer can make.
- Dashboard
- Admin API
- ADC
- In the default gateway group, navigate to Services and click the
demo-apiservice. - Click Plugins, then Enable Plugin.
- Search for
limit-countand configure it:
{
"count": 5,
"time_window": 60,
"rejected_code": 429,
"key_type": "var",
"key": "consumer_name",
"policy": "local"
}
- Click Submit.
# Replace the service definition with key-auth and limit-count
curl -k "https://localhost:7443/apisix/admin/services/demo-api?gateway_group_id={gateway_group_id}" -X PUT \
-H "X-API-KEY: ${API_KEY}" \
-H "Content-Type: application/json" \
-d '{
"name": "demo-api",
"upstream": {
"type": "roundrobin",
"scheme": "http",
"nodes": [
{ "host": "httpbin.org", "port": 80, "weight": 100 }
]
},
"plugins": {
"key-auth": {},
"limit-count": {
"count": 5,
"time_window": 60,
"rejected_code": 429,
"key_type": "var",
"key": "consumer_name",
"policy": "local"
}
}
}'
services:
- name: demo-api
upstream:
name: default
scheme: http
nodes:
- host: httpbin.org
port: 80
weight: 100
routes:
- name: get-request
uris:
- /get
methods:
- GET
plugins:
key-auth: {}
limit-count:
count: 5
time_window: 60
rejected_code: 429
key_type: var
key: consumer_name
policy: local
labels:
docs-example: demo-api
Preview the changes owned by this example and confirm that the diff contains no unintended updates or deletions:
adc diff -f adc.yaml \
--include-resource-type service \
--label-selector docs-example=demo-api
Synchronize the reviewed configuration:
adc sync -f adc.yaml \
--include-resource-type service \
--label-selector docs-example=demo-api
Test the Rate Limit
Send multiple requests in quick succession:
for i in $(seq 1 6); do
echo "Request $i:"
curl -s -o /dev/null -w "HTTP %{http_code}\n" \
http://localhost:9080/get -H "apikey: my-secret-api-key"
done
Expected output:
Request 1: HTTP 200
Request 2: HTTP 200
Request 3: HTTP 200
Request 4: HTTP 200
Request 5: HTTP 200
Request 6: HTTP 429
Next Steps
- Learn More About API7 Products and APISIX: Understand the full API7 product ecosystem.
- Configure the Control Plane: Fine-tune your control plane for production.
- Monitor Gateway Metrics: Monitor your gateway traffic.