Skip to content

docs: migrate traffic recipes to service model#9

Open
guoqqqi wants to merge 3 commits intomasterfrom
codex/recipe-service-model-traffic
Open

docs: migrate traffic recipes to service model#9
guoqqqi wants to merge 3 commits intomasterfrom
codex/recipe-service-model-traffic

Conversation

@guoqqqi
Copy link
Copy Markdown
Contributor

@guoqqqi guoqqqi commented Apr 28, 2026

Summary

  • Migrate blue-green, canary, and API versioning recipes away from standalone a7 upstream resources.
  • Use a7 service create plus route service_id for default routing.
  • Keep traffic-split examples only where needed for weighted or header-based routing, using inline plugin upstreams for canary targets.
  • Update Config Sync examples to use services and route paths / service_id.

Validation

  • make validate-skills
  • make test-skills
  • git diff --check

Summary by CodeRabbit

  • Documentation
    • Updated API versioning recipe documentation with revised examples for command sequences, URI path versioning, header-based routing, gradual rollout, deprecation strategies, and configuration sync patterns.
    • Updated blue-green deployment recipe with refreshed step-by-step flow, traffic management testing, declarative configuration examples, and troubleshooting guidance.
    • Updated canary deployment recipe with streamlined progression instructions, new routing configuration patterns, promotion and rollback workflows, and improved header-based canary guidance.

Copilot AI review requested due to automatic review settings April 28, 2026 16:42
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Apr 28, 2026

📝 Walkthrough

Walkthrough

Updates three API7 EE skill documentation files to migrate from upstream-centric to service-centric routing models. Changes include command examples, route configuration schemas, and example payloads across API versioning, blue-green deployment, and canary deployment recipes.

Changes

Cohort / File(s) Summary
API7 EE Recipe Documentation – API Versioning
skills/a7-recipe-api-versioning/SKILL.md
Replaces upstream_id/upstream references with service_id/service in URI path and header-based versioning examples. Updates command metadata from a7 upstream create to a7 service create, route definitions from uri+upstream_id to paths+service_id, and Config Sync schema to include versioned services block. Revises gradual rollout and deprecation examples to align with new structure.
API7 EE Recipe Documentation – Blue-Green Deployment
skills/a7-recipe-blue-green/SKILL.md
Shifts blue-green routing from upstream_id swapping to service-backed model with service_id. Updates step-by-step flow to inspect/update routes via service_id, changes green testing from traffic-split to header-based injection with inline upstreams, and converts declarative config from upstreams to services schema. Adjusts verification commands and troubleshooting guidance to reference service IDs.
API7 EE Recipe Documentation – Canary Deployment
skills/a7-recipe-canary/SKILL.md
Converts canary mechanics from upstream_id-centric to service_id-centric routing. Creates stable-service/canary-service with routes using service_id and inline upstream definitions for weighted traffic. Simplifies progression flow, updates bash script for route updates with service_id, and refactors Config Sync YAML from upstreams/uri to services/paths. Removes cookie-based canary guidance and updates header-based canary match variables.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

  • docs: align mTLS skill with service model #7: Directly related migration from upstream-centric fields and commands (a7 upstream, upstream_id, uri) to service-centric model (a7 service, service_id, paths) across skill documentation.
