Today's apps are as spread out as they've ever been, thanks in part to REST APIs, which make it easy to link to a plethora of backend services. That's cool, but what if something goes awry? What if one of the APIs breaks? How are you going to find what’s wrong in order to fix it? For starters, begin by keeping things simple when you initially build your app and avoid using SDKs whenever possible.
That's one bit of advice John Sheehan, CEO of Runscope, offered Friday at the Ultimate Developer Event in Boston. In his talk, “Zen and the Art of API Maintenance,” Sheehan addressed the main challenges modern app developers face.
Sheehan is a “Python guy” who used to work at Twilio and IFTTT before co-founding Runscope, a service that generates data about API traffic. Runscope (built on AWS EC2 and programmed in Python) gives developers visibility into distributed apps. The San Francisco startup launched in March with $1.1 million in seed funding.
Here are the three challenges distributed apps run into, according to Sheehan. (You can view his full slidedeck here.)
Challenge #1: Getting the complete picture of your application
You can’t fix it if you can’t see it. That's the problem with distributed apps. It is very difficult to get the full picture of what is going on. Traditional performance monitoring tools, geared toward old-style apps, don't give you the whole story, says Sheehan.
He gives the example of one company that was building a mobile app. Everything worked fine with in-house testing on Wi-Fi, but as soon as they released the app to their partners, the API immediately went down. After a lot of head scratching and tail chasing, they finally figured out the problem. As it turned out, when the API made a call over the cell network, it waited for the response, but when a response didn't come fast enough, it would retry the call again and again, essentially creating its own denial-of-service attack.
“You get a lot of these network conditions that can cause some very strange problems we are not used to seeing when all of the pieces of code run on your own service under your control,” said Sheehan.
As a way to spot problems quickly – and sometimes before they even happen – he suggests developers log everything outside of their external control to pick up patterns and monitor issues over time.
“Log everything on your servers. Log every call you make to other servers. Log every response you get back from other servers. If you can, log every client device that is making a call to your backend service on some type of aggregate logging device," he said.
Log everything, so when you email the originator of the API, you can show them exactly what you are seeing. “Never assume the provider, even if they are in the same company as you, is logging data relevant to your application," he said.
Challenge #2: Managing change
How do you manage change when you have no control over what changes are made to the third-party APIs you are using? The answer, avoid dependency hell. That means using native APIs whenever possible, says Sheehan. At Runscope, he says, they have a zero SDK rule.
Over the lifetime of an app, you spend far more time maintaining the app then you do in the initial developing and prototyping of it. So, if you want to build something to last, optimize for long-term maintenance. “SDKs introduce a complexity cost over the lifetime of your app that outweigh the gain of not having to rewrite the code," Sheehan said.
Too often, the originator does not maintain parity between the native API and what’s in the SDK. Even if they don’t break the API in version 1, says Sheehan, they may release new functionality that you want to use but now the SDK doesn’t have it.
But, he says, SDKs are okay in some cases. For instance, if you are building a prototype, and you simply want to find out if the API is going to solve your problem, SDKs are okay. Just be mindful that prototypes tend to live a lot longer than we expect, says Sheehan. "Don’t make an SDK an early bad decision," he said.
If no good HTTP client is available, you should use an SDK. Go is about the only language with a really great HTTP client out-of-the-box, says Sheehan. If you use Ruby, you’ll likely end up using Httparty, Typhoeus or Faraday. Or, if you code in Python, you might use Requests. But, in the absence of a good HTTP client, "an SDK may be your only choice for building an actual working implementation," Sheehan said.
Also, if you are building a full-blown client, you should use an SDK. “If you are building a client for your API and you would tend to use every single method of that API in your app, then an SDK or wrapper might be the best solution for you," he said.
Finally, if you are working with a complex API, such as Dropbox or Evernote’s Thrift (a technology originally developed by Facebook), you will want to use an SDK. “I've never worked with Thrift, therefore, I wouldn't know how to write a direct connection to that API. So for complex cases, you may want to use an SDK," said Sheehan.
When you do use SDKs, a few things to look out for: Be mindful of dependencies. They can wreak havoc in your app. Be wary of community contributed SDKs. In such cases, the people who built the SDK may have long moved on to other projects. And finally, watch out for inactive SDKs. If it appears an SDK hasn't been updated in six months, send a note to the developer asking how actively they maintain it.
Challenge #3: High fidelity testing
When you run automated tests on your application, make sure your tests are as close to real-world calls as possible. Of course, this is difficult when testing APIs. The test environment can be different from the live environment in subtle ways that will alter the nature of API requests or responses, says Sheehan.
Most API integration testing requires you to try to recreate the live environment from scratch, increasing the likelihood that you run into these differences and your tests will be inaccurate. Runscope offers tools that allow you to create tests based on real requests captured from within an app, which helps you build far more accurate tests, says Sheehan.