Fusio 7.2.1 常用 CLI 命令与 API 实测详解

系统梳理 Fusio 7.2.1 的 `php bin/fusio` 命令行工具与核心 REST API——覆盖认证会话、系统运维、部署迁移、资源管理、市场应用与数据库一键生成等高频命令,以及令牌签发与业务数据 CRUD 的实测用法,全部命令与回显均经真实环境验证。

FusioFusioAPIPHP2026/10/24

Fusio 7.2.1 常用 CLI 命令与 API 实测详解

目标:系统梳理 Fusio 7.2.1 的 php bin/fusio 命令行工具与核心 REST API——覆盖认证会话、系统运维、部署迁移、资源管理、市场应用与数据库一键生成等高频命令,以及令牌签发与业务数据 CRUD 的实测用法,全部命令与回显均经真实环境验证。

一、本文环境与执行口径

实测环境与 《Fusio 7.2.1 Docker Compose 部署指南》 的部署同构(实测日期 2026-10-24):Fusio 7.2.1 + MySQL 9,宿主机 8148 端口映射到应用 80 端口,管理员 admin / q1w2e3r4,应用安装目录 /var/www/html/fusio。

命令执行口径:CLI 命令统一写作 php bin/fusio <命令>(在应用目录内执行);Compose 部署下的等价写法是在部署目录执行 docker compose exec fusio php bin/fusio <命令>。REST API 则从服务器本机 curl http://127.0.0.1:8148/... 发起。所有回显均为实机原文(个别超长输出做了节选,节选处已注明)。

两个先交代的事实:

  • CLI 版本横幅:php bin/fusio 启动时会打印 psx 8.1.9.0(底层 PSX 框架版本),API 层自报版本为 v8.9.3(GET / 可见);
  • 启动时常见两条 PHP Warning(Unable to load dynamic library 'oci8' / 'pdo_oci',镜像未装 Oracle 支持库 libaio 所致)——不影响任何命令功能,官方镜像已知现象,看到无需处理。

二、命令全景:php bin/fusio list

php bin/fusio list 输出 100+ 个子命令,按命名空间分组(7.2.1 实测全量分组归纳):

分组命令数代表命令用途
顶级5route、serve路由清单、stdin 模拟 HTTP 请求
auth3auth:login(别名 login)、auth:whoami、auth:logoutCLI 登录会话
system14system:health、system:user_add、system:token、system:mcp系统运维(详见第四节)
deploy3deploy:deploy、deploy:export、deploy:importYAML 定义部署与配置导入导出
migrations12migrations:status、migrations:migrate数据库迁移
dbal1dbal:run-sql直接执行 SQL
marketplace4marketplace:list、marketplace:install应用市场
generate4generate:sdk、generate:modelSDK/模型/表类代码生成
grid1grid:setup从数据库一键生成 REST API
资源 CRUD 组各 5user:、app:、action:、connection:、schema:、scope:、role:、rate:、plan:、category:、event:、cronjob:、operation:、agent:每组固定 create/detail/update/delete/list 五件套
messenger3messenger:consume异步消息消费(supervisor 常驻的就是它)
debug3debug:container、debug:autowiring依赖容器诊断
api/app2api:push、app:*规范推送 typehub.cloud、应用管理

常用全局选项:-n(免交互,脚本必备)、-q(只输出错误)、-v(详细输出)、-h(命令帮助)。查任意命令用法用 php bin/fusio help <命令>。

另有 route 命令可直接打印全部注册路由(节选实测输出):

OPTIONS|HEAD|GET /authorization/whoami                                            operation://278::278
OPTIONS|POST     /authorization/revoke                                            operation://277::277
OPTIONS|PUT      /backend/account/change_password                                 operation://4::4
OPTIONS|POST     /backend/action                                                  operation://6::6
OPTIONS|DELETE   /backend/action/$action_id<[0-9]+|^~>                            operation://12::12

