Penyimpanan data Open Cloud

*Konten ini diterjemahkan menggunakan AI (Beta) dan mungkin mengandung kesalahan. Untuk melihat halaman ini dalam bahasa Inggris, klik di sini.

Selain mengakses penyimpanan data dari Engine API di Studio atau permainan langsung (DataStoreService), Anda dapat menggunakan Open Cloud API untuk mengakses penyimpanan data standar dan penyimpanan data terurut dari skrip eksternal dan alat lainnya.

Akses Open Cloud ke penyimpanan data Anda membuka berbagai kemungkinan penggunaan, termasuk:

  • Portal dukungan pelanggan yang memungkinkan tim Anda menangani permintaan dukungan secara langsung, seperti memodifikasi inventaris pengguna atau mengeluarkan pengembalian dana
  • Papan peringkat global yang dapat Anda tampilkan di situs web eksternal
  • Pembaruan skema dengan skrip yang membaca entri dari penyimpanan data saat ini, memetakan ke skema baru, dan menulis entri kembali ke penyimpanan data baru

Contoh-contoh di halaman ini menunjukkan cara membangun portal dukungan inventaris pengguna dan papan peringkat eksternal dengan Node.js dan Python, tetapi gunakan bahasa yang Anda suka; Open Cloud API mendukung bahasa pemrograman apa pun yang dapat mengirimkan permintaan HTTP.

Perbedaan dari Engine API

Meskipun Open Cloud API mengakses penyimpanan data yang sama dan mirip dengan bekerja dengan DataStoreService, ada beberapa perbedaan kunci:

  • ID Universe: Berbeda dengan Engine API, Open Cloud API bersifat stateless dan dapat berasal dari mana saja, sehingga Anda harus selalu memberikan ID universe, pengidentifikasi unik untuk permainan Anda.

  • Izin terpisah untuk membuat dan memperbarui: Engine API membuat entri baru jika tidak ada saat Anda memanggil DataStore:SetAsync(), tetapi metode Open Cloud untuk membuat dan memperbarui entri terpisah. Izin terpisah bisa lebih aman dan lebih fleksibel dalam situasi tertentu. Misalnya, Anda mungkin ingin alat dukungan pelanggan Anda hanya dapat mengedit profil pengguna yang ada, bukan membuat yang baru.

  • Serialisasi data: Semua endpoint Open Cloud mengharuskan Anda untuk mensyaratkan data sebelum mengirimkannya. Serialisasi berarti mengubah objek menjadi string. Deserialisasi adalah sebaliknya, mengubah string menjadi objek. Engine API secara otomatis mensyaratkan dan mendeserialisasi konten entri, tetapi untuk Open Cloud, Anda harus menghasilkan atau mengurai entri Anda ke dan dari JSON sendiri.

Izin

Penyimpanan data sering menyimpan informasi sensitif, seperti profil pengguna dan mata uang virtual. Untuk menjaga keamanan, setiap metode Open Cloud memiliki izin yang sesuai, yang disebut ruang lingkup, yang harus Anda tambahkan ke kunci API Anda, seperti ruang lingkup universe-datastores.control:list untuk metode List Data Stores. Jika Anda tidak menambahkan izin yang diperlukan, panggilan API Anda akan mengembalikan kesalahan. Lihat dokumentasi referensi untuk ruang lingkup yang diperlukan untuk setiap endpoint.

Untuk informasi lebih lanjut tentang mengelola izin, lihat Kelola kunci API.

Portal dukungan inventaris pengguna

Contoh ini menggunakan penyimpanan data bernama Inventory dan skema untuk setiap entri dari "userId": {"currency": number, "weapon": string, "level": number}. Kuncinya adalah userId.

Ruang lingkup yang diperlukan

Saat membuat Kunci API untuk contoh ini, tambahkan ruang lingkup berikut ke kunci Anda:

  • universe-datastores.objects:list
  • universe-datastores.objects:read
  • universe-datastores.objects:update

Secara opsional, tambahkan izin hanya untuk penyimpanan data Inventory, atur pembatasan alamat IP, dan atur tanggal kedaluwarsa.

Tambahkan skrip untuk portal dukungan inventaris pengguna

Setelah membuat kunci API dengan izin yang diperlukan untuk aplikasi contoh, Anda dapat membuat skrip untuk membuat permintaan ke endpoint. Skrip ini mengambil 10 entri pertama dalam penyimpanan data, menambahkan nilai currency untuk masing-masing sebanyak 10, dan kemudian memperbarui setiap entri. Untuk penyimpanan data yang lebih besar, Anda harus menangani paginasi menggunakan parameter kueri maxPageSize dan pageToken.

incrementCurrency.js

