resource11 / game-project-api

A rails API to store tic-tac-toe boards

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

General Assembly Logo

A Tic-tac-toe data store API

An API to store tic-tac-toe game state and let two players compete across the internet. It allows players to register as users of the API and play against other registered users.

The API does not currently validate game states.

API end-points

Verb URI Pattern Controller#Action
POST /sign-up users#signup
POST /sign-in users#signin
DELETE /sign-out/:id users#signout
PATCH /change-password users#changepw
GET /games games#index
POST /games games#create
GET /games/:id games#show
PATCH /games/:id games#update
GET /games/:id/watch games#watch

All data returned from API actions is formatted as JSON.


User actions

Summary:

Request Response
Verb URI body Status body
POST `/sign-up` credentials 201, Created user
400 Bad Request empty
POST `/sign-in` credentials 200 OK user w/token
401 Unauthorized empty
DELETE `/sign-out/:id` empty 201 Created empty
401 Unauthorized empty
PATCH `/change-password/:id` passwords 204 No Content user w/token
400 Bad Request empty

signup

The create action expects a POST of credentials identifying a new user to create, e.g. using FormData:

<form>
  <input name="credentials[email]" type="text" value="an@example.email">
  <input name="credentials[password]" type="password" value="an example password">
  <input name="credentials[password_confirmation]" type="password" value="an example password">
</form>

or using JSON:

{
  "credentials": {
    "email": "an@example.email",
    "password": "an example password",
    "password_confirmation": "an example password"
  }
}

The password_confirmation field is optional.

If the request is successful, the response will have an HTTP Status of 201, Created, and the body will be JSON containing the id and email of the new user, e.g.:

{
  "user": {
    "id": 1,
    "email": "an@example.email"
  }
}

If the request is unsuccessful, the response will have an HTTP Status of 400 Bad Request, and the response body will be empty.

signin

The signin action expects a POST with credentials identifying a previously registered user, e.g.:

<form>
  <input name="credentials[email]" type="text" value="an@example.email">
  <input name="credentials[password]" type="password" value="an example password">
</form>

or:

{
  "credentials": {
    "email": "an@example.email",
    "password": "an example password"
  }
}

If the request is successful, the response will have an HTTP Status of 200, OK, and the body will be JSON containing the user's id, email, and the token used to authenticate other requests, e.g.:

{
  "user": {
    "id": 1,
    "email": "an@example.email",
    "token": "an example authentication token"
  }
}

If the request is unsuccessful, the response will have an HTTP Status of 401 Unauthorized, and the response body will be empty.

signout

The signout actions is a DELETE specifying the id of the user so sign out.

If the request is successful the response will have an HTTP status of 204 No Content.

If the request is unsuccessful, the response will have a status of 401 Unauthorized.

changepw

The changepw action expects a PATCH of passwords specifying the old and new.

If the request is successful the response will have an HTTP status of 204 No Content.

If the request is unsuccessful the reponse will have an HTTP status of 400 Bad Request.


The sign-out and change-password requests must include a valid HTTP header Authorization: Token token=<token> or they will be rejected with a status of 401 Unauthorized.

Game actions

All games action requests must include a valid HTTP header Authorization: Token token=<token> or they will be rejected with a status of 401 Unauthorized.

All of the game actions, except for watch, follow the RESTful style.

Games are associated with users, player_x and player_o. Actions, other than update, will only retrieve a game if the user associated with the Authorization header is one of those two users. If this requirement is unmet, the response will be 404, Not Found, except for the index action which will return an empty games array.

Summary:

Request Response
Verb URI body Status body
GET `/games[?over=]` n/a 200, OK games found
The optional `over` query parameter restricts the response to games with a matching `over` property. 200, OK empty games
The default is to retrieve all games associated with the user.. 401 Unauthorized empty
POST `/games` n/a 201, Created game created
401 Unauthorized empty
400 Bad Request errors
GET `/games/:id` n/a 200, OK game found
401 Unauthorized empty
404, Not Found empty
PATCH `/games/:id` empty 200, OK game joined
400 Bad Request errors
400 Bad Request empty
PATCH `/games/:id` game delta 200, OK game updated
400 Bad Request errors
404, Not Found empty

index

The index action is a GET that retrieves all the games associated with a user. The response body will contain JSON containing an array of games, e.g.:

{
  "games": [
    {
      "id": 1,
      "cells": ["o","x","o","x","o","x","o","x","o"],
      "over": true,
      "player_x": {
        "id": 1,
        "email": "and@and.com"
      },
      "player_o": {
        "id": 3,
        "email": "dna@dna.com"
      }
    },
    {
      "id": 2,
      "cells": ["","","","","","","","",""],
      "over": false,
      "player_x": {
        "id": 3,
        "email": "dna@dna.com"
      },
      "player_o": {
        "id": 1,
        "email": "and@and.com"
      }
    }
  ]
}