三、认证与会话:auth 三件套与 system:token

3.1 auth:login / whoami / logout

CLI 的大部分管理命令依赖登录态。未登录直接调 auth:whoami 的实测报错:

In Authenticator.php line 178:
  Found no existing token, please request a token through the login command

auth:whoami

登录(-r 指定实例地址、-u/-p 账号密码):

php bin/fusio login --username=admin --password=q1w2e3r4
Login successful

登录成功后再查当前身份,实测输出(scopes 节选,管理员实际持有 backend/consumer/authorization 全系 60+ 项):

kind: 'https://typehub.cloud/s/fusio/sdk/7.0.14/Consumer_UserAccount'
id: 2
roleId: 1
status: 1
name: admin
email: admin@example.com
scopes:
    - backend
    - backend.account
    - backend.action
    - ...
    - consumer
    - authorization
date: '2026-10-23T19:38:04Z'

php bin/fusio logout 清除本地登录态(实测回显 Logout successful)。注意:登录态是本机文件级的,同一台服务器的后续 CLI 命令共享;换机器需重新 login。

3.2 system:token:不登录直接签发访问令牌

给指定应用+用户签发令牌(脚本化场景常用):

Usage:
  system:token <appId> <userId> <scopes> <expire> [<tenantId>]

实测(appId/userId 均可用名字):

App: fusio
User: scott
Token: eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJodHRwOi8vMTkyLjE2OC4xLjYyOjgxNDgi...
Expires: 86400
Scope: consumer

两个实测出的规则:

  • scopes 必填且校验严格:不传 scopes 时报 No scopes provided(usage 回显见上);传入的 scope 还会与该 app/user 的授权范围求交集(源码 getValidScopes),不在范围内的 scope 不会生效;
  • expire 用 ISO 8601 duration(如 P1D),上例 Expires: 86400 即 24 小时。

3.3 system:mcp:stdio 方式的 MCP 服务

未登录时报错(同 3.1 的 token 缺失);登录后通过 stdin 发送 JSONRPC initialize 得到实测回显:

{"jsonrpc":"2.0","id":1,"result":{"protocolVersion":"2024-11-05","capabilities":{"logging":{},"completions":{},"prompts":{"listChanged":true},"resources":{"listChanged":true},"tools":{"listChanged":true}},"serverInfo":{"name":"Fusio","version":"v8.9.3","description":"Self-Hosted API Management for Builders."}}}

即 CLI 的 MCP 服务不依赖 configuration.php 的 fusio_mcp 开关(该开关只管 HTTP 端点 /mcp,见 《Fusio 7.2.1 配置参数详解》 4.2 节)。

四、系统运维命令(system:*)

4.1 健康与检查

php bin/fusio system:health    # 健康检查:逐个连接探测
php bin/fusio system:check user   # 指定检查项

实测回显:

[✓] demorest
[✓] System
Check successful

system:check 必须带检查名,缺参会报 Not enough arguments (missing: "name") 并提示 system:check <name>;传不存在的检查名返回 Unknown check。镜像入口脚本正是用 system:check user 判断管理员是否已初始化(见 《Fusio 7.2.1 配置参数详解》 3.2 节)。

4.2 用户管理三兄弟

system:user_add(别名 adduser)——建管理员/用户,选项完整支持角色指定:

Options:
  -r, --role[=ROLE]          Role of the account [1=Administrator, 2=Backend, 3=Consumer]
  -u, --username[=USERNAME]  The username
  -e, --email[=EMAIL]        The email
  -p, --password[=PASSWORD]  The password

实测(role 3 = Consumer 角色建号):

Created user scott successful

配合 user:create <payload>(YAML/JSON 文件建号)与 REST 的 /backend/user/ 是三条等价路径。验证建号结果可用 dbal:run-sql 直查用户表(实测):

