Have you ever tried to read a complicated article with music on? Or turned your coffee machine on and completely failed to return to it when it was finished dripping? You might be confronting our most human of frailties: the fact that our brains just can’t keep track of a whole lot of information at once. Now let’s see if you’ve had this experience as a mobile developer: have you ever tried to build a mobile app and the server for it by simultaneously writing in two different languages, on two different platforms, by working in two different codebases? It’s hard because of the same reason I never end up drinking hot coffee: you can’t keep all the information you need in your head at once.
Mobile development seems like a nice, tidy niche until you recognize that every useful, interesting app also requires that you have a server to make it do anything interesting. Server-side code and networking is what turns Facebook from a personal diary into a social network. And whether you’ve got a single person or two dedicated teams building your app and your server, you face the same issues.
For starters, you need to learn to build the right server for a mobile app. Hopefully, you’ve got experience with some server-side development to begin with, because it’s a wildly different way of thinking than what mobile developers are used to. Doubly so when things go wrong. When mobile code breaks, it’s often visible and obvious, and usually can be debugged helpfully just inside your IDE. Servers — distributed and decomposed into microservices as they often are — aren’t as generous in letting you know what’s going wrong, or why.
Let’s say you do have the server-side experience you need — maybe somebody on your team has built a lot of Django web apps before. The next likely frustration is that your mobile app feature wishlist starts to outrun what’s viable for the server-side tech you’re most familiar with. When you use Uber and instantly see updates to your driver’s location, it’s great! And up until about a year ago, there was no sane way to build that feature with a Django web server, because as useful as real-time protocols are, they often break how web frameworks work.
Sure, large web frameworks in all sorts of languages are making progress towards easy-to-use, socket-based, real-time connections — but each framework has to make a bunch of compromises to get it out the door, because these frameworks were often first built in a different era, with different core use cases. Django and Rails were easy ways to build dynamic websites, which you’d connect to in a web browser, and pass requests to well-defined endpoints. Request in, response out. Streaming, real-time data does not fit well into the discrete world of web browser requests.
Mobile apps have to take this same basic request-based architecture for granted, whether or not it makes sense, and that leads to enormous amounts of work for both mobile developers and server-side devs. The RESTful API paradigm has helped to bridge the gap between what last generation’s web servers expect and what’s natural for mobile apps to send by giving a clear way to send data and to specify what data to send, but that means you end up with a single controller on a mobile app that has to deal with a half-dozen different endpoints. That “heart” button on Instagram? It has its own client-side networking code, and a corresponding endpoint on the server, along with almost every other button in the whole Instagram app.
It works, as long as you don’t change anything. But even a small change to your data model will force you to rewrite a ton of client-side and server-side code. You’ll have to rewrite the code that serializes data into a request on the client, then rewrite the code on the server that deserializes that data into something the server can work with. Then you’ll have to update the server’s database schema so it can store it. And then you’ll have to do all the same changes on the round-trip back.
There’s considerable fragility here, but why? Ultimately, it’s because even though API servers and mobile apps need to do the same things, they have evolved to solve them in very different ways. Everyone needs to model and store data, communicate with outside services, and run custom logic. But web apps were built around web browsers, and mobile apps simply don’t work that way. Users demand new data, or at least functional apps even if they’re offline. Their use means real-time streaming data makes sense, even though it’s painful for us to implement with the kluge that is the modern mobile API stack.
It’s this gap between the nature of mobile and the nature of the web that leads us to frustration in mobile development. Is there a future where we have mobile-native server-side tools that give us features and practices that we know our users demand? Yes. In many ways, those tools exist or are emerging today — including object databases, automatic sync, and serverless frameworks that abstract server-side code from server-side management. Their simplest innovation is their most profound, though: if you can think in a mobile way in your app and on your server, that’s the quickest way to a great experience for your developers and your users.