Skip to content

Commit f7ba637

Browse files
Update usage-data-stores.md
Added a JavaScript Examples to expand on the languages you can use open-cloud for
1 parent c729cbc commit f7ba637

File tree

1 file changed

+192
-0
lines changed

1 file changed

+192
-0
lines changed

content/en-us/cloud/open-cloud/usage-data-stores.md

Lines changed: 192 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,8 @@ When [creating an API Key](./api-keys.md) for this example, make sure you perfor
7878

7979
#### Adding Scripts for the User Inventory Support Portal
8080

81+
##### > Python Example
82+
8183
After creating the API key with permissions required for the example app, you need to add Python scripts to perform app functionalities. The `data_stores_methods.py` file shows how to define [`List Entries`](../../reference/cloud/datastores-api/v1.json#list-entries), [`Get Entry`](../../reference/cloud/datastores-api/v1.json#get-entry), and [`Increment Entry`](../../reference/cloud/datastores-api/v1.json#increment-entry) methods. The `update_inventory` file uses the defined methods to list a subset of user inventories, increase the virtual currency for each user, and update the data.
8284

8385
```python title='data_stores_methods.py'
@@ -187,6 +189,93 @@ export API_KEY=... \
187189
python update_inventory
188190
```
189191

192+
##### > JavaScript Example
193+
194+
After creating the API key with the required permissions for the example app, you need to add JavaScript code to perform app functionalities. The `data_stores_methods.js` file shows how to define [`List Entries`](../../reference/cloud/datastores-api/v1.json#list-entries), [`Get Entry`](../../reference/cloud/datastores-api/v1.json#get-entry), and [`Increment Entry`](../../reference/cloud/datastores-api/v1.json#increment-entry) methods. The `update_inventory.js` file uses the defined methods to list a subset of user inventories, increase the virtual currency for each user, and update the data.
195+
196+
```javascript title='dataStoresMethods.js'
197+
const fetch = require('node-fetch');
198+
199+
class DataStores {
200+
constructor() {
201+
this._baseUrl = "https://apis.roblox.com/datastores/v1/universes/{universeId}";
202+
this._apiKey = process.env.API_KEY;
203+
this._universeId = "UNIVERSE_ID";
204+
this.ATTR_HDR = 'Roblox-entry-Attributes';
205+
this.USER_ID_HDR = 'Roblox-entry-UserIds';
206+
this._objectsUrl = `${this._baseUrl}${this._universeId}/standard-datastores/datastore/entries/entry`;
207+
this._incrementUrl = `${this._objectsUrl}/increment`;
208+
this._listObjectsUrl = `${this._baseUrl}${this._universeId}/standard-datastores/datastore/entries`;
209+
}
210+
211+
async _getHeaders() {
212+
return { 'x-api-key': this._apiKey };
213+
}
214+
215+
async getEntry(datastore, objectKey, scope = null) {
216+
const url = `${this._objectsUrl}?datastoreName=${datastore}&entryKey=${objectKey}&scope=${scope || ''}`;
217+
const response = await fetch(url, { headers: await this._getHeaders() });
218+
const data = await response.json();
219+
return data;
220+
}
221+
222+
async listEntries(datastore, scope = null, prefix = "", limit = 100) {
223+
const url = `${this._listObjectsUrl}?datastoreName=${datastore}&scope=${scope}&prefix=${prefix}&limit=${limit}`;
224+
const response = await fetch(url, { headers: await this._getHeaders() });
225+
const data = await response.json();
226+
return data;
227+
}
228+
229+
async incrementEntry(datastore, objectKey, incrementBy, scope = null) {
230+
const url = `${this._incrementUrl}?datastoreName=${datastore}&entryKey=${objectKey}&incrementBy=${incrementBy}&scope=${scope || ''}`;
231+
const response = await fetch(url, { method: 'POST', headers: await this._getHeaders() });
232+
const data = await response.json();
233+
return data;
234+
}
235+
}
236+
237+
module.exports = DataStores;
238+
```
239+
240+
```javascript title='updateInventory.js'
241+
const DataStores = require('./dataStoresMethods');
242+
const dataStoresApi = new DataStores();
243+
244+
// Set up
245+
const datastoreName = "Inventory";
246+
247+
// List keys for a subset of users
248+
dataStoresApi.listEntries(datastoreName)
249+
.then(keys => {
250+
console.log(keys);
251+
});
252+
253+
// Read inventory for each user
254+
for (let x = 0; x < 5; x++) {
255+
const updatedObjectKey = `User_${x + 1}`;
256+
dataStoresApi.getEntry(datastoreName, updatedObjectKey)
257+
.then(value => {
258+
console.log(`${updatedObjectKey} has ${value.gems} gems in their inventory`);
259+
});
260+
}
261+
262+
// Update the currency of each user by 10
263+
for (let x = 0; x < 5; x++) {
264+
const updatedObjectKey = `User_${x + 1}`;
265+
dataStoresApi.incrementEntry(datastoreName, updatedObjectKey, 10)
266+
.then(value => {
267+
console.log(`${updatedObjectKey} now has ${value.robux} robux in their inventory`);
268+
});
269+
}
270+
```
271+
272+
To test, set the `API_KEY` environment variable and run the JavaScript file:
273+
274+
```bash
275+
export API_KEY=... \
276+
node updateInventory.js
277+
```
278+
190279
### External Persistent Leaderboard
191280

192281
This section walks through a concrete example of creating an external persistent leaderboard in Python, in which you can list and read your users information stored in ordered data stores, make edits, and then publish to an external website for promotion.
@@ -219,6 +308,8 @@ When [creating an API Key](./api-keys.md) for this example, make sure you perfor
219308

220309
#### Adding Scripts for the Leaderboard
221310

311+
##### > Python Example
312+
222313
After creating the API key with permissions required for the example app, you need to add Python scripts to perform app functionalities.
223314

224315
The `ordered_data_stores.py` file shows how to define [`List`](../../reference/cloud/datastores-api/ordered-v1.json#list), [`Create`](../../reference/cloud/datastores-api/ordered-v1.json#create), [`Update`](../../reference/cloud/datastores-api/ordered-v1.json#update) and [`Increment`](../../reference/cloud/datastores-api/ordered-v1.json#increment) methods. The `leaderboard` file uses the defined methods to create entries of users in ordered data stores, display scores, increment scores of winning users, and update the leaderboard. The `leaderboard` file also imports a `config` JSON file for configuring the Universe ID, API domain, and your API key.
@@ -308,3 +399,104 @@ python leaderboard
308399
```
309400

310401
After completing testing, you can publish or embed the leaderboard to websites outside of Roblox for more reach.
402+
403+
##### > JavaScript Example
404+
405+
After creating the API key with the required permissions for the example app, you need to add JavaScript code to perform app functionalities.
406+
407+
The `ordered_data_stores.js` file shows how to define [`List`](../../reference/cloud/datastores-api/ordered-v1.json#list), [`Create`](../../reference/cloud/datastores-api/ordered-v1.json#create), [`Update`](../../reference/cloud/datastores-api/ordered-v1.json#update), and [`Increment`](../../reference/cloud/datastores-api/ordered-v1.json#increment) methods. The `leaderboard.js` file uses the defined methods to create entries of users in ordered data stores, display scores, increment scores of winning users, and update the leaderboard. The `leaderboard.js` file also imports a `config.json` file for configuring the Universe ID, API domain, and your API key.
408+
409+
```javascript title='ordered_data_stores.js'
410+
const axios = require('axios');
411+
const fs = require('fs');
412+
413+
class DataStores {
414+
constructor(configFile) {
415+
this._config = JSON.parse(fs.readFileSync(configFile, 'utf-8'));
416+
}
417+
418+
_H() {
419+
return { 'x-api-key': this._config.api_key, 'Content-Type': 'application/json' };
420+
}
421+
422+
async list(datastore, scope, pageSize = 10, orderBy = "", filter = "", exclusiveStartKey = "") {
423+
const url = `${this._config.api_key_url}universes/${this._config.universe_id}/orderedDataStores/${datastore}/scopes/${scope}/entries`;
424+
const response = await axios.get(url, {
425+
headers: this._H(),
426+
params: { "max_page_size": pageSize, "order_by": orderBy, "filter": filter, "page_token": exclusiveStartKey }
427+
});
428+
return response.data;
429+
}
430+
431+
async create(datastore, scope, entry, data) {
432+
const url = `${this._config.api_key_url}universes/${this._config.universe_id}/orderedDataStores/${datastore}/scopes/${scope}/entries`;
433+
const payload = JSON.stringify({ "value": 11 });
434+
const response = await axios.post(url, payload, {
435+
headers: this._H(),
436+
params: { "id": entry }
437+
});
438+
return response.data;
439+
}
440+
441+
async increment(datastore, scope, entry, incrementBy) {
442+
const url = `${this._config.api_key_url}universes/${this._config.universe_id}/orderedDataStores/${datastore}/scopes/${scope}/entries/${entry}:increment`;
443+
const payload = JSON.stringify({ "amount": incrementBy });
444+
const response = await axios.post(url, payload, { headers: this._H() });
445+
return response.data;
446+
}
447+
}
448+
```
449+
450+
```javascript title='leaderboard.js'
451+
const leaderboardEndpoints = require('./ordered_data_stores');
452+
453+
const datastores = new leaderboardEndpoints.DataStores('config.json');
454+
455+
// Variables
456+
const orderedDataStore = 'PlayerScores';
457+
const scope = 'global';
458+
const entryNames = ['Ragdoll', 'Balinese', 'Tabby', 'Siamese'];
459+
460+
// Create an entry and give each new player 50 points for joining the game
461+
entryNames.forEach(async (name) => {
462+
await datastores.create(orderedDataStore, scope, name, 50);
463+
});
464+
465+
// Display the players' scores
466+
datastores.list(orderedDataStore, scope).then((playerScores) => {
467+
console.log(playerScores);
468+
});
469+
470+
// Increment the first player's score for winning the game
471+
datastores.increment(orderedDataStore, scope, entryNames[0], 100);
472+
473+
// Increment all the players' scores for participating in the game
474+
entryNames.forEach(async (name) => {
475+
await datastores.increment(orderedDataStore, scope, name, 10);
476+
});
477+
478+
// Display the updated leaderboard
479+
datastores.list(orderedDataStore, scope).then((updatedPlayerScores) => {
480+
console.log(updatedPlayerScores);
481+
});
482+
```
483+
484+
```json title='config'
485+
{
486+
"universe_id": "",
487+
"api_key_url": "https://apis.roblox.com/datastores/ordered-v1/",
488+
"api_key": ""
489+
}
490+
```
491+
492+
To test, set the `API_KEY` environment variable and run the `leaderboard.js` file:
493+
494+
```bash
495+
export API_KEY=... \
496+
node leaderboard.js
497+
```
498+
499+
After completing testing, you can publish or embed the leaderboard to websites outside of Roblox for more reach.
500+
501+
502+

0 commit comments

Comments
 (0)