Permalink
Switch branches/tags
Find file Copy path
Fetching contributors…
Cannot retrieve contributors at this time
85 lines (60 sloc) 8.51 KB

AzureFunctionsNodeLeaderboards-Cosmos

Software License Build Status PRs Welcome unofficial Google Analytics for GitHub

This project is a starter kit that allows you to set up a RESTful API service that stores game leaderboards (scores) and exposes them via HTTP(s) methods/operations. A game developer can use this API service in their game and post new scores, get the top scores, find out the latest ones and more. A Unity client is also provided. You can read some of the thought process that drove the creation of this project in the blog post here.

Deployment

One-click deployment via Azure ARM template is supported, click the button below to deploy the project in your Azure subscription using Azure Functions Consumption Plan.

with Consumption Plan

The deployment will take some time to execute (due to resources' creation and time to pull code from GitHub), please be patient. Be aware that App name, Storage account name and Cosmos DB database name must all be globally unique. Otherwise, the deployment will fail to complete and you will see an error message in the Azure portal. In this case, you should delete the created Resource Group and try again.

If you do want to deploy the project using Azure Functions App Service Plan, use the button below:

with App Service Plan

High level architecture

The technology/architecture stack includes an Express Node.js app hosted on an Azure Function that talks to a Cosmos DB database via its MongoDB API. Azure Application Insights service is used to provide information and metrics regarding application performance and behavior. A Unity game engine client is also provided, with a relevant SDK to access the leaderboards API.

alt text

On the software side of things, Mongoose is used to facilitate interactions between the JavaScript code and the database whereas the frontend API calls are served by Express web framework. Also, the azure-functions-express package is used to facilitate the usage of Express framework within an Azure Function.

Designing the leaderboard

Leaderboards within games can easily vary. In designing this library, we tried to satisfy the below requirements:

  • store all scores for all users (of course!)
  • a score object is immutable (so you will not find any update methods here)
  • we need to easily get the top score of each user
  • we need to easily get the latest scores of each user
  • we need to easily get the top scores for today
  • we need to easily get the top scores of all time, along with the users that got them
  • we need to easily get the surrounding ranked players along with their top score compared to our user
  • authentication and authorization are not implemented (but hints and guidelines on how to add these mechanisms are provided)

Usage

After you deploy the script, you will have an Azure Resource Group containing the following resources:

  • A Cosmos DB database that uses the MongoDB API
  • A Storage Account
  • An App Service Name that hosts the Azure Function with its relevant App Service Plan
  • The Azure Function that will pull the code from the GitHub repo you designate and an Application Insights service to monitor its execution

Now, you can call the available web service operations from your game. You can visit the Azure Portal to get the Azure Function URL, it will be in the format https://functionName.azurewebsites.net

Authentication

All requests to the leaderboards API must contain two headers on each request: x-ms-client-principal-id and x-ms-client-principal-name. If these values are missing, then the request will fail. The x-ms-client-principal-id should be unique for each user. Meaning, each time you use the same x-ms-client-principal-id for inserting a new score, this score will belong to the same user. The implemented leaderboards API does not impose any method to validate/verify these values, so you are free to implement whatever you like. However, App Service supports various authentication methods which automatically set the required headers, you can check them here. The Unity client sample in this repo contains code to set these headers with current user's details. For more details on authentication/authorization, please check the tech details file here.

Operations supported

Here you can see a short list/summary of all the operations that are supported, check here for full details and response samples. Some operations support skipping via a skip query string parameter, check the operations page for details.

VERB URL Description
POST https://functionURL/api/scores Creates a new score. Post body has the format { "value":Integer value of the score, ... }. Returns the updated user details.
GET https://functionURL/api/users/:userId Gets a specific user's details, including top score and latest scores
GET https://functionURL/api/user/scores/:count Gets the top 'count' scores for logged in user sorted by score value
GET https://functionURL/api/scores/top/:count Gets top scores achieved in the game by all users, in descending order. This can include more than one score per user
GET https://functionURL/api/users/maxscore/:count Gets the scores achieved by each unique user, in descending order. Practically this includes the max score per single user
GET https://functionURL/api/scores/today/top/:count Gets the top 'count' scores for today
GET https://functionURL/api/users/toptotaltimesplayed/:count Gets the top 'count' users for all time in regards to the times they have played (i.e. number of times they have posted a new score).
GET https://functionURL/api/scores/latest/:count Gets the latest 'count' scores
GET https://functionURL/api/scores/:scoreID Gets a specific score
GET https://functionURL/api/users/surroundingbyscore/:userId/:count Gets the surrounding users of the requested one, ordered by their max score
GET https://functionURL/api/health Gets the application's health

Docker

You might notice that there is a Dockerfile inside the Azure Functions code. Check the docs/technicalDetails.md file for instructions on how to build and run the project on a Docker container and on a Kubernetes cluster.

More details

  • Check the docs/FAQ.md for answers to common questions you may have about the project.
  • Check the docs/operations.md for the list of all supported HTTP methods of the leaderboards API.
  • Check the docs/technicalDetails.md for various technical details of the project.

License

This project is licensed under the MIT License.