🚥 Pre-merge checks | ✅ 6
✅ Passed checks (6 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'docs: migrate traffic recipes to service model' directly and clearly summarizes the main change: migrating documentation examples for traffic management recipes from upstream-based to service-based routing patterns.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
E2e Test Quality Review ✅ Passed Documentation-only PR updating recipe guides from upstream to service model; E2E test quality criteria not applicable to documentation changes.
Security Check ✅ Passed Documentation PR reviewed for sensitive data exposure, insecure configurations, and security anti-patterns; no hardcoded credentials, API keys, tokens, or insecure practices identified in examples.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch codex/recipe-service-model-traffic

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share
Review rate limit: 0/1 reviews remaining, refill in 60 minutes.

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Migrates the recipe documentation for canary, blue-green, and API versioning to the service-backed model (using a7 service create + route service_id) instead of standalone upstream resources, while keeping traffic-split only for weighted/header-based overrides.

Changes:

  • Update canary and blue-green recipes to create services and bind routes via service_id.
  • Update API versioning recipe to model “one service per version” and use paths + service_id.
  • Refresh Config Sync YAML examples to use services and route paths/service_id.

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 1 comment.

File Description
skills/a7-recipe-canary/SKILL.md Converts canary workflow to service-backed routing; uses inline upstream only inside traffic-split; updates Config Sync example.
skills/a7-recipe-blue-green/SKILL.md Reworks blue/green recipe around swapping route service_id; keeps header-based testing via traffic-split inline upstream.
skills/a7-recipe-api-versioning/SKILL.md Refactors versioning patterns to “service per version” with service-backed routes and updated Config Sync example.
Comments suppressed due to low confidence (1)

skills/a7-recipe-canary/SKILL.md:19

  • metadata.a7_commands is missing a7 route list, but the troubleshooting section later instructs running a7 route list --service-id stable-service. Please add a7 route list to the command list so the skill metadata matches the documented workflow.
  a7_commands:
    - a7 service create
    - a7 service update
    - a7 route create
    - a7 route update
    - a7 route get
    - a7 config sync

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

a7 route update route-v1 -g production -f - <<'EOF'
{
"service_id": "service-v1",
"plugins": {
Copy link

Copilot AI Apr 28, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In “Gradual Version Rollout”, the route-v1 route was created earlier with the proxy-rewrite plugin to strip the /v1 prefix. This update payload sets plugins to only traffic-split, which can inadvertently drop proxy-rewrite depending on how route updates are applied. Consider including both proxy-rewrite and traffic-split in the update payload (or explicitly documenting that the update preserves existing plugins) so the rewrite behavior remains intact during rollout.

Suggested change
"plugins": {
"plugins": {
"proxy-rewrite": {
"regex_uri": ["^/v1/(.*)", "/$1"]
},

Copilot uses AI. Check for mistakes.
Copilot AI review requested due to automatic review settings April 29, 2026 13:54
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🧹 Nitpick comments (2)
skills/a7-recipe-blue-green/SKILL.md (1)

244-251: Minor: make verification commands gateway-group explicit.

In the troubleshooting table you suggest:

  • Verify with a7 route get api -o json

Other examples in the same file consistently use --gateway-group default. For consistency (and to avoid “route not found” confusion), consider including --gateway-group default in that troubleshooting row as well.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@skills/a7-recipe-blue-green/SKILL.md` around lines 244 - 251, Update the
troubleshooting table row that currently shows the command "a7 route get api -o
json" to include the gateway group flag so it reads "a7 route get api
--gateway-group default -o json"; specifically edit the table cell containing
"Verify with `a7 route get api -o json` and retry after propagation" to include
"--gateway-group default" to match other examples and avoid "route not found"
confusion.
skills/a7-recipe-canary/SKILL.md (1)

181-213: Minor: add an explicit header example for x-canary: true.

The “Header-Based Canary” section explains the match condition and says only requests with x-canary: true go to canary, but it doesn’t show a curl example to validate the exact header name/value (and whether true is treated as a string).

Consider adding a short curl snippet similar to the blue-green recipe’s header test, e.g. hitting /api/* with -H 'x-canary: true'.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@skills/a7-recipe-canary/SKILL.md` around lines 181 - 213, Add a short curl
example to the "Header-Based Canary" section demonstrating the exact header name
and value used for the match (use the header key x-canary and the value true) so
readers can validate whether true is treated as a string; place a one-line curl
snippet similar to the blue-green recipe's header test (targeting the /api/*
path and using -H 'x-canary: true') immediately after the explanation that "Only
requests with `x-canary: true` go to canary."
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@skills/a7-recipe-api-versioning/SKILL.md`:
- Around line 195-238: The YAML example includes an unsupported top-level
gateway_group field; remove gateway_group from the config file and document that
the gateway group must be provided via the CLI flag (e.g., use "a7 config sync
-g production -f <file>") instead; update the example YAML to omit gateway_group
and, if applicable, adjust any references to the ConfigFile struct or parsing
code that might expect gateway_group so the ConfigFile struct remains the single
source of truth for file-based fields.

In `@skills/a7-recipe-canary/SKILL.md`:
- Around line 262-298: Remove the top-level gateway_group key from the Config
Sync YAML in SKILL.md so the example matches the ConfigFile schema; instead rely
on providing the gateway group via CLI/application context (e.g., using the a7
config sync -g/--gateway-group flag). Locate the YAML block containing
gateway_group: default and delete that line, leaving the rest of the
route/service definitions intact; ensure no other references to gateway_group
remain in the example.

---

Nitpick comments:
In `@skills/a7-recipe-blue-green/SKILL.md`:
- Around line 244-251: Update the troubleshooting table row that currently shows
the command "a7 route get api -o json" to include the gateway group flag so it
reads "a7 route get api --gateway-group default -o json"; specifically edit the
table cell containing "Verify with `a7 route get api -o json` and retry after
propagation" to include "--gateway-group default" to match other examples and
avoid "route not found" confusion.

In `@skills/a7-recipe-canary/SKILL.md`:
- Around line 181-213: Add a short curl example to the "Header-Based Canary"
section demonstrating the exact header name and value used for the match (use
the header key x-canary and the value true) so readers can validate whether true
is treated as a string; place a one-line curl snippet similar to the blue-green
recipe's header test (targeting the /api/* path and using -H 'x-canary: true')
immediately after the explanation that "Only requests with `x-canary: true` go
to canary."
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 10ff3b51-a046-4206-843c-53d60102e795

📥 Commits

Reviewing files that changed from the base of the PR and between 024dacd and 8d0720f.

📒 Files selected for processing (3)
  • skills/a7-recipe-api-versioning/SKILL.md
  • skills/a7-recipe-blue-green/SKILL.md
  • skills/a7-recipe-canary/SKILL.md

Comment on lines 195 to 238
```yaml
# versioning-config.yaml
gateway_groups:
- id: production
upstreams:
- id: v1-backend
nodes: { "v1-svc:80": 1 }
- id: v2-backend
nodes: { "v2-svc:80": 1 }
routes:
- id: service-v1
uri: "/v1/*"
upstream_id: v1-backend
plugins:
proxy-rewrite:
regex_uri: ["^/v1/(.*)", "/$1"]
- id: service-v2
uri: "/v2/*"
upstream_id: v2-backend
plugins:
proxy-rewrite:
regex_uri: ["^/v2/(.*)", "/$1"]
version: "1"
gateway_group: production
services:
- id: service-v1
name: Service V1
upstream:
type: roundrobin
nodes:
- host: v1-svc
port: 80
weight: 1
- id: service-v2
name: Service V2
upstream:
type: roundrobin
nodes:
- host: v2-svc
port: 80
weight: 1
routes:
- id: service-v1-route
name: service-v1-route
paths:
- /v1/*
service_id: service-v1
plugins:
proxy-rewrite:
regex_uri: ["^/v1/(.*)", "/$1"]
- id: service-v2-route
name: service-v2-route
paths:
- /v2/*
service_id: service-v2
plugins:
proxy-rewrite:
regex_uri: ["^/v2/(.*)", "/$1"]
```

Apply the configuration:

```bash
a7 config sync -g production -f versioning-config.yaml
```
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

fd -t f -e "*.go" | head -20

Repository: api7/a7

Length of output: 33


🏁 Script executed:

git ls-files | grep -E "\.go$" | head -30

Repository: api7/a7

Length of output: 842


🏁 Script executed:

find . -name "*.go" -type f | head -30

Repository: api7/a7

Length of output: 902


🏁 Script executed:

cat -n pkg/api/types_config.go

Repository: api7/a7

Length of output: 1794


🏁 Script executed:

cat -n internal/config/config.go

Repository: api7/a7

Length of output: 11567


🏁 Script executed:

sed -n '195,238p' skills/a7-recipe-api-versioning/SKILL.md

Repository: api7/a7

Length of output: 876


Remove top-level gateway_group from Config Sync YAML.

The example includes gateway_group: production in the YAML, but the ConfigFile struct does not support this field. The gateway group should only be specified via the CLI flag (-g production), not in the configuration file.

Suggested change
 ```yaml
 version: "1"
-gateway_group: production
 services:
   - id: service-v1
     name: Service V1
     upstream:
       type: roundrobin
       nodes:
         - host: v1-svc
           port: 80
           weight: 1
   - id: service-v2
     name: Service V2
     upstream:
       type: roundrobin
       nodes:
         - host: v2-svc
           port: 80
           weight: 1
 routes:
   - id: service-v1-route
     name: service-v1-route
     paths:
       - /v1/*
     service_id: service-v1
     plugins:
       proxy-rewrite:
         regex_uri: ["^/v1/(.*)", "/$1"]
   - id: service-v2-route
     name: service-v2-route
     paths:
       - /v2/*
     service_id: service-v2
     plugins:
       proxy-rewrite:
         regex_uri: ["^/v2/(.*)", "/$1"]
</details>

<!-- suggestion_start -->

<details>
<summary>📝 Committable suggestion</summary>

> ‼️ **IMPORTANT**
> Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

```suggestion

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@skills/a7-recipe-api-versioning/SKILL.md` around lines 195 - 238, The YAML
example includes an unsupported top-level gateway_group field; remove
gateway_group from the config file and document that the gateway group must be
provided via the CLI flag (e.g., use "a7 config sync -g production -f <file>")
instead; update the example YAML to omit gateway_group and, if applicable,
adjust any references to the ConfigFile struct or parsing code that might expect
gateway_group so the ConfigFile struct remains the single source of truth for
file-based fields.

Comment on lines 262 to 298
```yaml
version: "1"
gateway_group: default
upstreams:
- id: stable
type: roundrobin
nodes:
"stable-v1:8080": 1
- id: canary
type: roundrobin
nodes:
"canary-v2:8080": 1
services:
- id: stable-service
name: stable-service
upstream:
type: roundrobin
nodes:
- host: stable-v1
port: 8080
weight: 1
- id: canary-service
name: canary-service
upstream:
type: roundrobin
nodes:
- host: canary-v2
port: 8080
weight: 1
routes:
- id: api
uri: /api/*
name: api
paths:
- /api/*
service_id: stable-service
plugins:
traffic-split:
rules:
- weighted_upstreams:
- upstream_id: canary
- upstream:
type: roundrobin
nodes:
"canary-v2:8080": 1
weight: 10
- weight: 90
upstream_id: stable
```
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Description: Verify whether config sync YAML supports a top-level gateway_group key.
set -euo pipefail
rg -n --no-heading "config sync" pkg/cmd | head -n 200
rg -n --no-heading "type ConfigFile|ConfigFile struct" pkg/api | head -n 200
rg -n --no-heading "gateway[-_ ]group" pkg/cmd pkg/api | head -n 200

Repository: api7/a7

Length of output: 33


🏁 Script executed:

#!/bin/bash
# Explore repository structure to understand layout
git ls-files | grep -E "(cmd|api)" | head -30
echo "---"
# Look for config sync related files
git ls-files | grep -i config | head -20
echo "---"
# Look for ConfigFile struct definition
rg -l "ConfigFile" --type go 2>/dev/null | head -20

Repository: api7/a7

Length of output: 1698


🏁 Script executed:

#!/bin/bash
# Read ConfigFile struct definition
echo "=== ConfigFile struct ==="
cat -n pkg/api/types_config.go | grep -A 50 "type ConfigFile"

echo ""
echo "=== Config sync implementation ==="
head -100 pkg/cmd/config/sync/sync.go

echo ""
echo "=== Check if gateway_group appears in config validation ==="
rg "gateway_group|gateway-group" pkg/cmd/config/validate/validate.go

Repository: api7/a7

Length of output: 4024


Remove top-level gateway_group from Config Sync YAML.

The "Config Sync" example includes gateway_group: default at the top level. This field is not part of the ConfigFile struct; the gateway group must be provided via the CLI or application config context (typically via -g/--gateway-group flag to a7 config sync).

Remove the gateway_group key from the example YAML to match the actual API schema.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@skills/a7-recipe-canary/SKILL.md` around lines 262 - 298, Remove the
top-level gateway_group key from the Config Sync YAML in SKILL.md so the example
matches the ConfigFile schema; instead rely on providing the gateway group via
CLI/application context (e.g., using the a7 config sync -g/--gateway-group
flag). Locate the YAML block containing gateway_group: default and delete that
line, leaving the rest of the route/service definitions intact; ensure no other
references to gateway_group remain in the example.

Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 3 out of 3 changed files in this pull request and generated 3 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

| Canary not receiving traffic | Match condition never true | Check header/cookie name and `a7 route get` output |
| Rollback not instant | Config has not propagated yet | Verify with `a7 route get` and retry after propagation |
| 502 from canary | Canary backend is unhealthy | Check canary service health before increasing weight |
| Weight changes have no effect | Editing wrong route | Verify route ID with `a7 route list --service-id stable-service` |
Copy link

Copilot AI Apr 29, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The troubleshooting command a7 route list --service-id stable-service will fail when the user doesn’t have a default gateway group set in their context (the CLI requires --gateway-group/-g or a configured default). Consider adding --gateway-group default (or mentioning that a default context gateway group must be set) to make the copy/paste instruction reliably runnable.

Suggested change
| Weight changes have no effect | Editing wrong route | Verify route ID with `a7 route list --service-id stable-service` |
| Weight changes have no effect | Editing wrong route | Verify route ID with `a7 route list --gateway-group default --service-id stable-service` |

Copilot uses AI. Check for mistakes.
| Can't rollback | Lost track of previous upstream | Always record current state before switching |
| Connections drop during switch | Long-running requests on old upstream | API7 EE handles in-flight requests gracefully; existing connections complete |
| 502 after switch | New environment not ready | Test health endpoint before switching; roll back if needed |
| Traffic still going to old env | Route update has not propagated yet | Verify with `a7 route get api -o json` and retry after propagation |
Copy link

Copilot AI Apr 29, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The troubleshooting suggestion a7 route get api -o json omits --gateway-group/-g, but a7 route get errors if no default gateway group is set in the user's context. Consider including --gateway-group default (or explicitly stating that a default gateway group must be configured) so the command works when copied as-is.

Suggested change
| Traffic still going to old env | Route update has not propagated yet | Verify with `a7 route get api -o json` and retry after propagation |
| Traffic still going to old env | Route update has not propagated yet | Verify with `a7 route get api --gateway-group "$GROUP" -o json` and retry after propagation |

Copilot uses AI. Check for mistakes.
Comment on lines +305 to +306
| Canary not receiving traffic | Match condition never true | Check header/cookie name and `a7 route get` output |
| Rollback not instant | Config has not propagated yet | Verify with `a7 route get` and retry after propagation |
Copy link

Copilot AI Apr 29, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The troubleshooting rows that suggest verifying with a7 route get don’t include --gateway-group/-g. Since the CLI requires a gateway group (unless a default is configured in context), consider adding the gateway group flag here as well to avoid copy/paste failures.

Suggested change
| Canary not receiving traffic | Match condition never true | Check header/cookie name and `a7 route get` output |
| Rollback not instant | Config has not propagated yet | Verify with `a7 route get` and retry after propagation |
| Canary not receiving traffic | Match condition never true | Check header/cookie name and `a7 route get --gateway-group default` output |
| Rollback not instant | Config has not propagated yet | Verify with `a7 route get --gateway-group default` and retry after propagation |

Copilot uses AI. Check for mistakes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants