Playing Cards API with Go Lang and JSON
This is a continuation from the previous post on setting up Google App Engine with Go and Martini.
Last week, I showed how you can quickly create and launch a project with Google App Engine and Go. I integrated Martini on GAE and today, I will finish the tutorial by actually designing an API to properly respond to requests with JSON. I will also enable CORS and create some functions in GO that will shuffle an array of objects, split the array according to a user provided number, and reorder the array of objects for multiple keys. If we translate that to playing cards, the API will handle shuffling a deck, dealing out the cards to the amount of players provided, and ordering them by suit and numbers. Any remainder of cards based on provided players will go into the kitty. JSON is a popular content type so I will use that and follow the RESTful style of API design.
Cards are the main resource but REST requires good linkage among resources so the main endpoint will just list all the items you can use. For this example, I will just implement “cards” but you can imagine bids, players, score, and other resources that could be retrieved, modified, updated, and deleted. A GET request to the cards resource will return a shuffled deck. That resource accepts a “players” URL parameter which still returns the same shuffled deck but now the JSON response will deal the deck among all the players, order the cards in each hand within each suit, and if the amount of players results in an uneven distribution, the remainder goes to the “kitty”. How do we do that in Go and Martini?
The main endpoint or list of resources can be static so we just need to transform what we have to a JSON response and add CORS. Cross-Origin Resource Sharing is not a hard requirement but I want to communicate from the client side in Ajax requests without using a server, plus Martini supports CORS out of the box. You could also just do it manually but I added the Martini package as well as render martini package to easily support Ajax and JSON. We need to first add these via GAE:
goapp get github.com/martini-contrib/cors
goapp get github.com/martini-contrib/render
Here’s how the main API endpoint code looks like in the hello.go file:
Now, let’s add the deck of cards and a shuffle function so that the cards resource can return a shuffled deck back to the end user:
So far, I think the code is self explanatory. The final route to handle is where the end user provides the amount of players and Go Language handles that parameter and splits the deck among the players, sorts by suit and number, and returns a JSON object with remainder of the cards in the kitty. Here’s a how I have implemented this:
The route is setup to accept a “players” URL parameter and it uses the allowCORSHandler to respond to the request with cross-origin headers. The “players” parameter will be provided as a string type in Go so I am using the Atoi method from strconv package to convert that string into a number. In the Go language, ParseInt always transforms the string to int64 type which I don’t need.
The first if statement checks if players URL parameter is invalid (like a string which results in 0) or greater than 52 (the deck of cards) and responds with all the shuffled cards. If there are less than 52 players provided, we setup some values to do the splitting and sorting. Go’s sort package has a good example of sorting for multiple keys and I am using that code in closures that order the Card structure (suit and numbers).
To split the deck of cards, I created a multidimensional array in Go according to amount of players provided and looped through that empty array using a for range function. Inside the loop, I grab the slice of the deck and assign to each player (assign it to each player in the two dimensional array) and then I order these cards by suit and number. Finally, outside the loop, I grab the remainder of the cards from the deck and put them into a kitty. The route responds with a JSON representation of these arrays.
Look at the full code on github.
Check out this live Playing Cards API demo on Google App Engine.
If you are interested in developing this out further, these are some good resources around playing cards:
Card Game Library
Playing Cards with HTML, CSS, and JS
Vectorized Playing Cards
Shuffle Cards with Images on JsFiddle
Deck of Cards
Fisher-Yates Shuffle Deck with JS