數據儲存的使用指南

*此內容是使用 AI(Beta 測試版)翻譯,可能含有錯誤。若要以英文檢視此頁面,請按一下這裡

除了使用工程 API( )在 Studio 或生產伺服器上存取數據庫外,您還可以使用開放雲端 API 存取和使用標準和訂購數據庫從外部腳本和工具與粒度存取和安全控制。

使用

您可以使用這些 API 存取您的資料來改善工作流程的多個區域,例如:

  • 客戶支持門戶 : 資料儲存有用於儲存持久用戶資源,例如使用者庫中的物品或技能點。有時候您需要更新這些資源以支客服、客服人員戶。您可以建立一個網站應用程式,讓客戶服務代理直接處理客戶支持請求,例如查看和修改使用者庫存和發出退款。而不是使用 Studio 或手動加入體驗,您可以建立一個網站應用程式來允許您的客戶服務代理直接處理客戶支持請求,例如查看和修改使用者庫存和發出退款。

  • LiveOps 面板 : 您可以使用 API 構建 LiveOps 面板,以提高實時操作的效率。例如,您可能會預先安排一個事件,將其隱藏在功能旗下,作為數據商店 商家存中配置數據的一部分,並設置一個時間來轉換旗幟以發布事件。您的經驗伺服器可以透過閱讀旗幟來偵測此變更,以啟動事件。

  • 外部排行榜 :若要在 Roblox 之外促銷您的經驗,您可以在實時間間拉取經體驗資訊,例如賽事排行榜,並在外部網站上顯示它。您可以授予訂購的數據儲存庫對網站定期請求最新數據通過 HTTP 並更新網頁。

  • 數據轉移自動化 :數據可能會隨著體驗的發展而更改或更新,例如升級數據模型以容納新功能。為了避免損失現有使用者資料,有時您需要將數據存儲從舊的資料庫遷移到新的資料庫。您可以寫一個外部腳本來閱讀當前數據存儲庫中的每個入口,將數據映射到新的模型,然後將入口寫回新的數據存儲庫來自動化數據遷移。

與引擎 API 的差異

雖然開放雲端 API 與 DataStoreService 相似,但有一些關鍵差異:

  • 宇宙ID和數據儲存名稱 : 與引擎API不同,開放雲端API是非狀態的,來自任何地方,因此您必須始終提供 宇宙ID ,您體驗的唯一標識,以及數據儲存名稱 名稱 ,當發送請求時。要了解如何獲得宇宙ID的更多信息,請參閱宇宙ID

  • 分開創建和更新權限 : 引擎 API 在您呼叫 DataStore:SetAsync() 時,如果它們不存在,會創建新記錄,但創建和更新入口的開放雲方法是分開的。在某些情況下,分離許可可能更安全和更靈活。例如,您可以創建一個客戶支持工具,可以編輯現有用戶的個人個人檔案料,但無法創建新用戶的個人資個人檔案。

  • 數據序列化 :所有開放雲端端點都需要在網絡傳輸之前將所有數據序列化。序列化意味著將對象轉換為字串。反序列化是相反的(將字串轉換為對物件)。引擎 API 會自動將入口內容序列化和反序列化,但對於開放雲端,您需要擁有行生成或解析您的入口資料以 JSON 。

安全權限

數據庫經常儲存敏感信息,例如使用者個人檔案和虛擬貨幣。為了維持安全,每個開放雲端 API 都有相應的必須權限,您必須將其添加到 API 鑰鍵中,例如列出 API 的 List Keys 權限。如果您未添加所需的權限,您的 API 呼叫將返回錯誤。對於每個操作所需的特定權限,請參閱 標準訂購數據儲存 API 參考。

配置您的 API 鑰匙 時,您可以為特定體驗內的每個數據存儲設置粒度權限,例如已讀、寫入和列出入口,或者您可以給出鑰匙來閱讀或寫入體驗內的所有數據存儲。您也可以限制對工具所需的數據儲存子集的存取,而不是直接暴露所有數據儲存。這樣可以減少鑰匙洩露的影響。

構建工具

您可以使用自己選擇的語言來構建工具,以 開啟雲端API為數據存儲提供服務 來滿足操作需求。以下例子會通過在 Python 使用標準數據存儲和排序數據存儲來建立 使用者庫支持門戶 的過程,使用外部持久排行榜來使用排序數據存儲。

使用者庫存支援網站

本節提供了在 Python 中建立使用者庫支持網站的具體例子,您可以在其中列出並閱讀一部分使用者庫的道具欄、進行編輯,然後更新回經體驗的資料儲存商店 商家。

對於這個例子,假設以追蹤中內容:

  • 儲存使用者庫存的數據儲存名稱是 Inventory

  • 每個數據入口的數據模型是 "userId": {"currency": number, "weapon": string, "level": number} 。關鍵是只有 userId

  • Python 腳本列出基於前缀的用戶庫存子集,在促銷期間將其虛擬貨幣增加 10,並更新數據。

