From a3a3991d115b0a122feb35ca904004413e3eb593 Mon Sep 17 00:00:00 2001 From: Qi Guo <979918879@qq.com> Date: Wed, 29 Apr 2026 00:47:02 +0800 Subject: [PATCH 1/3] docs: align user guides with service routes --- docs/golden-example.md | 26 ++++++------- docs/roadmap.md | 10 ++--- docs/user-guide/getting-started.md | 62 +++++++++++++++++++++--------- docs/user-guide/route.md | 45 ++++++++++------------ 4 files changed, 81 insertions(+), 62 deletions(-) diff --git a/docs/golden-example.md b/docs/golden-example.md index fc7f46c..165b61e 100644 --- a/docs/golden-example.md +++ b/docs/golden-example.md @@ -191,21 +191,21 @@ Matching the API7 EE Runtime Admin API route schema. package api type Route struct { - ID string `json:"id"` // IDs are string in API7 EE - Name string `json:"name"` - Desc *string `json:"desc,omitempty"` + ID string `json:"id,omitempty"` + Name string `json:"name,omitempty"` + Desc string `json:"desc,omitempty"` + URI string `json:"uri,omitempty"` URIs []string `json:"uris,omitempty"` + Paths []string `json:"paths,omitempty"` Methods []string `json:"methods,omitempty"` - Host *string `json:"host,omitempty"` + Host string `json:"host,omitempty"` Hosts []string `json:"hosts,omitempty"` - Priority int `json:"priority"` - Status int `json:"status"` + ServiceID string `json:"service_id,omitempty"` + Upstream map[string]interface{} `json:"upstream,omitempty"` Plugins map[string]interface{} `json:"plugins,omitempty"` - UpstreamID *string `json:"upstream_id,omitempty"` - ServiceID *string `json:"service_id,omitempty"` Labels map[string]string `json:"labels,omitempty"` - CreateTime int64 `json:"create_time"` - UpdateTime int64 `json:"update_time"` + Status int `json:"status,omitempty"` + Priority int `json:"priority,omitempty"` } ``` @@ -511,10 +511,10 @@ func JSONResponse(path string) Response { { "id": "1", "name": "users-api", - "uris": ["/api/v1/users"], + "paths": ["/api/v1/users"], "methods": ["GET", "POST"], "status": 1, - "upstream_id": "u1" + "service_id": "svc-users" } ] } @@ -529,4 +529,4 @@ func JSONResponse(path string) Response { 5. Create `pkg/cmd///_test.go` with TTY/non-TTY/error test cases. 6. Add test fixture JSON in `test/fixtures/`. 7. Register in `pkg/cmd/root/root.go`. -8. Run `make check` to verify. \ No newline at end of file +8. Run `make check` to verify. diff --git a/docs/roadmap.md b/docs/roadmap.md index 3d5d731..885dfe7 100644 --- a/docs/roadmap.md +++ b/docs/roadmap.md @@ -74,9 +74,9 @@ This document defines the per-PR development plan for the a7 CLI (API7 Enterpris - **Commands**: `a7 token create|list`, `a7 user/role/policy` - **Focus**: Managing CLI access tokens and platform permissions. -### PR-36: Portal & Custom Plugins -- **Commands**: `a7 portal`, `a7 custom-plugin` -- **Focus**: Developer portal configuration and custom Lua plugin management. +### PR-36: Custom Plugin Extensions +- **Commands**: `a7 custom-plugin` (future) +- **Focus**: Custom Lua plugin management when exposed by supported API7 EE APIs. --- @@ -92,6 +92,6 @@ This document defines the per-PR development plan for the a7 CLI (API7 Enterpris | 8 | PR-33 | E2E Test Infra | Smoke tests | | 8 | PR-34 | Resource CRUD E2E | Lifecycle validation | | 9 | PR-35 | Token & RBAC | Multi-user E2E | -| 9 | PR-36 | Portal & Extensions | Feature-specific E2E | +| 9 | PR-36 | Custom Plugin Extensions | Feature-specific E2E | -**Total**: 9 PRs to reach production readiness. \ No newline at end of file +**Total**: 9 PRs to reach production readiness. diff --git a/docs/user-guide/getting-started.md b/docs/user-guide/getting-started.md index 3f4d1e2..a404c21 100644 --- a/docs/user-guide/getting-started.md +++ b/docs/user-guide/getting-started.md @@ -66,30 +66,53 @@ a7 gateway-group list If the connection is successful, you will see a list of gateway groups. -## Your First Route +## Your First Service and Route -Once you have a working context, you can start managing routes within a gateway group. +Once you have a working context, create a service for the backend and then +create a route that references that service. -### 1. Create a Route Configuration +### 1. Create a Service Configuration -Create a file named `route.json` with the following content: +Create a file named `service.json` with the following content: ```json { - "id": "getting-started", - "name": "getting-started-route", - "uri": "/get", - "methods": ["GET"], + "id": "getting-started-service", + "name": "getting-started-service", "upstream": { "type": "roundrobin", - "nodes": { - "httpbin.org:80": 1 - } + "nodes": [ + { + "host": "httpbin.org", + "port": 80, + "weight": 1 + } + ] } } ``` -### 2. Apply the Route +### 2. Apply the Service + +```bash +a7 service create -g default -f service.json +``` + +### 3. Create a Route Configuration + +Create a file named `route.json`: + +```json +{ + "id": "getting-started", + "name": "getting-started-route", + "paths": ["/get"], + "methods": ["GET"], + "service_id": "getting-started-service" +} +``` + +### 4. Apply the Route Use the `route create` command to send this configuration to API7 EE. Note that `--gateway-group` (or `-g`) is required for runtime resource commands if not set in the current context. @@ -97,12 +120,12 @@ Use the `route create` command to send this configuration to API7 EE. Note that a7 route create -g default -f route.json ``` -### 3. Verify the Route +### 5. Verify the Route List your routes to see the new entry: ```bash -a7 route list -g default +a7 route list -g default --service-id getting-started-service ``` You can also get the full details of the route you just created: @@ -111,7 +134,7 @@ You can also get the full details of the route you just created: a7 route get getting-started -g default ``` -### 4. Test the Route +### 6. Test the Route Assuming your API7 gateway is running and listening for data plane traffic (default port 9443), you can test the route with `curl`: @@ -119,12 +142,13 @@ Assuming your API7 gateway is running and listening for data plane traffic (defa curl -ik https://localhost:9443/get ``` -### 5. Clean Up +### 7. Clean Up -When you are done, you can delete the route: +When you are done, delete the route and service: ```bash a7 route delete getting-started -g default --force +a7 service delete getting-started-service -g default --force ``` ## Interactive Mode @@ -195,8 +219,8 @@ You can delete or export multiple resources with one command. # Delete all routes in the current gateway group a7 route delete --all --force -g default -# Export upstreams by label as JSON -a7 upstream export --label team=platform --output json -g default +# Export services by label as JSON +a7 service export --label team=platform --output json -g default ``` ## What's Next diff --git a/docs/user-guide/route.md b/docs/user-guide/route.md index 2c2adb0..5b2d892 100644 --- a/docs/user-guide/route.md +++ b/docs/user-guide/route.md @@ -8,28 +8,27 @@ The `a7 route` command allows you to manage API7 Enterprise Edition (API7 EE) ro ### `a7 route list` -Lists all routes in the specified gateway group. +Lists routes in the specified gateway group. In current API7 EE environments, +routes are scoped by service, so prefer passing `--service-id` when listing +routes for a known service. | Flag | Short | Default | Description | |------|-------|---------|-------------| | `--gateway-group` | `-g` | | Target gateway group name (required) | -| `--page` | | `1` | Page number for pagination | -| `--page-size` | | `20` | Number of items per page | -| `--name` | | | Filter routes by name | | `--label` | | | Filter routes by label | -| `--uri` | | | Filter routes by URI | +| `--service-id` | | | Filter routes by service ID | | `--output` | `-o` | `table` | Output format (table, json, yaml) | **Examples:** -List all routes in the "default" gateway group: +List routes for a service in the "default" gateway group: ```bash -a7 route list -g default +a7 route list -g default --service-id example-service ``` -Filter routes by label: +Filter routes by label within a service: ```bash -a7 route list -g default --label env=prod +a7 route list -g default --service-id example-service --label env=prod ``` ### `a7 route get ` @@ -60,6 +59,11 @@ Creates a new route from a JSON or YAML file. **Examples:** +Create a service first: +```bash +a7 service create -g default -f service.json +``` + Create a route from a JSON file: ```bash a7 route create -g default -f route.json @@ -70,14 +74,9 @@ a7 route create -g default -f route.json { "id": "getting-started", "name": "example-route", - "uri": "/get", + "paths": ["/get"], "methods": ["GET"], - "upstream": { - "type": "roundrobin", - "nodes": { - "httpbin.org:80": 1 - } - } + "service_id": "example-service" } ``` @@ -146,10 +145,11 @@ Key fields in the route configuration (sent to `/apisix/admin/routes`): |-------|------|-------------| | `id` | string | Unique identifier for the route | | `name` | string | Human-readable name for the route | -| `uri` | string | The URI pattern to match | +| `paths` | array | Path patterns to match | +| `uri` | string | Legacy URI pattern accepted by some APISIX-compatible payloads | | `methods` | array | HTTP methods allowed (e.g., ["GET", "POST"]) | | `upstream` | object | Inline upstream configuration | -| `upstream_id` | string | Reference to an existing upstream ID | +| `service_id` | string | Reference to the service that owns the upstream configuration | | `status` | integer | Route status (1 for enabled, 0 for disabled) | | `plugins` | object | Plugin configurations for the route | | `labels` | object | Key-value pairs for filtering and organization | @@ -160,18 +160,13 @@ Key fields in the route configuration (sent to `/apisix/admin/routes`): ```json { - "uri": "/api/v1/*", + "paths": ["/api/v1/*"], "name": "api-v1-route", + "service_id": "billing-service", "methods": ["GET", "POST"], "labels": { "env": "production", "team": "billing" - }, - "upstream": { - "type": "roundrobin", - "nodes": { - "billing.internal:8080": 1 - } } } ``` From 074c4c982c5faa11d6bc3e2eb321d525d0c40a0c Mon Sep 17 00:00:00 2001 From: Qi Guo <979918879@qq.com> Date: Wed, 29 Apr 2026 01:02:02 +0800 Subject: [PATCH 2/3] docs: clarify route upstream bindings --- docs/golden-example.md | 15 ++++++++++----- docs/user-guide/route.md | 3 ++- 2 files changed, 12 insertions(+), 6 deletions(-) diff --git a/docs/golden-example.md b/docs/golden-example.md index 165b61e..596be32 100644 --- a/docs/golden-example.md +++ b/docs/golden-example.md @@ -201,6 +201,7 @@ type Route struct { Host string `json:"host,omitempty"` Hosts []string `json:"hosts,omitempty"` ServiceID string `json:"service_id,omitempty"` + UpstreamID string `json:"upstream_id,omitempty"` Upstream map[string]interface{} `json:"upstream,omitempty"` Plugins map[string]interface{} `json:"plugins,omitempty"` Labels map[string]string `json:"labels,omitempty"` @@ -360,17 +361,21 @@ func printTable(io *iostreams.IOStreams, routes []api.Route) error { } w := tabwriter.NewWriter(io.Out, 0, 0, 3, ' ', 0) - fmt.Fprintln(w, "ID\tNAME\tURIS\tSTATUS\tUPSTREAM_ID") + fmt.Fprintln(w, "ID\tNAME\tURIS\tSTATUS\tSERVICE_ID\tUPSTREAM_ID") for _, r := range routes { uris := strings.Join(r.URIs, ",") status := fmt.Sprintf("%d", r.Status) - upstream := "N/A" - if r.UpstreamID != nil { - upstream = *r.UpstreamID + service := r.ServiceID + if service == "" { + service = "N/A" + } + upstream := r.UpstreamID + if upstream == "" { + upstream = "N/A" } - fmt.Fprintf(w, "%s\t%s\t%s\t%s\t%s\n", r.ID, r.Name, uris, status, upstream) + fmt.Fprintf(w, "%s\t%s\t%s\t%s\t%s\t%s\n", r.ID, r.Name, uris, status, service, upstream) } return w.Flush() } diff --git a/docs/user-guide/route.md b/docs/user-guide/route.md index 5b2d892..9cceb43 100644 --- a/docs/user-guide/route.md +++ b/docs/user-guide/route.md @@ -149,7 +149,8 @@ Key fields in the route configuration (sent to `/apisix/admin/routes`): | `uri` | string | Legacy URI pattern accepted by some APISIX-compatible payloads | | `methods` | array | HTTP methods allowed (e.g., ["GET", "POST"]) | | `upstream` | object | Inline upstream configuration | -| `service_id` | string | Reference to the service that owns the upstream configuration | +| `service_id` | string | Reference to a service that owns the upstream configuration | +| `upstream_id` | string | Reference to a standalone upstream; distinct from `service_id` and still supported by the CLI/API | | `status` | integer | Route status (1 for enabled, 0 for disabled) | | `plugins` | object | Plugin configurations for the route | | `labels` | object | Key-value pairs for filtering and organization | From 587d668cf4f86eb19fd227ce2fab660817ee4cd1 Mon Sep 17 00:00:00 2001 From: Qi Guo <979918879@qq.com> Date: Thu, 30 Apr 2026 00:44:07 +0800 Subject: [PATCH 3/3] docs: clarify service-scoped route listing --- docs/golden-example.md | 14 ++++++++++---- docs/user-guide/route.md | 6 +++--- 2 files changed, 13 insertions(+), 7 deletions(-) diff --git a/docs/golden-example.md b/docs/golden-example.md index 596be32..db28470 100644 --- a/docs/golden-example.md +++ b/docs/golden-example.md @@ -361,10 +361,16 @@ func printTable(io *iostreams.IOStreams, routes []api.Route) error { } w := tabwriter.NewWriter(io.Out, 0, 0, 3, ' ', 0) - fmt.Fprintln(w, "ID\tNAME\tURIS\tSTATUS\tSERVICE_ID\tUPSTREAM_ID") - + fmt.Fprintln(w, "ID\tNAME\tPATHS\tSTATUS\tSERVICE_ID\tUPSTREAM_ID") + for _, r := range routes { - uris := strings.Join(r.URIs, ",") + paths := strings.Join(r.Paths, ",") + if paths == "" { + paths = r.URI + } + if paths == "" { + paths = strings.Join(r.URIs, ",") + } status := fmt.Sprintf("%d", r.Status) service := r.ServiceID if service == "" { @@ -375,7 +381,7 @@ func printTable(io *iostreams.IOStreams, routes []api.Route) error { upstream = "N/A" } - fmt.Fprintf(w, "%s\t%s\t%s\t%s\t%s\t%s\n", r.ID, r.Name, uris, status, service, upstream) + fmt.Fprintf(w, "%s\t%s\t%s\t%s\t%s\t%s\n", r.ID, r.Name, paths, status, service, upstream) } return w.Flush() } diff --git a/docs/user-guide/route.md b/docs/user-guide/route.md index 9cceb43..15e9414 100644 --- a/docs/user-guide/route.md +++ b/docs/user-guide/route.md @@ -8,9 +8,9 @@ The `a7 route` command allows you to manage API7 Enterprise Edition (API7 EE) ro ### `a7 route list` -Lists routes in the specified gateway group. In current API7 EE environments, -routes are scoped by service, so prefer passing `--service-id` when listing -routes for a known service. +Lists routes in the specified gateway group. API7 EE may require +`--service-id` to list routes; omit it only if your environment supports +unscoped route listing. | Flag | Short | Default | Description | |------|-------|---------|-------------|