Skip to main content

a6-persona-developer

Who This Is For

You are an API developer responsible for:

  • Designing and configuring API routes on APISIX
  • Choosing and configuring plugins for auth, rate limiting, transformation
  • Testing APIs locally against a development APISIX instance
  • Writing declarative configs for CI/CD pipelines
  • Debugging request flow through the gateway

Getting Started

1. Install and configure

# Install a6
go install github.com/api7/a6/cmd/a6@latest

# Connect to your dev APISIX instance
a6 context create dev --server http://localhost:9180 --api-key edd1c9f034335f136f87ad84b625c8f1

# Verify connection
a6 health

2. Explore available plugins

# List all available plugins
a6 plugin list

# Get the schema for a specific plugin
a6 plugin get key-auth --output json
a6 plugin get limit-count --output json

Building Your First API

Step 1: Create an upstream (your backend)

a6 upstream create -f - <<'EOF'
{
"id": "my-api-backend",
"type": "roundrobin",
"nodes": {
"localhost:3000": 1
}
}
EOF

Step 2: Create a route

a6 route create -f - <<'EOF'
{
"id": "my-api",
"uri": "/api/*",
"methods": ["GET", "POST", "PUT", "DELETE"],
"upstream_id": "my-api-backend"
}
EOF

Step 3: Test it

curl http://localhost:9080/api/hello

Step 4: Add authentication

# Create a consumer with key-auth
a6 consumer create -f - <<'EOF'
{
"username": "dev-user",
"plugins": {
"key-auth": { "key": "my-dev-key" }
}
}
EOF

# Enable key-auth on the route
a6 route update my-api -f - <<'EOF'
{
"plugins": {
"key-auth": {}
}
}
EOF

# Test with the key
curl -H "apikey: my-dev-key" http://localhost:9080/api/hello

Plugin Selection Guide

Use this decision tree to choose the right plugins for your API.

Authentication — "Who is calling?"

NeedPluginKey Feature
Simple API keykey-authHeader/query param key lookup
JWT tokensjwt-authRS256/HS256, token in header/query/cookie
Username/passwordbasic-authHTTP Basic authentication
HMAC signatureshmac-authRequest body signing, replay prevention
OAuth2/OIDCopenid-connectAuth0, Okta, Keycloak integration

Rate Limiting — "How much can they call?"

NeedPluginKey Feature
Fixed window counterlimit-countN requests per time window, Redis cluster support
Leaky bucketlimit-reqSmooth rate limiting, burst allowance

Transformation — "Change request/response"

NeedPluginKey Feature
Rewrite URI/headersproxy-rewriteStrip prefixes, add headers, change host
Modify responseresponse-rewriteChange status code, body, headers
A/B testing, canarytraffic-splitWeighted routing, conditional matching
URL redirectredirectHTTP 301/302/307 redirects

Security — "Block bad traffic"

NeedPluginKey Feature
IP whitelist/blacklistip-restrictionCIDR support, allow/deny lists
CORS headerscorsCross-origin resource sharing
Access controlconsumer-restrictionRestrict by consumer, group, or route

Observability — "What's happening?"

NeedPluginKey Feature
MetricsprometheusLatency, status codes, bandwidth
Distributed tracingzipkin or skywalkingRequest trace correlation
Access logshttp-logger or kafka-loggerStructured log export

Common Patterns

API with auth + rate limiting

a6 route create -f - <<'EOF'
{
"uri": "/api/*",
"upstream_id": "my-api-backend",
"plugins": {
"key-auth": {},
"limit-count": {
"count": 1000,
"time_window": 3600,
"key_type": "var",
"key": "consumer_name",
"rejected_code": 429
}
}
}
EOF

Strip version prefix

a6 route create -f - <<'EOF'
{
"uri": "/v1/*",
"upstream_id": "my-api-backend",
"plugins": {
"proxy-rewrite": {
"regex_uri": ["^/v1/(.*)", "/$1"]
}
}
}
EOF

Add CORS for frontend apps

a6 route update my-api -f - <<'EOF'
{
"plugins": {
"cors": {
"allow_origins": "http://localhost:3001",
"allow_methods": "GET,POST,PUT,DELETE,OPTIONS",
"allow_headers": "Authorization,Content-Type",
"allow_credential": true,
"max_age": 3600
}
}
}
EOF

Use a Service for shared config

When multiple routes share the same upstream and plugins, use a Service:

# Create service with shared config
a6 service create -f - <<'EOF'
{
"id": "my-api-service",
"upstream_id": "my-api-backend",
"plugins": {
"key-auth": {},
"cors": { "allow_origins": "*" }
}
}
EOF

# Routes inherit service config
a6 route create -f - <<'EOF'
{ "uri": "/users/*", "service_id": "my-api-service" }
EOF

a6 route create -f - <<'EOF'
{ "uri": "/orders/*", "service_id": "my-api-service" }
EOF

Local Development Setup

Start APISIX locally with Docker

# If using the a6 repo's docker-compose
make docker-up

# Or manually
docker run -d --name etcd \
-p 2379:2379 \
-e ALLOW_NONE_AUTHENTICATION=yes \
bitnami/etcd:3.5

docker run -d --name apisix \
-p 9080:9080 -p 9180:9180 \
-v $(pwd)/apisix-config.yaml:/usr/local/apisix/conf/config.yaml \
apache/apisix:3.11.0-debian

Seed development data

# Create your dev config file
cat > dev-config.yaml <<'EOF'
upstreams:
- id: local-backend
type: roundrobin
nodes:
"host.docker.internal:3000": 1

consumers:
- username: dev
plugins:
key-auth:
key: dev-key

routes:
- id: api
uri: "/api/*"
upstream_id: local-backend
plugins:
key-auth: {}
EOF

# Apply it
a6 config sync -f dev-config.yaml

Debugging

Trace a request

# See how APISIX routes a specific request
a6 debug trace --uri /api/users --method GET --header "apikey: dev-key"

Stream logs

# Watch APISIX error logs in real-time
a6 debug logs --follow

# Filter by log level
a6 debug logs --follow --level error

Inspect a route's full config

# See the merged config (route + service + plugins)
a6 route get my-api --output json | jq .

CI/CD Integration

Validate in CI

# .github/workflows/apisix.yml
- name: Validate APISIX config
run: a6 config validate -f apisix-config.yaml

Deploy with config sync

- name: Deploy to staging
run: |
a6 context create staging --server ${{ secrets.STAGING_URL }} --api-key ${{ secrets.STAGING_KEY }}
a6 context use staging
a6 config diff -f apisix-config.yaml
a6 config sync -f apisix-config.yaml

Export for other tools

# Export to Kubernetes-friendly format
a6 export --format kubernetes > k8s-apisix.yaml

# Export to standalone YAML
a6 export --format standalone > apisix-standalone.yaml

Decision Framework

SituationAction
New API endpointCreate upstream → create route → add plugins → test
Add auth to existing APICreate consumer → update route with auth plugin → test
Multiple routes, same configCreate a Service → reference via service_id
Need rate limitingChoose limit-count (fixed) or limit-req (smooth) → add to route
Backend URL changeda6 upstream update <id> with new nodes
Debug 502 errorsa6 debug tracea6 upstream health → check backend
Prepare for productiona6 config dump → commit to git → a6 config validate in CI
Test a new plugina6 plugin get <name> for schema → add to a test route → verify

Best Practices

  1. Use declarative configs — store apisix-config.yaml in your repo, use a6 config sync for deployments instead of imperative commands
  2. One service per API — group related routes under a Service for shared config
  3. Auth on every route — never expose unauthenticated routes in production
  4. Rate limit by consumer — use key_type: "var" with key: "consumer_name" for per-user limits
  5. Test locally first — always test against a dev APISIX instance before deploying
  6. Inspect plugin schemas — run a6 plugin get <name> to see required/optional fields before configuring
  7. Use --output json — pipe JSON output to jq for scripting and automation
  8. Keep routes focused — one route per endpoint pattern; avoid overly broad URI matchers like /* in production

This page is generated from a6-persona-developer/SKILL.md in the api7/a6 repository. Browse all skills on the AI Agent Skills page.

API7.ai Logo

The digital world is connected by APIs,
API7.ai exists to make APIs more efficient, reliable, and secure.

Sign up for API7 newsletter

Product

API7 Gateway

SOC2 Type IIISO 27001HIPAAGDPRRed Herring

Copyright © APISEVEN PTE. LTD 2019 – 2026. Apache, Apache APISIX, APISIX, and associated open source project names are trademarks of the Apache Software Foundation