If the over query parameter is specified the results will be restricted accordingly.

If there are no games associated with the user, the response body will contain an empty games array, e.g.:

{
  "games": [
  ]
}

create

The create action expects a POST with an empty body (e.g new FormData() or '' - if JSON, '{}'). If the request is successful, the response will have an HTTP Status of 201, Created, and the body will contain JSON of the created game with player_x set to the user calling create, e.g.:

{
  "game": {
    "id": 3,
    "cells": ["","","","","","","","",""],
    "over": false,
    "player_x": {
      "id": 1,
      "email": "and@and.com"
    },
    "player_o": null
  }
}

If the request is unsuccessful, the response will have an HTTP Status of 400 Bad Request, and the response body will be JSON describing the errors.

show

The show action is a GET specifing the id of the game to retrieve. If the request is successful the status will be 200, OK, and the response body will contain JSON for the game requested, e.g.:

{
  "game": {
    "id": 1,
    "cells": ["o","x","o","x","o","x","o","x","o"],
    "over": true,
    "player_x": {
      "id": 1,
      "email": "and@and.com"
    },
    "player_o": {
      "id": 3,
      "email": "dna@dna.com"
    }
  }
}

update

join a game as player 'o'

This update action expects an empty (e.g new FormData() or '' - if JSON, '{}') PATCH to join an existing game.

If the request is successful, the response will have an HTTP Status of 200, OK, and the body will be JSON containing the game joined, e.g.:

{
  "game": {
    "id": 1,
    "cells": ["","","","","","","","",""],
    "over":false,
    "player_x": {
      "id": 1,
      "email": "and@and.com"
      },
    "player_o": {
      "id": 3,
      "email":
      "dna@dna.com"
    }
  }
}

If the request is unsuccessful, the response will have an HTTP Status of 400 Bad Request, and the response body will be empty (game cannot be joined, player_o already set or user making request is player_x) or JSON describing the errors.

update a game's states

This update action expects a PATCH with changes to to an existing game, e.g.:

<form>
  <input name="game[cell][index]" type="text" value="0">
  <input name="game[cell][value]" type="text" value="x">
  <input name="game[over]" type="text" value="false">
</form>
{
  "game": {
    "cell": {
      "index": 0,
      "value": "x"
    },
    "over": false
  }
}

If the request is successful, the response will have an HTTP Status of 200, OK, and the body will be JSON containing the modified game, e.g.:

{
  "game": {
    "id": 1,
    "cells": ["x","","","","","","","",""],
    "over":false,
    "player_x": {
      "id": 1,
      "email": "and@and.com"
      },
    "player_o": {
      "id": 3,
      "email":
      "dna@dna.com"
    }
  }
}

If the request is unsuccessful, the response will have an HTTP Status of 400 Bad Request, and the response body will be JSON describing the errors.

watch

The watch action is handled differently than all the others. Because watch implements a streaming source of data, we'll use a wrapper around the html5 object EventSource to handle the events sent.

You can find the wrapper here. The wrapper is also available from the deployed app at the path /js/resource-watcher-0.1.0.js.

The events that watch implements let you know when a game has been updated. By using this interface you can write code that lets a player see another's move almost as it happens. Updates to the game from one player's browser are sent to the other's browser.

You create a watcher object using the resourceWatcher function. This function takes two parameters, the watch url and a configuration object which must contain the Authorization token, and may contain an optional timeout in seconds, e.g.:

var gameWatcher = resourceWatcher('<server>/games/:id/watch', {
      Authorization: 'Token token=<token>'[,
      timeout: <timeout>]
});

The watched resource has a default timeout of 120 seconds.

You should add a handler for change and error events. The error events are not the most informative. The change event may return a timeout.

game.on('change', function(d){
  var data = JSON.parse(d);
  if (data.timeout) { //not an error
    game.close();
    return console.warn(data.timeout);
  }
  var gameData = data.game;
  var cell = gameData.cell;
  var index = cell.index
  var value = cell.value;
});

game.on('error', function(e){
  console.error(e);
});

Source code distributed under the MIT license. Text and other assets copyright General Assembly, Inc., all rights reserved.

About

A rails API to store tic-tac-toe boards

License:Other


Languages

Language:Ruby 82.5%Language:HTML 12.7%Language:JavaScript 2.9%Language:CSS 1.9%