Thomas McGoey-Smith

Rewriting my Web App in Go

Side: I’m still relatively new to Go (Golang), and a bit new to building web apps, but I was able to successfully ship the first version of Has It Shipped Yet (HISY) over the summer. Now with more customer feedback and better go skills, I’m rewriting the next version from the ground up. If you spot something that’s a bit wonky or just have a better way of doing things, please let me know in the comment section below.


Although Joel Spolsky (from Joel on Software) has a great article about how you should never do a rewrite, I was inspired after watching DHH’s talk on Rewriting Basecamp 2 & now 3.

The current version is pretty buggy and at times, I’m a bit shocked that’s it’s still chugging away.

Instead of trying to get in there and change up somethings, I’m going in for a complete rewrite.

Since the first version, I was able to work on my next app Persistent Discounts, originally I had plans on launching it (it did make it to the beta phase), but it lacks too many features to be meaningful. Instead I hope to port over some of it’s technology in the next “larger” app I build.

But, building that app, gave me some really good insights into building a embedded Shopify app, and I was able to build my own middleware for logging errors (largely thanks to elithrar to his excellent post on handling errors.)

Reinventing the MVC Wheel

The one thing I’ve notice building things web apps in Go, is trying to reinvent the MVC wheel. Before digging into Go, I was in a large part an avid Rails noob (I still attend my local ruby meetup, because there an awesome group of experienced devs), so when I dig into Go I attempt to badly copy over rails MVC style.

Just to give you an idea, here is part of my “routes” file:

// Campaign - Index
mx.Handle("/campaigns", m.Authenticate(Handler{env, campaigns.HandleIndex})).Methods("GET")

// Campaign - Create
mx.Handle("/campaigns", m.Authenticate(Handler{env, campaigns.HandleCreate})).Methods("POST")

It somewhat follows Rail’s Single Routing.

If you notice I wrap things in a m.Authenticate. This was because I needed a way to support CSRF protection and user authentication. Originally, I planned not to include this, but ran into some weird bugs on my admin panel.

Anyway, going forward, I’ve figured out a nice little balance between full MVC rails land and something light weight that involves a tad bit more code, but much easier to manage. (I’ll be sharing it when it comes time to get the project up and running.)

Getting Started

Here’s the mission statement of Has It Shipped Yet? “Answer just one question, has my package shipped yet.”. In a more complex way - Help Shopify stores build trust by helping their customers know that their package has been fulfilled and is on their way.

If you’ve ever bought anything online, you might have run into the issue of trying to track down your package. Having just a tracking number works okay when it’s just one item, but when things are fulfilled separately it gets a bit overwhelming. Instead, it would be nice to visit just one site and see the status in one place. Etsy & American Eagle do this pretty well.

Lessons learned from V1

Because I never shipped a Shopify App before, I wasn’t sure how user friendly I would need to make things. I learned pretty fast when the support requests started to flood in:

  • Theming is a huge pain! Don’t expect your users to understand how to code things with HTML. It’s not going to happen! Stick to WYSIWYG.

  • Your users aren’t just based in North America. It’s time to support multiple languages, currencies, and shipping carriers.

  • Spend time getting onboarding right. You’ll get too many uninstalls otherwise.

  • Build an email onboarding course too. Let your users get to know who you are. (Build Trust)

  • Always be building trust. Always! This is a huge common theme in the Shopify community. Broken Apps, and broken support. It’s easy to forget that your user actually depends on your App to run their business. Don’t forget that!

  • Take advantage of webhooks. Right now V1 doesn’t support the uninstall webhook, which caused a bunch of pain when it came to installation issues.

  • Invest time making your App Embeddable. It’s easy to have an external link to some other site, but it does kill your user experience (especially if your App is more of an add-on to Shopify).

Committed Features

  • Introduce support for theming

  • Add support for a third-party shipping API tracking service (in my case EasyPost is affordable and covers a large range of carriers)

  • Build a better onboarding flow

  • Build support for email course (make it clear that I’m here to help)

  • Introduce a sustainable billing model. Right now I’m free, most Apps tend to offer little but charge quite a bit. My hope with theming, I can offer a range of pricing plans (free included) that work for most stores.

The hardest one will probably be theming. If you ever need a great book on where to start with building widgets checkout out Third-Party JS. It’s definitely helped improve my JS skills.

The Timeline

My original idea was shipping V2 by mid-October. But because I fell behind with my other App, and ran into a heavier course load with school, V2 will probably not be out until late-November or December. My goal is to invest more in the user experience instead of just shipping right away. V1 is still running despite it’s bugs, so I have more time to get it right this time.

With V2, I really want to write about the process. This way I can help others building their Apps in Go, and also since I’m working alone I find writing helps with hashing out ideas and figuring out problems.

Plus it would be nice to improve my writing skills too.

@tamcgoey on Oct 11, 2015

Enjoyed the article? Subscribe to my newsletter for more.

© Thomas McGoey-Smith (2014-2018). RSS.