Gaming/GameCenter/Architecture

From MozillaWiki
Jump to: navigation, search

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.