php bin/fusio dbal:run-sql 'SELECT id, name, status FROM fusio_user'
 ---- --------------- --------
  id   name            status
 ---- --------------- --------
  1    Administrator   1
  2    admin           1
  3    scott           1
  4    peter           0
  5    peter2          0
 ---- --------------- --------

注意 status=0 的行是被删除用户(软删除标记),与 user:delete 的行为对应。user:delete <id> 对不存在 id 的实测回显是 Could not find user。

4.3 清理、轮转与定时任务

命令实测回显说明
system:cleanClean up successful!清理过期 app token 等冗余数据;镜像 cron 每月 1 日自动执行
system:log_rotateCreated archive table fusio_audit_20261024 / Copied 60 entries to fusio_audit_20261024 table / Truncated fusio_audit table(共 6 行)把审计与错误日志表搬进按日归档表后清空主表;同样有月度 cron
system:cronjob_executeExecution successful执行到期的计划任务;镜像 cron 每分钟触发
system:mail_test <to>缺参报错 Not enough arguments (missing: "to");成功时无输出、退出码 0验证 mailer 配置(配合 FUSIO_MAILER,配置见 C1 篇)

4.4 其他 system 命令速查

命令用途
system:wait_for等待外部依赖(数据库)就绪,入口脚本第一步
system:clear_cache清空系统缓存(含 container.php 编译产物,改配置后也可用它替代手工 rm)
system:upgrade把 YAML 操作定义转换为 PHP
system:register <class>注册自定义适配器(-y 自动确认)
system:restore恢复软删除的数据库记录

五、部署与迁移:deploy:* / migrations:* / dbal

5.1 deploy:export / import / deploy

deploy:export 把平台内全部定义导出为一份 JSON(不接文件参数时打到 stdout),实测节选:

