Using GraphQL + Apollo at Expo
Adam Miskiewicz
It’s not often the best engineering decision to use the “coolest new thing”. It’s almost universally agreed upon that the smart thing to do is to rely on time-tested and stable technologies. With regards to a web or mobile backend, the sage advice is to use a relational database, build RESTful APIs, and in general just use things that everybody knows and understands; “Keep it simple” is the agreed upon mantra.
At Expo, we diligently follow the “keep it simple” rule. Being a small startup, we have a lot of projects and not many people, and it’s important that we focus on shipping features. That being said, we strongly believe in evaluating technologies, both new and old, by their merits and flaws, over adhering a particular dogma.
GraphQL and the Apollo toolchain were choices that we evaluated not by their GitHub star count or release dates, but by how effective we felt they would be in helping our small team build and iterate on our products: They allow for quick, reliable iteration, and an intuitive way to bridge the gap between back-end and front-end development. There’s a multitude of examples of large companies using GraphQL and Apollo in production, but this stack is just as powerful for a company the size of Expo. The tools continue to prove their worth, and are definitely examples of a time when choosing the cool new thing paid off.
B.A.: Before Apollo
At the end of 2016, one of Expo’s main internal goals was revamping our client app, a project we affectionately call “Expo Home”.
The previous version of the app was basically just an Expo project viewer. You could view your recent projects but couldn’t view someone’s profile with the projects they’d worked on.
The new app
Besides a nice visual facelift (pictured below), our goal with the new version of the client was to make it much more community-oriented. We have sign in/sign up, user profiles, a way to explore “featured”, “new”, and “top” projects, and project/user search. We have much more planned for Expo Home in the future, but these features are what we agreed would be our MVP, for launch in February 2017.
Prior to starting the project, we had some, but not all, of the necessary data available through a myriad of RESTful-ish endpoints exposed by our backend, which we had used in other ancillary parts of our products. In addition to not exposing the data we needed and not being well documented, this part of our codebase also wasn’t very well tested or maintained. We didn’t want to build the future of the Expo client on these shaky foundations, so we had two options — rearchitect and build out a more maintainable RESTful API, or take a different approach altogether.
Prior to working at Expo, I had the opportunity to work on a few apps that used GraphQL and Relay, and was very impressed with the outcome, and was particularly enthusiastic about GraphQL. As the backend engineer on this project, I thought it would be a great idea to try GraphQL for Expo Home, and use Apollo on the frontend.
We had a ton of new features to build, and I had wanted to introduce GraphQL into the Expo tech stack for a while. This project seemed like the perfect fit, but I needed to sell it to my team.
Why GraphQL
Lots has been written about GraphQL vs REST, as well as about the problems REST APIs often face. I presented some of these arguments to the team while pitching them on using GraphQL to power Expo Home.
Building a performant, maintainable, RESTful application is absolutely possible. Doing it quickly, on the other hand, is another story. We had less than two months to ship the first version of the new Expo mobile app, and thus working quickly was important.
Engineering, as with most other things in life, is about tradeoffs. Some considerations I posed to the team:
- User experience — If we spend a ton of time making our data fetching logic in the app really robust, are we sacrificing the user experience of our app and polish around UI?
- Performance and stability — If we spend a ton of time on UI polish, are we making a slow app, or one that doesn’t gracefully handle failure?
- Over-fetching — On the backend, we could spend our time focusing on API coverage, and making sure that every last thing that a front-end engineer could ever think of doing is covered by the APIs. If we did that, however, are we building slow endpoints (by providing too much data) or are we causing a request waterfall from our clients because they have to request many API resources to build the UI for a single screen?
- Tech debt— What if we spend time building individual, bespoke APIs that provide perfect coverage for a given screen with no over or under-fetching? Are we backing ourselves into an implementation corner, making everything difficult to manage when we want to add a feature?
With GraphQL and Apollo, we didn’t have to make these same tradeoffs and could build a fast and easy-to-maintain front-end and back-end from the outset of the project.
Developer Workflow & Production-Ready Results
In web and mobile development, it’s common practice to build some UI with mock data before integrating with any APIs/services. This workflow allows both back-end and front-end developers to work mostly in parallel.
But eventually it’s time to bring in real data. This process will typically be a carefully coordinated dance between front-end and back-end engineers, as each person (or team) finds places where they misjudged the other. Even if a careful spec is put in place beforehand, there will almost certainly be constant back-and-forth.
In our case, it was imperative that with the short timeline Brent Vatne and I could work in parallel as much as possible. As I look back on building the new version of the Expo app, the part that sticks out to me the most is how smooth the workflow was as Brent Vatne and I worked on the app.
Brent and I had almost none of this forced collaboration. This was due to two things:
- Apollo and its surrounding tooling makes it trivial to use mock data/a mock server, which we leveraged from the beginning of the project.
- GraphiQL the in-browser IDE for exploring GraphQL servers (pictured below) is simply an amazing tool for browsing an API and discovering its capabilities.
Instead of spending time discussing API design or what data should be in which endpoint, Brent and I were able to talk about how to make the product better and provide a great user experience.
Another thing that sticks out to me about the GraphQL/Apollo development experience is that at the end of the day, you’re not left with something that was easy to get started with but doesn’t fulfill production needs. It’s quite the opposite — everything we built, because we leveraged the Apollo toolchain and followed GraphQL best-practices, was production-ready from the get-go.
The Future
Expo Home is far from complete — we have tons of planned improvements for 2017.
An example of one such improvement is a feature that shows the current project you have open in XDE, our desktop developer environment, on the main screen of Expo Home. There are a few moving pieces to this feature, but one of the parts I’m most excited about is leveraging GraphQL subscriptions to update the app front-end.
Apollo’s graphql-tools
package makes this pretty simple to do, and we can leverage PubNub as the backend, alleviating us from implementing our own WebSocket-based solution.
At Expo, we’re also working on bringing pieces of the Expo Home experience to web. All of Expo Home’s backend work, in addition to a reasonable amount of front-end work, can be reused in this effort. And as Expo grows, and we need to move pieces of our infrastructure out of our monolith and into some individual services, the web and mobile clients can stay untouched, allowing us to move quickly in all parts of our infrastructure without blocking any particular team or project.
It’s rare to find a technology that is valuable to both the enterprise and the ten person company. GraphQL can help the 5000 person organization wrangle their 1000’s of REST APIs and services into a coherent, discoverable schema and interface, but it can also help the small startup foster good communication patterns between their back-end and front-end developers, enable better parallel work, and provide a solid basis for future API and feature development.
GraphQL and the Apollo toolchain have already been instrumental in our product roadmap in 2017, and we’ve only scratched the surface of their overall potential.
If you want to know even more about how we use GraphQL and Apollo at Expo, watch my talk from Apollo Day 2017: