Tutorial: Proxying and Managing API Requests via Plugins
A hands-on tutorial that walks you through proxying API requests, adding authentication with Key Auth, and enabling rate limiting with the Limit Count plugin.
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:
- 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 Proxy) |
| 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:
- GETadc sync -f adc.yamlStep 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.
- 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: {}adc sync declaratively replaces all resources, so the file must contain the full desired state — keep the upstream and route blocks from Step 1 alongside the new plugins block.
adc sync -f adc.yamlTest 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:
- 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-keyadc sync -f adc.yamlTest 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.
- 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: localadc sync -f adc.yamlTest 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"
doneExpected output:
Request 1: HTTP 200
Request 2: HTTP 200
Request 3: HTTP 200
Request 4: HTTP 200
Request 5: HTTP 200
Request 6: HTTP 429Next 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.