從高等級來看,您可以通過添加 API 鑰匙許可和添加腳本來構建 Python 應用程式。

為數據存儲添加 API 鑰匙許可

為此範例創建 API 鑰匙 時,請確保執行以下設定:

  1. 選擇 API 系統 選單中,在 存取權限 部分選擇 宇宙資料儲存器

  2. (可選)數據儲存 部分中,選擇特定數據儲存的 API 操作。

    1. 啟用 特定資料儲存操作 切換。預設情況下,五個資料儲存自動載入,但您可以通過 +新增資料儲存到列表 按鈕來添加額外的資料儲存。
    2. 選擇資料商店 商家存環境名稱旁的下拉箭頭,然後選擇您希望資料儲存獲得存取的 API 操作。
  3. 選擇整個體驗的 API 操作。

    1. 點擊 選擇體驗以添加 下拉選單,然後選擇一個體驗。
    2. 體驗操作 中,單擊下拉箭頭並選擇您想要添加到 API 的操作。這個例子選擇 閱讀入口 , 更新入口 , 以及 列出入口鑰匙 對整個體驗。
  4. 安全 部分中,明確設置 IP 存取到鑰匙使用 CIDR記號,並設置明確的過期日期,以便您的鑰匙在那之後自動停止工作。在這個例子中,如果你打算先進行本地測試,你可以將 IP 限制設為 0.0.0.0/0 並讓它在 30 天內過期

新增用戶庫存支持網站的腳本

創建了 API 鑰匙與示例應用App式所需的權限後,您需要添加 JavaScript 代碼來執行應用程式功能。該 文件顯示如何定義 , 和 方法。update_inventory.js 文件使用定義的方法來列出用戶庫存的子集,增加每個用戶的虛擬貨幣,並更新數據。

dataStoresMethods.js

const fetch = require('node-fetch');
class DataStores {
constructor() {
this._baseUrl =
'https://apis.roblox.com/datastores/v1/universes/{universeId}';
this._apiKey = process.env.API_KEY;
this._universeId = 'UNIVERSE_ID';
this.ATTR_HDR = 'Roblox-entry-Attributes';
this.USER_ID_HDR = 'Roblox-entry-UserIds';
this._objectsUrl = `${this._baseUrl}${this._universeId}/standard-datastores/datastore/entries/entry`;
this._incrementUrl = `${this._objectsUrl}/increment`;
this._listObjectsUrl = `${this._baseUrl}${this._universeId}/standard-datastores/datastore/entries`;
}
async _getHeaders() {
return { 'x-api-key': this._apiKey };
}
async getEntry(datastore, objectKey, scope = null) {
const url = `${
this._objectsUrl
}?datastoreName=${datastore}&entryKey=${objectKey}&scope=${scope || ''}`;
const response = await fetch(url, { headers: await this._getHeaders() });
const data = await response.json();
return data;
}
async listEntries(datastore, scope = null, prefix = '', limit = 100) {
const url = `${this._listObjectsUrl}?datastoreName=${datastore}&scope=${scope}&prefix=${prefix}&limit=${limit}`;
const response = await fetch(url, { headers: await this._getHeaders() });
const data = await response.json();
return data;
}
async incrementEntry(datastore, objectKey, incrementBy, scope = null) {
const url = `${
this._incrementUrl
}?datastoreName=${datastore}&entryKey=${objectKey}&incrementBy=${incrementBy}&scope=${
scope || ''
}`;
const response = await fetch(url, {
method: 'POST',
headers: await this._getHeaders(),
});
const data = await response.json();
return data;
}
}
module.exports = DataStores;
updateInventory.js

const DataStores = require('./dataStoresMethods');
const dataStoresApi = new DataStores();
// Set up
const datastoreName = 'Inventory';
// List keys for a subset of users
dataStoresApi.listEntries(datastoreName).then((keys) => {
console.log(keys);
});
// Read inventory for each user
for (let x = 0; x < 5; x++) {
const updatedObjectKey = `User_${x + 1}`;
dataStoresApi.getEntry(datastoreName, updatedObjectKey).then((value) => {
console.log(
`${updatedObjectKey} has ${value.gems} gems in their inventory`
);
});
}
// Update the currency of each user by 10
for (let x = 0; x < 5; x++) {
const updatedObjectKey = `User_${x + 1}`;
dataStoresApi
.incrementEntry(datastoreName, updatedObjectKey, 10)
.then((value) => {
console.log(
`${updatedObjectKey} now has ${value.robux} robux in their inventory`
);
});
}

要測試,設置 API_KEY 環境變量並執行 JavaScript 檔案:


export API_KEY=... \
node updateInventory.js

外部永久排行榜

本節將介紹在 Python 中創建外部永久排行榜的具體示例,在其中您可以列出並閱讀儲存在排序數據儲存中的用戶信息,進行編輯,然後發布到外部網站進行促銷。

