So for this weeks main project, I had decided to latch onto another’s project and help out. My target was Richard’s mappyr mobile app, built in React Native; it’s kind of like a geolocation reddit where posting and viewing comments are done when actually at a location. My job, I offered, was to build the backend.

Backend First Draft

This first draft, aptly named mappyr-backend was a very simple implementation of what he needed to proceed: a database of comments which can be upvoted. The things I need to implement are many, but mainly:

  1. authentication (even anonymous)
  2. a relational table for upvotes/downvotes
  3. a user table

The backend itself, however simple, took about a day to cook up: it’s a Go powered database wrapper and api route handler. This kind of thing gets done pretty fast with Go, and it took me a similar amount of time to simply deploy it. That is the tricky part:

Step One: Translation to Postgres

Because I don’t pay for a virtual machine somewhere on the internet, I decided to take a swing at using Heroku to deploy the developer backend, so that Richard could play around with the api as soon as possible (we figured the authentication etc could wait). Effectively this meant I had to translate the database portion of the code to Postgresql (from my wonderfully simple sqlite3). After getting the postgresql server and user running on my machine, there were not too many small syntax changes I had to muddle through first:

  • Instead of an AUTOINCREMENT INTEGER, postgres can simply take a serial type.
  • I had to swap a DATETIME type for the TIMESTAMP type.
  • Rather than a ? for insert/select values, I used $i, which has a useful number variable.
  • The Go sql driver doesn’t provide a function for returning the lastInsertId, and so I had to add returning id to the INSERT statement, and then Scan it into a id variable.

Onto Heroku’s Postgres

Oh, but that’s not all. After having translated the statements, the Go sql Open() function takes modified parameters for it’s database infos (such as the user, password, and db name – which also will change once the postgres database is set up on Heroku. For the second parameter of sql.Open(), the aforementioned “infos”, Heroku needs url := os.Getenv("DATABASE_URL"), and this needs to be parsed by the driver (so it should be unhidden), connection, _ := pq.ParseURL(url) along with the parameter: sslmode=require.

Step Two: Prepare for Heroku

Aside from the typical heroku-toolbelt and account needed for this deploy type thing, a Go application (lacking otherwise a standard package manager) needs a few special tweaks. As the instructions dictate, it needs dependencies tracked by a package called Godep. This is so easy to use, one command will save the dependencies to the Vendor/ directory along with a handy JSON file of versions and package names. Next I needed to add the standard Procfile for running the server, looking like this:

web: mappyr-backend -port=$PORT

So I added a flag to my program for setting the port, or otherwise the server needs to ListenAndServe on dynamically created port. This can be retrieved again with the os.Getenv("PORT") function and concatenated with a colon.

Step Three: These steps are not linear

The trail and error for this took me a not-unexpected long time. In fact, the back and forth of combinations I attempted make me a bit hestitant to say I could repeat it outright, but in any case there is one tip which helped me a long:

heroku logs --tail

Otherwise this whole shambled process is done blind.