Gaming/GameCenter/Architecture: Difference between revisions

From MozillaWiki
Jump to navigation Jump to search
(Created page with "Any architectural decisions (e.g., language, database, data models, API) should be noted on this page. = Languages = Galaxy prototypes have been written in Node.js, but the l...")
 
(remove python)
 
(5 intermediate revisions by 2 users not shown)
Line 2: Line 2:


= Languages =
= Languages =
Galaxy prototypes have been written in Node.js, but the language choice should still be discussed.
The backend architecture (galaxy-api) is written in Node.js.


Below is a list of pros/cons of Node.js and Python (a possible candidate for the Game Center).
[For real-time, socket-based parts, we should also consider Go]


== Node.js ==
== Node.js ==
=== Pros ===
=== Pros ===
* Galaxy API prototypes have been written in Node.js
* Mozilla has deployed Node.js projects to scale (e.g., Persona, FxA)
* Mozilla has deployed Node.js projects to scale (e.g., Persona, FxA)
* Node community is vibrant
* Node community is vibrant
Line 20: Line 21:
* Event-driven, asynchronous; callbacks are a pain (but we have promises!)
* Event-driven, asynchronous; callbacks are a pain (but we have promises!)
* Few mature SQL ORMs (Knex, Bookshelf, Sequelize are decent); NoSQL is usually preferred
* Few mature SQL ORMs (Knex, Bookshelf, Sequelize are decent); NoSQL is usually preferred
== Python ==
=== Pros ===
* Mozilla has deployed Python projects to scale (e.g., AMO, Marketplace)
* SQL ORMs are mature (SQLAlchemy, Django ORM)
* Frameworks are fantastic (Flask, Django)
* Synchronous code (easy to write)
* Mature libraries (and well-documents too)
* Strong community
* Simple syntax (makes it easier to write things elegantly)
=== Cons ===
* Synchronous, blocking code
* Real-time, socket network is unnatural and difficult (forced to use such libraries as Tornado/Twisted/gevent)
* Throughput (requests per second) can be lower than Node.js's (depending on which benchmark you read)


= Data Models =
= Data Models =
Line 57: Line 43:
== Redis ==
== Redis ==
* LeaderboardScore
* LeaderboardScore
** Sorted set for each leaderboard (where key is `LeaderboardInfo.id`, score is score, member is `User`.id)
** Sorted set for each leaderboard (where key is <code>LeaderboardInfo.id</code>, score is <code>score</code>, member is <code>User.id</code>)
 


= API =
= API =

Latest revision as of 23:18, 8 September 2014

Any architectural decisions (e.g., language, database, data models, API) should be noted on this page.

Languages

The backend architecture (galaxy-api) is written in Node.js.

[For real-time, socket-based parts, we should also consider Go]

Node.js

Pros

  • Galaxy API prototypes have been written in Node.js
  • Mozilla has deployed Node.js projects to scale (e.g., Persona, FxA)
  • Node community is vibrant
  • JavaScript would be both on the server and the client, easing context switching and contributors (hopefully)
  • WebSocket libraries are fantastic (WS, Socket.io), among other composable networked components
  • Everything is event-driven, asynchronous
  • Excellent for real-time apps with high throughput and low latency (and some/most gaming services may need to be real time)
  • Learned from previous languages/environment’s mistakes (e.g., npm for package management)
  • Frameworks are fantastic (Express, Koa, Restify)
  • Very fast (with V8)

Cons

  • Event-driven, asynchronous; callbacks are a pain (but we have promises!)
  • Few mature SQL ORMs (Knex, Bookshelf, Sequelize are decent); NoSQL is usually preferred

Data Models

PostgreSQL

  • Game
    • id
    • name
    • slug
    • app_url
  • User
    • id
    • email
    • username
  • LeaderboardInfo
    • id
    • name
    • slug

Redis

  • LeaderboardScore
    • Sorted set for each leaderboard (where key is LeaderboardInfo.id, score is score, member is User.id)

API

Full documentation will live elsewhere, but this is the tentative API structure.

Game

GET /games
Retrieve a list of all public games.

POST /games
Create a new game. Name, slug, and URL are required in a JSON payload.

GET /games/:game_slug
Retrieve a single game.

PATCH /games/:game_slug
Update a game’s info based on the fields specified in the JSON payload.

PUT /games/:game_slug
Replace a game’s data with all of the data in the JSON payload.

DELETE /games/:game_slug
Delete a single game.

Leaderboard

GET /games/:game_slug/leaderboards
Retrieve a list of all leaderboards’ names+slugs for a particular game.

POST /games/:game_slug/leaderboards
Create a new leaderboard for a particular game. Name and slug are required in a JSON payload.

GET /games/:game_slug/leaderboards/:board_slug
Retrieve a single leaderboard belonging to some particular game.

PATCH /games/:game_slug/leaderboards/:board_slug
Update a leaderboard’s name or slug based on the fields specified in the JSON payload.

PUT /games/:game_slug/leaderboards/:board_slug
Replace a leaderboard’s name and slug with the data in the JSON payload.

DELETE /games/:game_slug/leaderboards/:board_slug
Delete a single leaderboard.

Leaderboard Score

GET /games/:game_slug/leaderboards/:board_slug/scores
Retrieve a list of all scores for a particular leaderboard.

POST /games/:game_slug/leaderboards/:board_slug/scores
Create a new score for a particular game.

GET /games/:game_slug/leaderboards/:board_slug/scores/:score_id
Retrieve a single score belonging to some particular leaderboard.

PATCH /games/:game_slug/leaderboards/:board_slug/scores/:score_id
Update a score based on `score` field specified in the JSON payload.

PUT /games/:game_slug/leaderboards/:board_slug/scores/:score_id
Replace a score based on `score` field specified in the JSON payload.

DELETE /games/:game_slug/leaderboards/:board_slug/scores/:score_id
Delete a single score.