If last sprint’s two-part post threatened to drown you in acronyms, good news this one won’t be nearly as involved. This week marks my second sprint working on porting my Tic-Tac-Toe project to an ASP.Net Web API 2 project. It’s gone well, as a lot of the basic logic already exists in one form or another it’s mostly been a matter of figuring out which parts translate directly, and which need changed. Mostly it’s been making objects to represent db records, the classes to manipulate them and so many tests. Sooo many tests. coughs Where was I? Oh yes, for now I’ve been sticking with AWS DynamoDB as my persistent storage, though at a couple points I contemplated if I was to the point something a little more powerful might be useful, the simplicity of Dynamo has kept me where I’m at, also, the fact that I can set up the tables locally and not have to pester anyone while I’m experimenting doesn’t hurt.
At this point I’m up to three controllers: Board, PlayerRecord and Session. The PlayerRecord is a copy of the persistent player record from the original project, storing Wins, Losses and Ties with the player name as the key. You can look up, update or remove records via the controller and that’s about all there is to say about it.
The Session controller is a little bit fancier, it stores the state (won/tied/in progress), the name of the first and second players, and some metadata about when the session was started and last updated. As Dynamo doesn’t support auto-incrementing keys, I’ve got it keyed to a guid (stored as a string in the db after some trial and error). When you want to create a session, you pass it the player names as well as the size of the board (3×3 or 4×4). It responds with the new record as well as calling the Board’s data store functions to create a matching record in its table. Remove also eliminates the record from the board table.
The Board controller has all the standard get/update/remove operations, but the direct update as well as remove are in there only for me to make sure I’ve got solid test data (for now). Instead, to update it, the client is expected to call the RecordMove which accepts the Session guid, the index you want to change and what you want to change it to. If that cell isn’t open, it’ll reject it, if it is, it updates the record then runs it through a Lambda from a previous sprint to check if the board is finished, by a win or tie, or can continue. It updates Dynamo, then sends the record back.
That’s the gist of things, I’ve also been adding XML documentation this week in anticipation of getting to play with Swagger which I’m looking forward to. I got to work through the realization that two of my controller’s returns weren’t very consistent between the two (when to use http status codes, and how to return the data). I added logging this week as well.
There is one thing that I’ve been going back and forth on conceptually, if the Board and Session should be separated. At first, I thought “hey Dynamo won’t care if I slap an extra parameter into it with an array of cell states” but in the end I split them because if I ever decided to switch to a different backend, it might be a pain to change it. I also didn’t want to combine the controllers as it seemed like edging near a Single Responsibility Principle violation. I’ve contemplated a hybrid approach that stores them as a single table but works on them as if they were separate. Unless I split them back into separate return types before I return each which seems needlessly complicated. I’m almost certain that by the time I’m done, one of those will be partially or fully folded into the other, I just need to straighten out the kinks in the options before I try it.
That’s how it is as of this writing, but at this point the Sessions table seems like it hardly has a reason to exist and I’m not entirely happy that the Sessions database object also makes a call to the Board (at create and removal). I’ve got a suspicion that as I add complexity, I’ll regret this, but for this week I think I’ll let it stand. That brings us up to about today, if I’m able to get my PR merged without too much work, I’m hoping to fiddle a bit with Swagger to visualize my APIs a little better.