2016-08-22

It seems that every recent MDG post alludes to the impending arrival of Apollo Stack. Well, to be exact the development of Apollo—you can integrate Apollo into your application today! While Apollo and GraphQL are certainly en vogue as the latest and greatest features in Meteor’s development, the many advantages Apollo offers may not be worth the initial headache. In order to evaluate whether Apollo is a good fit for your developer-arsenal, let’s take a look at what exactly this touted library is and what it brings to the table.



What is Apollo Stack?

Oddly enough, neither the Apollo homepage nor the Apollo documentation in their current forms do a terribly good job of explaining more than the broad strokes. To be fair, however, Apollo is a nascent project and the developers have other priorities like moving the Stack out of its current “technical preview” phase.

Apollo Stack consists of a pair of libraries (Server and Client) which together represent the fruition of MDG’s promise to add support for not-MongoDBs to Meteor. Apollo is the result of an effort to build a pipeline through which data from any source can be integrated into a Meteor application. Mongo requires that you query it in a Mongo-specific format, a database query language, but Apollo implements an application query language—GraphQL—that can span many types of backends. Apollo is an intermediary between your client and data. No longer will you be tied to using Mongo and nothing else when developing with Meteor, so long as you are willing to adopt Apollo.

Apollo Server

Apollo Server is a process that sits between your data sources (MongoDB, mySQL instance, REST API, etc.) and your client code. It listens for requests from a client, makes some requests to the underlying sources (usually databases or APIs), and passes back structured data. You can think of Apollo as a funnel (see the diagram below) in which Apollo Server forms the middle. The Server unifies any number of databases into a single stream of data accessible to the client.

Apollo Client

Apollo Client serves as the interface between your client UI and the server. In the funnel example, the Client is the narrow stem. It is roughly analogous to Meteor’s MiniMongo in that it caches data and handles reactivity, though it also manages communication with the server. When used with React, the Client functionally resembles the Redux store provider.

Note that the Client and Server packages can be decoupled and used independently if you should have a compelling reason to do so. Under the hood, the Server package is just a bundle of existing GraphQL tools and serves merely as an “opinionated guide for how to build a GraphQL server in JavaScript”. Just like Meteor, much of the magic (optimistic UI, caching, and to an extent reactivity) happens in the Client.

Apollo Stack Layout



Apollo Server sits between your databases/APIs and your client, while Apollo Client connects with your view layer. The queries from client to server are made in GraphQL syntax. The Server translates those queries into the appropriate syntax for each source and returns JSON data to the client. Don’t worry about how the server changes GraphQL to source-specific queries yet, but know that you will write code to do this!

So…. what is GraphQL?

GraphQL is a Facebook technology—it’s really only a specification, and Apollo is the implementation thereof—that was made public in 2015. It aims to change the nature of the application-data relationship. In short, it is an architecture with a syntax attached for querying data, and it forms the foundation of the Apollo Stack. The syntax loosely resembles a sort of half-JSON, absent the values for each key.

Here’s a sample query in GraphQL syntax. This finds a single hero, the name of that hero, and some attribute’s of that hero’s friends.

Here’s most of the JSON response to the above query. Note the magic involved in returning information on Luke Skywalker inside a query for characteristics of R2-D2. This example query and response was lifted from the official GraphQL documentation.

GraphQL was conceived as an improvement on existing query layers; REST, SOAP, and DDP. Many applications load data from either a rigid REST API or custom queries for each view in the application (think rendering data into a template using Express).

There is a plethora of shortcomings with each method. For instance, code duplication is nearly inevitable when you load data into individual templates instead of reusable components, and a REST API usually necessitates multiple calls to load even simple views. Additionally, consider this: as your application matures or you commence development of clients on other platforms, you may add new fields to existing endpoints. If and when those API endpoints change, older clients will receive the extra fields despite not being able to make use of that data. This would hardly spell the end of the world, but would also certainly be suboptimal. Over time, these inefficiencies can add up and bog down your client.

Improvements on Meteor’s data architecture

So long, pub-sub

GraphQL improves on these limitations by allowing the client to ask the server for exactly the data it needs—nothing more, nothing less. Apollo forgoes the classic Meteor publish-subscribe model, without losing the “magic” of Meteor reactivity. Just like Meteor query code resides in the client, GraphQL queries are created and made by the client. This means only the minimum amount of data required to populate your application’s components is transmitted.

Self-documentation

Another great feature of GraphQL, and by extension Apollo, is that your schema is self-documenting. This means that once you have set up your schema, tools like GraphiQL (the most widely-used GraphQL GUI) can display awesome outlines of the data your application stores.



On the left pane, notice the autocompletion dropdown that GraphiQL can offer. The application is aware of every field attached to each object representation. In this case, those objects are blog posts in a list of the ten most recent posts. As a result, GraphiQL can offer suggestions tailored to the fields contained in a post as I type a query. The center pane shows the JSON representation of the query result.

On the right side is a panel for browsing all the query-able fields in your server. The image above shows information similar to a SQL table’s list of fields, yet GraphiQL is more useful still because it can show you “compound fields"—in this case, the "object” is a single blog post. Where a relational database would store the member fields of a post in multiple tables, GraphiQL’s self-documentation shows all Post fields as if they are stored together.

The ramifications of GraphQL’s self-documentation are not huge and far-reaching, but the feature is a luxury. Newcomers to an existing GraphQL server will have an easy time creating a mental map of the server’s data without external documentation.

To try out GraphiQL for yourself or to browse a sample “self-documentation” visit Kadira’s Learn GraphQL Sandbox.

Connection flexibility

Apollo is also more flexible than Meteor’s data layer, because it does not require a DDP connection. This is great for anyone building a non-Meteor-bundled application—for instance, a native mobile app or desktop app. Apollo does not lock you into a Meteor web-app and allows you to make GraphQL queries over basic HTTP, just like a standard REST API. No longer will you need third-party DDP wrappers!

Here’s a sample HTTP GraphQL query string:

As an aside, it will be interesting to see if this feature helps GraphQL replace REST over time. I can imagine the Facebook Graph API, among others, may move away from their current REST forms and instead allow you to make queries of the above form. If GraphQL became the standard, I could hypothetically query other APIs inside my application with little to no configuration, without changing syntax, while using the second-hand API’s fields as if they were my own.

Querying data: REST vs. Meteor vs. GraphQL

Here is an example to illustrate the improvement GraphQL makes on the models of querying data. Let’s say we are building a view of the user’s friends list, where each list contains an array of people, including the person’s name and age. The data behind the view might ultimately look like this:

Using REST

To get there with a REST API, we could either have a specific route that would only be good for fetching all these specific fields for the friends in a friends list, but going down this path lands us with an endpoint for every view in our application.

Alternatively, we could make a number of requests to build this response:

Then, for each list:

And then, for each member of the list:

But, this path would get out of hand with less simplistic queries. More requests mean more overhead—more paths, ergo more difficult documentation and maintenance.

Using Mongo

With Meteor and Mongo, we could keep response time low by publishing all this information before the view is ever loaded and then querying MiniMongo locally for the relevant data. The problem here is that we have to either: publish some information on all of our friends (whether that information will ever be shown or not), or write a really complex publish function that manipulates multiple collections into a single publication, combining information about users and friends lists—yuck!

The neatest solution is a Meteor server-side method that loops over all the desired lists and the members of those lists, but that lands us right back in the endpoint-per-view conundrum.

Using GraphQL

Enter GraphQL. With proper configuration in the server, we can make an elegant query from the client:

