Integrating third party services in your mobile app

June 27, 2018

Twitter bought Smyte and decided to simply shut down all current customers access within 30 minutes or so after announcing the acquisition. This did not only cause some minor problems, but simply broke whole products, like NPM, which had some downtime. Even worse off than the web applications that broke are mobile applications which do not simply allow you to push a new release but require some form of review, or pretend to require one, to get approved to the platform specific store. While there is a lot to learn by this acquisition, handled as classy as you would imagine from Twitter, let us talk a bit about integrating third party services in your mobile application.

The basic problem is fairly simple to explain: There is no real fast turn around if you are building a platform native application. There were some attempts to solve this, some by trying to patch the application and dynamically load code, some using web technology. But, if an app breaks, it is likely that a native third party SDK or library was used - and we do not need another discussion about native vs web.

Generally there are a few options how you can integrate third party services. All of them come with some tradeoffs and different risks. When creating a mobile application one of the (maybe the most) important things is making sure it does not crash or stops working. Getting a spot on a users home screen is hard. Having a user constantly come back to your application is even harder. Uninstalling an application that seems broken on the other hand is pretty simply and fast to do for most users.

The most common way is to download a library or SDK from a third party, likely the one providing the service you want to use, and simply start using it. This is straight forward and pretty much within the competency of ever mobile dev. Assuming you were using Smyte to detect potential spam and harassment before posting a comment to your server you would most likely do something like this: (I never used Smyte and I am mostly writing pseudo code)

func postComment() {
    let smyte = Smyte()
    let badWord = smyte.check("Windows ME")
    if badWord {
        self.showBadWordAlert()
    } else {
        self.postComment()
    }
  }

Now imagine what would happen when Smyte is down or, well, disabled? You will likely get a timeout on the third line where you call check() assuming the library does not guard against this problem. The two most common ways to handle this is either simply handling the error by posting the comment without check or telling the user to try again later.

Posting the comment without a check means people can freely post "Windows ME" or other nasty things, not posting the comment means you users will likely get annoyed pretty fast if the problem persists. But this only solves the problem of your app breaking, you will still be missing some functionality until you can get a new version released. The first option is likely the least problematic one when you also have a server side spam and harassment detection.

Which also brings us to the second option - server side integration of third party services. I think it is easy to agree that whatever we can safely do on the client we should be doing on the client for a smooth user experience. We do not really want a full server side check, doing all the work of posting content just to get back an error message. What if the comment includes images or maybe a video? That is a lot of traffic and time from the users perspective just to be told you do not want "Windows ME" to appear on your page. So what we can do is pretty simple: We create an API wrapping Smyte.

 [POST] /api/text-check

 {
     "comment": "Windows ME"
 }

 Response 200

 {
     "bad word": true 
 }

On the client we can nearly use the exact same code

func postComment() {
    let myAPI = MyAPI()
    let badWord = myAPI.check("Windows ME")
    if badWord {
        self.showBadWordAlert()
    } else {
        self.postComment()
    }
  }

While this might decrease the performance a bit since we have two network calls instead of one, it also opens up a few nice possibilities.

Technically you could actually start maintaining some sort of "bad word cache". If people only post the same emoji or "OMG cute!" over and over for every picture of a kitten silently murdering its owner there is not a lot of value in calling a third party service for each comment. Especially if you are charged per API call. But this also is a lot of work and maybe something to first approach after establishing a solid revenue stream. What is more important for our problem is the fact that you could replace Smyte with Sift and have your app fully functioning again in a matter of how fast you can deploy your backend.

So we have a few assumptions in here: You actually have a backend application, which is not necessarily true for every mobile app. You can actually scale and maintain a backend application, which is not necessarily true for every mobile dev. But both problems can be solved - enter Functions as a Service, short FaaS, or maybe better known under the most irritating and wrong term established over the last three years: "serverless computing". Every major provider offers a service like this and a few smaller ones try to establish themselves with various differentiating features.

The idea is nearly the same as with having a backend, but you do not have to maintain the application, you do not have to scale it and performance is likely a bit better if your app sees enough usage to prevent cold starts of servers. Another nice addition to the list of pros is that you can use nearly every language you want by now, so you can simply write your third party integrations with the same language as your mobile app, the one you are comfortable with.

One of the things to keep in mind is that FaaS usually gets expensive at a certain point. But once you reach this point you will likely be in a position to either hire someone to help out with a backend or you will have found some time, if you want to, to build a backend by yourself and use one of the platform as a service providers like Heroku or the PaaS offering of your current Fans provider.

Speaking from experience I can say that being able to randomly swap third parties at any given time without requesting an expedited review of your application is quite nice and actually justifies the additional development work. Also speaking from experience I would advice solving one of the hard problems in CS early on - naming things. Nothing is more annoying than maintaining an API integration for Smyte that calls Sift. Not that this ever happened to me... a second time. I think it is fair to say that either a backend integration or some small function are certainly doable tasks and both provide some advantages to solve the problem of third parties shutting down, being unreliable or simply a new competitor offering a way better service for a better price, while also opening up new possibilities to improve the product.