{
    "version": "v8.9.3",
    "action": [
        {
            "kind": "https:\/\/typehub.cloud\/s\/fusio\/sdk\/7.0.14\/Backend_Action",
            "name": "Demorest_Products_SQL_Delete",
            "class": "Fusio.Adapter.Sql.Action.SqlDelete",
            "async": false,
            "config": {
                "connection": "4",
                "table": "products"
            },
            "date": "2026-10-23T19:46:41Z"
        },
        ...

三件套分工:deploy:export 导出全量配置 → deploy:import <file> 导入恢复 → deploy:deploy 部署 YAML 定义文件(入口脚本每次启动也会跑一次 deploy 同步)。这是环境迁移/备份恢复的标准载体,与数据库 dump(B2 篇的 mysqldump 方案)配合使用。

5.2 migrations 状态与执行

实测 migrations:status(节选,7.2.1 共 22 个迁移全部已执行):

| Migration                                   | Status   | Migrated At         | Execution Time | Description          |
| Fusio\Impl\Migrations\Version20230508210151 | migrated | 2026-10-23 19:42:44 | 3.905s         | Setup initial tables |
| Fusio\Impl\Migrations\Version20261008103540 | ...      | ...                 | ...            | ...                  |

migrations:up-to-date 实测回显:

 [OK] Up-to-date! No migrations to execute.

升级 Fusio 版本时,入口脚本的逻辑就是 migration:up-to-date 失败即自动 migration:migrate --no-interaction,所以手动升级场景只需换镜像版本重启,迁移自动完成。

5.3 dbal:run-sql

官方帮助原文给出用法范式:php bin/fusio dbal:run-sql "SELECT * FROM users",支持 --connection 指定命名连接(默认操作元数据库)、--force-fetch 强制取结果。除了上文查用户表,清理防火墙实验数据(DELETE 语句)等运维操作也走它,配合 C1 篇第六节的防火墙实验很有用。

六、资源管理命令:CRUD 五件套与市场

6.1 命名规律

user/app/action/connection/schema/scope/role/rate/plan/category/event/cronjob/operation/agent 十四个资源组共用同一套五件套:*:create(建)、*:detail <id>(查)、*:update <id> <payload>(改)、*:delete <id>(删)、*:list(列表)。create/update 都吃 YAML/JSON payload 文件;这些命令本质上调用的是后台 REST API,所以先 login 再用。

6.2 实测样例

app 列表(登录后 php bin/fusio app:list,节选):

{
    "kind": "https:\/\/typehub.cloud\/s\/fusio\/sdk\/7.0.14\/Backend_AppCollection",
    "totalResults": 4,
    "entry": [
        { "id": 4, "status": 1, "name": "redoc",     "appKey": "ef44e5d6-259e-438e-9fff-fe047907b252" },
        { "id": 3, "status": 1, "name": "fusio",     "appKey": "c5c26de3-7d0a-4c6b-bccb-bc5c2d7e3b16" },
        { "id": 2, "status": 1, "name": "developer", "appKey": "26d0c2df-6be6-4877-8cce-e4cd239befa7" },
        { "id": 1, "status": 1, "name": "account",   "appKey": "b8080764-d5f7-42e2-bdd5-5a09035a5142" }
    ]
}

默认四个应用即后台(fusio)、开发者门户(developer)、账户页(account)、文档渲染(redoc)。appKey 就是 REST 令牌签发时 Basic 认证用的 client_id(见第八节)。

action/connection/scope 列表同样直接可用(action:list 实测返回 5 个 Demorest_Products_SQL_* 动作、connection:list 返回 System 与业务连接)。未登录调用任何此类命令都会得到 3.1 的 Found no existing token 报错。

6.3 marketplace 命令

marketplace:list 实测(市场可用应用与版本):

+------------+---------+
| Name       | Version |
+------------+---------+
| plant      | 0.3.1   |
| swagger-ui | 2.0.0   |
| redoc      | 1.0.4   |
| account    | 2.4.0   |
| developer  | 7.2.1   |
| fusio      | 7.2.0   |
+------------+---------+

marketplace:install <type> <name> 安装(type 取 app/action 等);缺 name 的实测报错为 Name not provided。选项 -d 可关 SSL 校验(内网镜像源场景)、-x 关闭环境变量替换。

6.4 grid:setup:从数据库一键生成 REST API

这是 Fusio 最"惊艳"的命令:对一个已有 MySQL/PG 库,自动建连接、建 Action、建 Schema、建 Operation,产出全套 CRUD 端点。

Usage:
  grid:setup [options] [--] [<name>]

  -d, --driver[=DRIVER]      Database driver (pdo_mysql, pdo_pgsql)
  -H, --host[=HOST]          Database host
  -u, --user[=USER]          Database user
  -p, --password[=PASSWORD]  Database password
  -D, --dbname[=DBNAME]      Database name
  -t, --prefix[=PREFIX]      Table prefix

实测过程(对 demo 库的 products 表,<name> 参数决定生成的连接与路由前缀):

Fusio Grid - Relational Database REST Setup
===========================================

 Connecting to target database demo ...

 [OK] Database connection successfully established

 Setup connection demorest ...

 [OK] Connection is available

 Building changelog ...
 ----------------- -------- ---------------
   Name              Method   Path
 ----------------- -------- ---------------
   products.getAll   GET      /products/
   products.get      GET      /products/:id
   products.create   POST     /products/
   products.update   PUT      /products/:id
   products.delete   DELETE   /products/:id
 ----------------- -------- ---------------

 [OK] Successfully generated REST API

两个实测踩坑点:

  • 交互确认步建议显式回答;生成物命名依赖 <name> 与表结构,实测中出现过 In Validator.php line 145: Invalid operation name 中断——换一个合法的 name 前缀重新执行即可;
  • 生成的同时会自动创建名为 <name> 的 scope 并挂到这些 Operation 上(实测生成的操作 scope 为 demorest),这直接决定了第八节 API 调用时要申请什么 scope。

6.5 generate 代码生成组

generate:sdk [<type>](客户端 SDK,-s 命名空间、-o 输出目录、-r 不打包 zip)、generate:model(TypeSchema 规范转模型类)、generate:frontend、generate:table(为元数据库生成表/行类)。另有 api:push <name> 把平台规范推送到 typehub.cloud(需 -u/-s 凭证)。

七、serve:不监听端口的调试利器

serve <method> <uri> [<headers>] 从 stdin 接收请求体、在进程内完成一次完整请求处理,状态行写到 stderr。实测:

echo -n '' | php bin/fusio serve GET /system/health
HTTP/1.1 200 OK
{
    "kind": "https://typehub.cloud/s/fusio/sdk/7.0.14/System_HealthCheck",
    "healthy": true,
    "checks": {
        "demorest": { "healthy": true },
        "System": { "healthy": true }
    }
}

排障时不需要绕经 Apache/端口,直接验证"框架层"对某 URI 的处理结果,与真实 HTTP 层的表现形成对照。

八、REST API 实测

8.1 端点总览

GET /(无需认证)返回平台自描述文档,实测关键字段与链接:

{
    "kind": "https://typehub.cloud/s/fusio/sdk/7.0.14/System_About",
    "apiVersion": "v8.9.3",
    "title": "Fusio",
    "categories": ["authorization", "backend", "consumer", "default", "system"],
    "links": [
        { "rel": "root",     "href": "http://192.168.1.62:8148/" },
        { "rel": "openapi",  "href": "http://192.168.1.62:8148/system/generator/spec-openapi" },
        { "rel": "health",   "href": "http://192.168.1.62:8148/system/health" },
        { "rel": "oauth2",   "href": "http://192.168.1.62:8148/authorization/token" },
        { "rel": "whoami",   "href": "http://192.168.1.62:8148/authorization/whoami" }
    ]
}

常用端点速查:/authorization/token(签发)、/authorization/whoami、/backend/*(管理 API,需 backend scope)、/consumer/*(消费端 API)、/system/health、/system/generator/spec-openapi(OpenAPI 规范下载)、/.well-known/*(OAuth2 元数据)、业务端点(本文为 grid:setup 生成的 /demorest/products)。

8.2 令牌签发:两种 grant 与 scope 的决定性作用

方式一:client_credentials(用应用的 app_key/app_secret 做 Basic 认证,机器对机器):

curl -s -X POST http://127.0.0.1:8148/authorization/token \
  -u "c5c26de3-7d0a-4c6b-bccb-bc5c2d7e3b16:<app_secret>" \
  -d "grant_type=client_credentials&scope=authorization"

实测响应(expires_in 由 fusio_expire_token 配置决定,默认 P2D = 172800 秒):

{
    "access_token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9...",
    "token_type": "bearer",
    "expires_in": 172800,
    "refresh_token": "39284a3354cd6b9eb52e-26648858082a9859359ed3c963289b2897028b81f187ccdf-47e617bcc1",
    "scope": "authorization"
}

方式二:password(用户名密码换令牌,scope 按需申请):

curl -s -X POST http://127.0.0.1:8148/authorization/token \
  -u "c5c26de3-7d0a-4c6b-bccb-bc5c2d7e3b16:<app_secret>" \
  -d "grant_type=password&username=admin&password=q1w2e3r4&scope=demorest"

实测响应头两个字段:"expires_in": 172800、"scope": "demorest"。

scope 是不是"摆设"?实测说明不是——同一个 app 的令牌,scope 只申请了 authorization 时去访问业务端点:

{
    "success": false,
    "title": "Internal Server Error",
    "message": "Access to this operation is not in the scope of the provided token"
}

HTTP 401。换成 scope=demorest 的令牌立刻放行。错误密码的 password grant 则返回 400(不是 401),连错会触发防火墙计数(阈值行为实测见 《Fusio 7.2.1 配置参数详解》 第六节)。

8.3 业务数据 CRUD 全流程(demorest/products)

对 grid:setup 生成的 products 资源做完整 CRUD,令牌用 scope=demorest:

列表 GET /demorest/products/(HTTP 200):

{
    "totalResults": 4,
    "itemsPerPage": 16,
    "startIndex": 0,
    "entry": [
        { "id": 4, "title": "USB-C Dock 12-in-1",  "price": "749.00",  "created_at": "2026-10-23T19:50:43+00:00" },
        { "id": 3, "title": "Display Stand",       "price": "159.50",  "created_at": "2026-10-23T19:44:21+00:00" },
        { "id": 2, "title": "Office Chair",        "price": "1299.00", "created_at": "2026-10-23T19:44:21+00:00" },
        { "id": 1, "title": "Mechanical Keyboard", "price": "399.00",  "created_at": "2026-10-23T19:44:21+00:00" }
    ]
}

创建 POST /demorest/products/,请求体 {"title":"USB-C Hub","price":"259.00"}:

{
    "success": true,
    "message": "Entry successfully created",
    "id": "5"
}

详情 GET /demorest/products/5:

{
    "id": 5,
    "title": "USB-C Hub",
    "price": "259.00",
    "created_at": "2026-10-24T05:46:37+00:00"
}

更新/删除 即 PUT/DELETE 同路径(历史实测回显 Entry successfully updated / 对应 Common_Message)。无令牌访问的实测回显是 401 + {"message": "Missing authorization header"}。

8.4 管理 API 与操作详情

后台日志接口 GET /backend/log(需 backend scope 令牌)实测节选,每条请求的 app、操作、IP、UA、路径都有留痕:

{
    "kind": "https:\/\/typehub.cloud\/s\/fusio\/sdk\/7.0.14\/Backend_LogCollection",
    "totalResults": 4,
    "entry": [
        {
            "id": 25, "appId": 3, "operationId": 281,
            "ip": "10.89.73.1", "userAgent": "curl\/7.81.0",
            "method": "POST", "path": "\/demorest\/products\/"
        }
    ]
}

单个 Operation 的定义可用 operation:detail 或管理 API 查看(实测 id 279):

{
    "id": 279,
    "name": "demorest.products.getAll",
    "scopes": ["demorest"],
    "httpMethod": "GET",
    "httpPath": "\/demorest\/products",
    "httpCode": 200,
    "outgoing": "schema:\/\/Demorest_Products_SQL_GetAll",
    "action": "action:\/\/Demorest_Products_SQL_GetAll"
}

8.5 关闭态端点的真实响应

configuration.php 中 fusio_graphql/fusio_mcp/fusio_jsonrpc 默认 false(配置解析见 《Fusio 7.2.1 配置参数详解》),对应端点实测响应:

  • POST /graphql → 500 + {"message": "GraphQL service is not enabled"}
  • POST /mcp → {"message": "MCP service is not enabled"}

需要启用时改对应键并清缓存即可(流程见 C1 篇第八节)。

九、常见问题

  1. CLI 报 oci8/pdo_oci Warning:镜像缺少 Oracle 扩展依赖库(libaio),纯警告不影响功能,无需处理;除非确要接 Oracle 数据源。
  2. 命令报 Found no existing token:未登录或登录态过期,重新 php bin/fusio login;脚本场景改用 system:token 或 REST 令牌。
  3. API 返回 Access to this operation is not in the scope of the provided token:申请令牌时 scope 没带上目标操作的 scope(grid:setup 生成的资源带 <name> scope),重新签发并附加即可。
  4. marketplace:install 报 Name not provided:命令格式是 <type> <name> 两个参数(如 marketplace:install app swagger-ui)。
  5. grid:setup 报 Invalid operation name:name 参数与表名组合出不合法的操作名,换 name 前缀重跑。

十、相关文档