The most recent coding challenge I have come across was challenging and fun to experiment with. I received it on Tuesday, and though I was only able to begin working on Friday, all week, I looked forward to digging into building my own API for the first time and learning how to use server-side Swift.
Here is the challenge:
To complete this question you will need to write both a client and a server. We are agnostic to how you design the client (mobile web, iOS, Android, desktop web) but it will need to be able to make HTTP requests to a specific endpoints. The server you create will also need to be able to respond to HTTP requests to specific endpoints. It is not important what language or framework you use to build your server.
The client should do the following in order
Make a GET request to /people
Make a POST request to /people
Please make the person object have the following attributes: id, name : “Sean”, favoriteCity : “New York”
Make a GET request to retrieve the object created in the previous request
Make a PUT request to /people and modify the attribute city to be “Brooklyn”
Make a GET request to /people/1
Make a DELETE request to /people/1
Make a GET request to /people
Using restful principles, decide how the server should handle each request including responding with the appropriate JSON. We are intentionally being vague about what exactly each request should do on the server. We want you to use your best guess as to how other programmers might expect your API to behave.
The last part of the challenge required the server to be deployed to Heroku.
Mapping Out a Game Plan
I first started with the server because I would need it later to handle the requests, but also because it was the part of the challenge I had never attempted before. I knew I had only two days to work on it and I figured that starting the server on Friday would leave me part of Saturday to finish up any loose ends and then power through the client part.
Friday – Figure out how to write a server; Figure out how to deploy to Heroku
Saturday – Finish server; Write an app to make requests to the server
I started by doing a bit of research on how to write a server in Swift. I came to find several blog posts recommending an open source library, Vapor. I started by created a new XCode project and configuring it to use the latest Swift Development Snapshot and creating a main.swift, Sources folder, and Package.swift manually. It wasn’t until later that I learned by using the Vapor toolbelt with the terminal, you can use vapor ProjectName new to create a project with a basic template.
In the first iteration, I was able to get the server running locally. I then set up my Heroku account and prepared a new app, but I was not able to get the app running with Heroku.
On Day 2, I now felt familiarized with Vapor, Heroku, and using the Swift for something other then an iOS app. I felt comfortable starting the server from scratch to try again to deploy it to Heroku. This time I used the handy terminal commands to create the project and had a template to use. It was much faster the second time around getting to where I left off yesterday.
Finally at 10am, I saw my “Hello Shea” greet me from a live https address! I then began to build a JSON to return. Here’s an updated version of the server with my hardcoded JSON. The null ids indicate that it is not connected to a database.
I then began to build out a database using Postgres and create some routes to POST data to the database.
After building the data model and testing the build, I ran into some bugs.
The data directory was initialized by PostgreSQL version 9.5, which is not compatible with this version 9.4.4.
This was odd because psql –version showed that I was using version 9.6. I ended up re-installing Postgres and updating homebrew. This is when the Heroku version stopped working. The branches deployed without problem, but the app showed a generic error without much clues.
dyld: Library not loaded:
I then had an issue where one of the dynamic libraries could not be found via an incorrect reference. After checking the target’s build settings, and finding it to be correct, I tried a vapor clean. It seemed to fixed the bug, but then led to another, more helpful bug.
Failed to start preparation
cannotEstablishConnection(“FATAL: role \”doughnut\” does not exist\n”)
Error: Run failed.
Now we are getting somewhere! This is an issue with the database – I can fix this!
I am bummed I ran out of time with the code challenge, but I learned a lot of cool stuff. I am excited to work on my server again and get the database up and running.
If I had more time, I would switch gears to my Client app. I would implement Networking similar to the way I did it in this repo. Other parts of that sample code would be similar including the implementation of the Project Object which I would change to be a Person object that matches up with my server’s JSON data model.
I would then implement the PUT/DELETE methods in the client similar to how I did it in this repo.
Lastly, I would return the to server and either get Postgres to work or find another database to use.
When I first saw the challenge, I did not know how long it would take me to get a server up and running. I had never done it before, and I believe starting with it was the right choice.
The only thing I would have done different would be to ask for more time with the challenge. The deadline appeared to be non-negotiable and I took it as such. In the end, time ran out. Outside the context of a challenge – I may have also reached out to some peers or mentors for pointers or recommendations.
To the next challenge! 🤓 💪🏼 💻