Add an anonymous read-only state endpoint for the public website, backed by the private competition service. Keep draft reads and writes behind existing admin login and document the production routing.
5.4 KiB
官网赛事信息后端接口
功能与调用链
YD_Event.Web 的“官网赛事信息”页面请求当前环境的 GET/PUT /api/website-competition。此接口由 YD_Event.Admin 提供,沿用后台登录认证;管理页不需要填写接口地址或管理密钥。
正式环境访问基地址为 https://jitsi-web.yuedongsports.com/,管理接口完整地址为 https://jitsi-web.yuedongsports.com/api/website-competition。此地址是后台对外入口;CompetitionApi:AdminUrl 是后端转发到官网赛事服务的地址,需单独配置。
YD_Event.Admin 在服务端把请求转发到官网赛事服务的内部 /api/competition/admin。两台服务器通过私网连接,不使用服务间管理密钥。官网赛事服务按来源 IP 放行内部管理请求,持久化草稿或发布状态,供公开页面读取。本仓库不新增赛事数据库表。
官网公开页面不访问需要登录的管理接口,而是匿名请求 GET /api/competition/state。此路由由 CompetitionPublicController 通过同一私网赛事服务读取 /api/competition/state;赛事服务在未发布时只返回空态。公开接口只支持读取,不提供草稿或写入能力。官网每 10 秒重新读取一次。
YD_Event.Web 管理页
→ 当前域名 /api/website-competition(后台登录态)
→ YD_Event.Admin(通过私网转发)
→ 官网赛事服务 /api/competition/admin(来源 IP 白名单)
→ 持久化赛事 JSON / 官网公开接口
接口
| 方法 | 路径 | 说明 |
|---|---|---|
GET |
/api/website-competition |
读取当前环境的完整赛事草稿,包括未发布内容 |
PUT |
/api/website-competition |
保存赛事信息及 published 状态,JSON 请求体上限为 8 MB |
GET |
/api/competition/state |
匿名读取已发布数据;未发布时返回空态 |
前两个管理方法要求已有的后台登录态;公开方法不要求登录。控制器原样转发上游的 JSON 响应和 HTTP 状态码。数据的主要结构如下;详细字段由管理页 Excel 模板及官网赛事服务校验规则约束。
{
"published": false,
"competition": { "nameZh": "", "nameEn": "", "dateZh": "", "dateEn": "", "venueZh": "", "venueEn": "" },
"notice": { "enabled": false, "textZh": "", "textEn": "" },
"schedule": { "currentId": "", "callingId": "", "upcomingCount": 3, "items": [] },
"results": { "overall": [], "challenge": [], "battle": [] },
"players": [],
"records": []
}
服务端配置
| 配置键 | 环境变量写法 | 说明 |
|---|---|---|
CompetitionApi:AdminUrl |
CompetitionApi__AdminUrl |
官网赛事服务内部管理接口完整 URL;本地默认 http://127.0.0.1:8787/api/competition/admin |
正式环境两台服务器分机部署,必须将 CompetitionApi__AdminUrl 配置为 http://<赛事服务私网 IP>:8787/api/competition/admin,不能使用默认的 127.0.0.1。赛事服务应只在私网地址监听,并通过 COMPETITION_ADMIN_ALLOWED_IPS 放行 YD_Event.Admin 的私网 IP;防火墙只允许后台服务器连接该端口。公网 Nginx 必须屏蔽 /api/competition/admin,避免绕过后台登录认证直接修改赛事数据。
公开状态接口从 CompetitionApi__AdminUrl 推导同源的 /api/competition/state,因此不需要额外的地址或密钥配置。正式环境沿用现有 /api/ 反向代理到 YD_Event.Admin;不要把公开接口直接转发到赛事服务。
部署步骤
- 启动官网赛事服务,设置持久化数据路径、私网监听地址、后台服务器的来源 IP 白名单;其健康检查为
GET /api/competition/ping。 - 在
YD_Event.Admin的运行环境配置内网管理接口 URL,然后启动或重启后端。Startup已注册专用WebsiteCompetitionHttpClient。 - 将后台站点同源的
/api/website-competition路由转发到YD_Event.Admin。不要把该路径直接暴露或转发到官网赛事服务管理接口。 - 管理员登录
YD_Event.Web后打开“官网赛事信息”,导入.xlsx、核对草稿并保存;需要公开展示时再开启“公开发布”。 - 从
https://www.yuedongsports.com携带Origin请求正式环境的GET /api/competition/state,确认返回已发布数据或空态,以及允许官网来源的 CORS 响应头。
错误排查
| 状态 | 常见原因 |
|---|---|
401/403 |
后台未登录或无权访问;若由上游返回 403,检查后台服务器私网 IP 是否在 COMPETITION_ADMIN_ALLOWED_IPS 中 |
413 |
PUT 请求体超过 8 MB |
502 |
官网赛事服务无法连接 |
503 |
上游 URL 无效 |
504 |
官网赛事服务超过 30 秒未响应 |
保存时上游的字段校验错误会原样返回,管理页会展示错误信息。
验证
dotnet build .\YD_Event.Web.Entry\YD_Event.Web.Entry.csproj --no-restore
确认官网赛事服务的 /api/competition/ping 返回成功;使用已有后台登录态访问 GET /api/website-competition,应返回上述赛事结构。未经登录直接访问应被后台认证拒绝。PUT 应先在测试环境使用草稿数据验证,再按发布流程操作。
匿名访问 GET /api/competition/state 应返回公开空态或已发布数据。若返回 404,检查新控制器是否已部署,以及 Nginx 是否仍使用直接代理赛事服务的旧片段;若返回 502,检查私网连接及 CompetitionApi__AdminUrl。