跳到內容

伺服器與版本

本頁介紹高階 server-scoped contract。普通消費者直接使用 /api/v1/songs 等 alias;省略 server 時,它們讀取 intl 的當前資料。

GET /api/v1/releases
尚未傳送
GET /api/v1/releases
HEAD /api/v1/releases

歷史 route name 保留用於相容。回應列出活動 server slug 和顯示資訊:

{
"releases": [
{ "id": "intl", "displayName": "Global", "region": "global" },
{ "id": "jp", "displayName": "JP", "region": "jp" }
]
}

此回應中的 id 是 server slug,用於 ?server= 和顯式 server-scoped 路由的 {server}。當部署新增或停用 server 時,列表會變化。

GET /api/v1/servers/{server}/release
尚未傳送
GET /api/v1/servers/{server}/release
GET /api/v1/servers/{server}/release?projection=identity

完整 manifest 描述 release 的 catalog、source tree、game-client inventory 和檔案。工具只需要記錄所選 release 時,可使用 projection=identity 返回的 compact descriptor:

{
"schema": "haneoka-resource-release-identity-v1",
"server": "intl",
"releaseId": "r-0123456789abcdef0123",
"sourceId": "source-snapshot-id"
}

releaseId 是服務返回的不透明值。上面的 JSON 使用結構示意值;實際請求先讀取當前 identity。

每個 server-scoped catalog、source 和 release route 都接受 release query:

const base = "https://haneoka.org/api/v1/servers/intl/";
const identityResponse = await fetch(`${base}release?projection=identity`);
if (!identityResponse.ok) throw new Error(`Identity HTTP ${identityResponse.status}`);
const identity = await identityResponse.json();
const query = new URLSearchParams({ release: identity.releaseId });
const response = await fetch(`${base}songs/100001?${query}`);
if (!response.ok) throw new Error(`Song HTTP ${response.status}`);
console.log(await response.json(), response.headers.get("X-Haneoka-Release-Id"));

回應包含 X-Haneoka-Release-Id 和 X-Haneoka-Source-Id。需要審計的 archive 應將這些 headers 與下載資料一起儲存。無效 release 返回 404 release_not_found;未固定請求使用 server 的當前 pointer。

Release media 和 game-client 檔案也由活動 server pointer 選擇。Content-addressed artifact route 顯式使用 source ID。請參閱媒體與檔案、Game-client和Source tree。

當 build 必須重現過去的產物、crawler 儲存完整 snapshot,或工具需要 release 的 storage descriptor 時固定 release。顯示當前歌曲、活動或劇情的 web app 可以繼續使用直接 alias,讓每次請求讀取當前 catalog。