對於這個例子,假設以追蹤中內容:

  • 代碼示例創建了預定義的用戶名列表用於演示目的。對於自己的應用程式,您應該使用經體驗中的實際使用者清單。

  • 代碼示例會向每個加入體驗的使用者新增 50 分,以用於演示目的。對於自己的應用程式,您應該根據經驗設計來定義規則。

從高等級來看,您可以通過添加 API 鑰匙許可和添加腳本來構建 Python 應用程式。

為訂購的數據儲存提供 API 鑰匙許可

示例應用程式需要四個方法來實現其功能:List , Create , UpdateIncrement , 因此您需要添加以下 API 鑰匙權限:

  • 閱讀 對於 list 方法。
  • 對於 CreateUpdateIncrement 方法。

為此範例創建 API 鑰匙 時,請確保執行以下操作:

  1. 選擇 API 系統 選單中,在 存取權限 部分選擇 排序的資料儲存

  2. 添加 API 操作的權限以在目標體驗中閱讀和寫入排序的數據儲存。

    1. 點擊 選擇體驗以添加 下拉選單,然後選擇目標體驗。
    2. 體驗操作 中,擴展下拉選單以選擇 閱讀寫入 操作。
  3. 安全 部分中,明確設置 IP 存取到鑰匙使用 CIDR記號,並設置明確的過期日期,以便您的鑰匙在那之後自動停止工作。在這個例子中,如果你打算先進行本地測試,你可以將 IP 限制設為 0.0.0.0/0 並讓它在 30 天內過期

添加排行榜的腳本

創建了 API 鑰匙與示例應用程App所需的權限後,您需要添加 JavaScript 代碼來執行應用程式功能。

該 文件顯示如何定義 , , ,和 方法。leaderboard.js 文件使用定義的方法來創建排序的數據存儲中的用戶入口、顯示分數、增加獲勝用戶的分數和更新排行榜。leaderboard.js也會匯入一個config.json來配置宇宙ID、API域和您的API鑰鍵。

ordered_data_stores.js

const axios = require('axios');
const fs = require('fs');
class DataStores {
constructor(configFile) {
this._config = JSON.parse(fs.readFileSync(configFile, 'utf-8'));
}
_H() {
return {
'x-api-key': this._config.api_key,
'Content-Type': 'application/json',
};
}
async list(
datastore,
scope,
pageSize = 10,
orderBy = '',
filter = '',
exclusiveStartKey = ''
) {
const url = `${this._config.api_key_url}universes/${this._config.universe_id}/orderedDataStores/${datastore}/scopes/${scope}/entries`;
const response = await axios.get(url, {
headers: this._H(),
params: {
max_page_size: pageSize,
order_by: orderBy,
filter: filter,
page_token: exclusiveStartKey,
},
});
return response.data;
}
async create(datastore, scope, entry, data) {
const url = `${this._config.api_key_url}universes/${this._config.universe_id}/orderedDataStores/${datastore}/scopes/${scope}/entries`;
const payload = JSON.stringify({ value: 11 });
const response = await axios.post(url, payload, {
headers: this._H(),
params: { id: entry },
});
return response.data;
}
async increment(datastore, scope, entry, incrementBy) {
const url = `${this._config.api_key_url}universes/${this._config.universe_id}/orderedDataStores/${datastore}/scopes/${scope}/entries/${entry}:increment`;
const payload = JSON.stringify({ amount: incrementBy });
const response = await axios.post(url, payload, { headers: this._H() });
return response.data;
}
}
leaderboard.js

const leaderboardEndpoints = require('./ordered_data_stores');
const datastores = new leaderboardEndpoints.DataStores('config.json');
// Variables
const orderedDataStore = 'PlayerScores';
const scope = 'global';
const entryNames = ['Ragdoll', 'Balinese', 'Tabby', 'Siamese'];
// Create an entry and give each new player 50 points for joining the game
entryNames.forEach(async (name) => {
await datastores.create(orderedDataStore, scope, name, 50);
});
// Display the players' scores
datastores.list(orderedDataStore, scope).then((playerScores) => {
console.log(playerScores);
});
// Increment the first player's score for winning the game
datastores.increment(orderedDataStore, scope, entryNames[0], 100);
// Increment all the players' scores for participating in the game
entryNames.forEach(async (name) => {
await datastores.increment(orderedDataStore, scope, name, 10);
});
// Display the updated leaderboard
datastores.list(orderedDataStore, scope).then((updatedPlayerScores) => {
console.log(updatedPlayerScores);
});
設定

{
"universe_id": "",
"api_key_url": "https://apis.roblox.com/datastores/ordered-v1/",
"api_key": ""
}

要測試,設置 API_KEY 環境變量並執行 leaderboard.js 檔案:


export API_KEY=... \
node leaderboard.js

完成測試後,您可以發布或埋入排行榜到 Roblox 以外的網站上,以獲得更多覆蓋率。