This query has been simplified for comprehension’s sake, so it would not return the entirety of our original JSON response, but it would catch all the important parts! This is a lot to digest at first, so all I will say is that Apollo Server starts at the outermost statement user(id:"me") and crunches its way through the rest of the query, picking out the fields specified and only the fields specified. More on how to get some guided practice at wrapping your head around this query in a bit.

Anyway, voila! We wrangled out the data we wanted in a single query where the code is entirely reusable. If you had a view with the list members’ profile pictures, you could simply add a single field to the new query:

While this unique query structure is one of GraphQL’s strengths, it is also one of the format’s largest obstacles. You will have to learn a new way of thinking about data structure when you set up Apollo Server, on top of learning the new syntax. Assimilating new patterns is almost always rewarding, but sadly is not always practical when it comes down to pragmatic development. This is the main cost of migrating to Apollo and GraphQL. For all the advantages it brings, you will experience a drop-off in productivity for a time. The good news to that end is that, as we have seen, GraphQL code is reminiscent of JSON, so you will not find the change jarring.

Apollo’s future

At the moment, Apollo patterns are still in flux as the libraries move toward v1 and official Meteor integration. Exactly what that convergence will look like remains to be seen, although the developers have pointed out that Apollo can be dropped into any number of other frameworks and is by no means tied to Meteor. I expect that “official” support will be marked by the inclusion of Apollo in the Meteor Guide, rather than Apollo’s inclusion in the base Meteor suite.

Another Apollo agenda item is documentation. Examples of beginner-level “Hello, World” uses are not particularly well documented. This makes getting started with Apollo tricky, particularly if you are a newcomer to GraphQL. Again, this is totally excusable given the project’s early status but is an important consideration nonetheless.

Your next steps

If Apollo appeals to you, your first order of business is getting comfy with GraphQL syntax, and then the specifics of the architecture. I highly recommend going through Kadira’s ‘Learn GraphQL’ online course at your own pace, as it offers a solid introduction to both syntax and theory. The course serves as a primer and will prepare you to begin writing your first Apollo code.

Once you have a grasp on the foundation, check back here for the first article in a series of hands-on Apollo tutorials. We will build on the concepts introduced by the Kadira course by creating a chatroom application using Meteor, Apollo, and React to illustrate how Apollo can simplify your development process!

Summary

The advantages of Apollo and GraphQL

Hallelujah! At long last, Meteor’s data layer is open to any and every database and API out there. Mix, match, and salt to taste!

Facilitates highly specific queries, reducing the amount of data your application transfers. Also makes build-time for new front-end components lightning fast! Just declare what data you want right in the component definition.

Provides a unified interface for your data, making it easier to develop multiple applications and reduce server-side bloat. For example, a phone app profile view may differ slightly from a web app profile view. You can easily change your query for each.

Can be phased into an app. It’s not an all-or-nothing proposition to integrate Apollo Stack into your application. You can start reaping its benefits as development time allows.

No loss of the features you love when moving away from default MongoDB—reactivity, client-side caching, and Meteor methods all stick around.

The disadvantages of Apollo and GraphQL

Requires a shift in thinking. You will struggle to understand how to set up your server and “graph” your data when you first start out.

Beyond the conceptual, you will have to learn how to use the syntax properly to develop efficiently. Trial and error in the GUI is still tedious as it is in a database shell so the faster you improve, the happier your experience will be.

Limited documentation and knowledge-base out there. Prepare to get frustrated and confused. In the long term, you can rest easy that GraphQL, the core of Apollo, is not going anywhere given Facebook’s backing of the project. Apollo’s own documentation will improve as MDG pivots from full-speed-ahead development and we inch closer to official support in Meteor.

If you already are comfortable and familiar with other architectures, the time investment in learning GraphQL and configuring Apollo may not pay off. Be sure to do your homework and walk through some intermediate examples of Apollo applications. Additionally, you will still need to know how to query the data sources you use. Apollo is not adequately magical to make queries on its own, so it does not necessarily offer a reduction in requisite know-how.

Show more