In the latest codebar.io tutorial, we are working with AJAX Requests. We have already used the Github and the BBC APIs issuing GET requests to retrieve information.

I built a sinatra app that handles JSON requests using POST, PUT and GET to manage a Hangman game. As part of doing this, I also had to enable CORS1 in Sinatra so that the calls could be executed from any domain.

CORS

To enable CORS first you must allow requests originating from any domain by setting the Access-Control-Allow-Origin to any (unless you only want to only allow specific domains).

1
headers['Access-Control-Allow-Origin'] = "*"

Not so simple requests

For every not so simple request, a preflight request is also issued. The browser asks the server for permission to issue the request and waits until its granted before doing anything else.

The preflight request is OPTIONS. The response must have Access-Control-Allow-Origin and Access-Control-Allow-Methods defined. To allow requests issued by JQuery, I also had to allow the X-Requested-With header.

1
2
3
4
5
options '/hangman' do
  headers['Access-Control-Allow-Origin'] = "*"
  headers['Access-Control-Allow-Methods'] = "PUT"
  headers['Access-Control-Allow-Headers'] = "X-Requested-With"
end

Game State

Using a database to store the game state is a bit overkill for such a simple app, so instead I store the state in a Base64 encoded token which the client sends on each request – thanks to @barisbalic for the suggestion. Alternatively, a cookie could have been used, but explicitly passing the token allows the client to run multiple games at the same time, and also required less effort to implement .

Generating the token

1
2
3
4
5
Base64.urlsafe_encode64({
    :solution => hangman.solution,
    :correct_guesses => hangman.correct_guesses,
    :wrong_guesses => hangman.wrong_guesses
    }.to_json)

Getting information from the token

1
JSON.parse(Base64.urlsafe_decode64(token))

Playing Hangman using curl

Start a new game

1
curl -X POST http://hangman-api.herokuapp.com/hangman

Guess a letter

1
2
3
4
curl -X PUT \
      http://hangman-api.herokuapp.com/hangman \
      -d token=token \
      -d letter=guess

Get the solution

1
2
3
curl -X GET \
      http://hangman-api.herokuapp.com/hangman \
      -d token=token

Read more about the API.

Playing Hangman using the interface

http://hangman-api.herokuapp.com

hangman