const apiKey = process.env.API_KEY;
if (!apiKey) {
throw new Error('Variabel lingkungan API_KEY tidak disetel.');
}
const apiHeaderKey = 'x-api-key';
const universeId = '';
const dataStoreId = 'Inventory';
const baseUrl = 'https://apis.roblox.com/cloud/v2/';
async function listEntries(universe, dataStore) {
const listPath = `universes/${universe}/data-stores/${dataStore}/entries`;
const url = baseUrl + listPath;
const response = await fetch(url, {
headers: { [apiHeaderKey]: apiKey }
});
return response.json();
}
async function getEntry(path) {
const url = baseUrl + path;
const response = await fetch(url, {
headers: { [apiHeaderKey]: apiKey }
});
return response.json();
}
async function updateEntry(path, payload) {
const url = baseUrl + path;
const response = await fetch(url, {
method: 'PATCH',
headers: {
[apiHeaderKey]: apiKey,
'Content-Type': 'application/json'
},
body: JSON.stringify(payload) // Badan harus berupa string
});
return response;
}
(async () => {
try {
const entries = await listEntries(universeId, dataStoreId);
for (const entry of entries.dataStoreEntries) {
const path = entry.path;
console.log(`\nMemproses entri: ${path}`);
const currentData = await getEntry(path);
currentData.value.currency += 10;
const payload = { value: currentData.value };
const updateResponse = await updateEntry(path, payload);
console.log(`Status: ${updateResponse.status}`);
console.log(`Respons: ${await updateResponse.text()}`);
}
} catch (error) {
console.error('Terjadi kesalahan selama eksekusi:', error);
}
})();

Untuk menguji, atur variabel lingkungan API_KEY, instal dependensi, dan jalankan skrip:


export API_KEY=<your_key>
node incrementCurrency.js

Papan peringkat eksternal yang persisten

Contoh ini membuat daftar pengguna yang telah ditentukan sebelumnya untuk tujuan demo, tetapi agar bermanfaat dalam permainan yang sebenarnya, Anda memerlukan penyimpanan data pengguna yang sebenarnya.

Ruang lingkup yang diperlukan

Saat membuat Kunci API untuk contoh ini, tambahkan ruang lingkup berikut ke kunci Anda:

  • universe.ordered-data-store.scope.entry:read
  • universe.ordered-data-store.scope.entry:write

Tambahkan skrip untuk papan peringkat

Setelah membuat kunci API dengan izin yang diperlukan untuk aplikasi contoh, Anda dapat membuat skrip untuk membuat permintaan ke endpoint. Skrip-skrip ini menambahkan beberapa entri contoh ke penyimpanan data terurut dengan angka acak dan kemudian mengambilnya dari nilai tertinggi ke terendah. Untuk penyimpanan data yang lebih besar, Anda harus menangani paginasi menggunakan parameter kueri maxPageSize dan pageToken.

leaderboard.js

const apiKey = process.env.API_KEY;
const apiHeaderKey = 'x-api-key';
const universeId = '';
const orderedDataStoreId = 'PlayerScores';
const scopeId = 'global';
const baseUrl = 'https://apis.roblox.com/cloud/v2/';
async function createOrderedEntry(universe, orderedDataStore, entryId, payload) {
const createPath = `universes/${universe}/ordered-data-stores/${orderedDataStore}/scopes/${scopeId}/entries`;
const url = new URL(baseUrl + createPath);
url.searchParams.append('id', entryId);
const response = await fetch(url, {
method: 'POST',
headers: {
[apiHeaderKey]: apiKey,
'Content-Type': 'application/json',
},
body: JSON.stringify(payload),
});
if (!response.ok) {
const errorText = await response.text();
throw new Error(`Kesalahan API (${response.status}): ${errorText}`);
}
return response.text();
}
async function listOrderedEntries(universe, orderedDataStore) {
const listPath = `universes/${universe}/ordered-data-stores/${orderedDataStore}/scopes/${scopeId}/entries`;
const url = new URL(baseUrl + listPath);
url.searchParams.append('orderBy', 'value desc');
return fetch(url, {
headers: {
[apiHeaderKey]: apiKey,
},
});
}
async function main() {
if (!apiKey) {
console.error('Kesalahan: Variabel lingkungan API_KEY tidak disetel.');
process.exit(1);
}
const entryNames = ['Ragdoll', 'Balinese', 'Tabby', 'Siamese'];
console.log('Membuat data contoh...');
for (const name of entryNames) {
try {
const randomValue = Math.floor(Math.random() * 50) + 1;
const payload = { value: randomValue };
const responseText = await createOrderedEntry(universeId, orderedDataStoreId, name, payload);
console.log(responseText);
} catch (error) {
console.error(`Gagal membuat entri untuk "${name}": ${error.message}`);
}
}
console.log('\nMengambil daftar entri yang disortir...');
try {
const playerScoresResponse = await listOrderedEntries(universeId, orderedDataStoreId);
console.log(playerScoresResponse.status);
const responseText = await playerScoresResponse.text();
console.log(responseText);
} catch (error) {
console.error(`Gagal untuk mendaftar entri: ${error.message}`);
}
}
main();

Untuk menguji, atur variabel lingkungan API_KEY, instal dependensi, dan jalankan skrip:


export API_KEY=<your_key>
node leaderboard.js
©2026 Roblox Corporation. Roblox, logo Roblox, dan Powering Imagination termasuk dalam merek dagang kami yang terdaftar dan tidak terdaftar di AS dan negara lainnya.