A GraphQL based incrementally-adoptable data stack that manages the flow of data between clients and backends
26th July 2016, 6:00 pm
This AMA is over!Thank the host
Thanks for the question, Sergio!
First, I think there is room for many great GraphQL clients in the ecosystem. Here on the Apollo team, we think GraphQL will be the next big way to load data after REST, so we think the ecosystem is just getting started and eventually there will be tons of options for servers, clients, tools, and more. So it's not about superior - it's about looking at the different options out there and seeing which one meets your needs the best. But we're committed to making it a long-term project -- we're already using it in production in two of our apps, and will be continuously developing it over the coming years.
Our goal is to build a sophisticated GraphQL client that can be a more flexible and hackable alternative to Relay. Relay is, at the time of writing, quite opinionated about a variety of development decisions, in large part because it is focused primarily on Facebook's application development needs. It only works with React, it requires specific schema features on the server around pagination, mutations, and refetching individual nodes, it is coupled to specific concepts about routes, fragments, and containers, and only supports several specific ways of using mutation results that don't always match the situation. If you like this approach, then Relay is awesome - it does a lot of work for you. I'd encourage you to keep using Relay if you love it.
We found that not all of these opinions worked for us, and we needed something that we could hack on to build new features, and easily debug by inspecting store state. So while in the overall architecture Apollo Client is extremely similar to Relay, with a normalized cache of GraphQL data, we decided to go with a few different decisions:
- Apollo Client is split from the start into a core implementation that is completely independent, and view layer integrations for React and Angular 2. This means it's easy for other people to build integrations for whatever view layer they need, like Ember, Vue, or more, without needing to reimplement any core logic.
- Apollo Client doesn't rely on a specific schema from the server. The current features about mutations work with any GraphQL mutation you can think of on the server, and the design for pagination we are currently working on will work with all kinds of pagination formats - page numbers, pages with cursors, and relay connections as well.
- Apollo Client doesn't require any specific build plugins. As long as you can install the NPM package, you can start using it without needing to add anything to your build setup. This is because none of the functionality depends on having schema information at runtime. You can still use static analysis tools like eslint-plugin-graphql to validate your queries at build time, but it's not required.
- Apollo Client is based on Redux, which gives us great insight into how the store is changing over time and makes it easy to integrate with existing client-side data in Redux. It can also be expanded to work with other state-machine based solutions like ngrx. But if you don't want to use Redux in your app, you don't have to - Apollo Client will make its own internal store that you don't have to think about.
I could keep going on about the differences, but you can see the trend - we're going for a more configuration over convention approach, so that you can take advantage of Apollo Client regardless of your client architecture, schema, etc.
Lastly, once Apollo Client becomes production-ready (we have an issue open now to track necessary changes before a 1.0 version), we can use it as a platform for us and the GraphQL community to experiment with new GraphQL features and approaches, including subscriptions, live queries, offline support, and more. Because it's build from the ground up to be flexible, we envision these features will be relatively simple to add once there is a need for them.
If this kind of transparent, hackable, and flexible GraphQL client sounds like a good idea to you, I'd invite you to contribute to the repository! There are already 29 contributors, and we are looking for more great ideas, discussions, and improvements.
That's a great question! The answer is very simple, but I think our documentation doesn't make it clear yet.
The main part of Apollo is the client. The client works with any GraphQL server, including express-graphql (JS), Graphene (Python), graphql-ruby, Sangria (Scala). So no matter which server you pick, you can use Apollo in the client.
While the client is already quite advanced, we've only been experimenting with a few different things on the server side, and haven't yet converged on a definite solution.
There are quite a few moving parts on the server side, so it helps to know what packages are involved and how they relate to each other:
graphql-js is the GraphQL reference implementation maintained and developed by Facebook. It includes a bunch of useful things, like functions to parse, validate and execute GraphQL queries.
express-graphql, also maintained by Facebook, is a middleware for express that uses graphql-js under the hood to parse, validate and execute queries sent over HTTP.
graphql-tools is a package that I put together to make creating GraphQL schemas a bit easier. It uses the parser provided by graphql-js and produces a schema compatible with graphql-js, which means you can use it together with express-graphql, or anything else built on top of graphql-js.
apollo-server is currently just graphql-tools and express-graphql bundled together. Graphql-tools is used to create an executable schema from the schema language, which is then passed to express-graphql.
As you see, express-graphql and apollo-server are actually one and the same thing under the hood, so which one you use doesn't matter all that much.
The next release of apollo-server (almost ready) will be implemented in typescript and support HAPI and Koa in addition to Express and connect. graphql-tools will no longer be part of it, so it will be clearer what is part of the server and what is part of graphql-tools.
In the medium term, most of our efforts will be focused on Apollo client and the complementary native mobile clients which we're building, so our goal with the server is to have a community-driven open-source graphql-server which is built for and tested in production.
As we talked to users of GraphQL, we realized that there's a lot of value in building a production-ready GraphQL client that's easy to use and simplifies using a GraphQL backend for a production app. Since we've realized that, we've focused our efforts on building Apollo Client to satisfy those needs by providing a straightforward API and features such as query batching. So, although Apollo Client has been built with reactivity and server-side push in mind, it is not at the very top of our priority list.
That said, we do already provide some degree of reactivity. If your application uses a view layer such as react-apollo or angular2-apollo, mutations that modify data and queries that fetch new data will automatically update your UI. Also, if you using polling queries, your UI will be updated as new data comes in. As an example of this in production, we actually reimplemented the Meteor Galaxy UI to use Apollo and it renders a live, reactive dashboard with container metrics, an activity feed, etc. using polling queries. Through query batching and scheduled polling queries, this approach can be performant enough to use in many situations.
Although we don't yet have an implementation of server-side push over WebSockets, we are working on implementing it in conjunction with GraphQL subscriptions and would be happy to work with others that are interested in getting this done.
There's another question about production apps, so I'll focus on open source examples here.
The main example app we have, which covers a relatively large range of features, is GitHunt: https://github.com/apollostack/GitHunt
This app includes examples of queries and mutations, and how those might work with routing, UI components, etc. There are directions for how to run the app in the repository.
You can also look at the home page of our docs for more community-contributed code samples: http://docs.apollostack.com/#Example-apps
As the team behind Meteor, we're excited about the prospects of an open standard for declarative data fetching. Allowing developers to specify what data they need and making the framework responsible for efficiently delivering that data to clients has always been one of the major strengths of Meteor.
We see GraphQL as a great opportunity to take what we have learned from working on Meteor's data layer, and apply it to building something that is incrementally adoptable and can be used with a larger set of backends. So our main motivation in building Apollo is to improve the developer experience of data driven apps for everyone.
Apollo is built on top of GraphQL which is a declarative way to specify the data an application needs and obtain it from (potentially) multiple sources. Jonas wrote a great post that describes how a GraphQL turns into a response that may contain data from a bunch of different places.
This means that Apollo doesn't have to make any assumptions at all about where your data is held or how you intend to access it. Apollo Client in particular focuses on caching and fetching the GraphQL query results as well as updating your UI with new data and doesn't care about where your data comes from.
For example, you might hold some of your application data (e.g. notifications) in Redis and other parts of your application data (e.g. user information) in MySQL. As long as you have the ability to retrieve the data from these data sources to fulfill the GraphQL queries you define, the fact that you're using those particular data sources isn't relevant to Apollo. Data sources aren't even limited to databases. In our GitHunt example, data is fetched from the GitHub API as well as a SQL database.
To summarize, Apollo can support pretty much any data source as long as you can implement GraphQL resolvers for the data source.
We all work at the same company - Apollo is a new project brought to you by the same people that developed Meteor, but focusing specifically on data management. Apollo actually started out many months ago as a plan to upgrade Meteor's data layer, especially to support multiple backend sources like SQL and microservices. As we talked to more people we figured out that this technology would be very useful for the application development community as a whole, so we decided to make it a separate project that can be used both inside and outside Meteor.
In Meteor 1.5, we're going to start making the integration with Apollo much more straightforward, so that people who like the other aspects of Meteor (integrated build system, accounts, mobile app compilation, etc) can also take advantage of all of the data loading benefits of Apollo.
Since Apollo addresses so many of the concerns people have had historically with Meteor's data system, including the ability to use different data sources, turning off reactivity, native mobile app support, and more, we are spending most of our time working on Apollo which we think will bring huge benefits both to Meteor developers and the wider application development community.
However, we're committed to continued development of the Meteor framework, both by implementing stuff ourselves and moving to a much more community driven development process (something that the Meteor community has wanted for a long time, and what we're doing with Apollo from the start). Just yesterday, we shipped Meteor 1.4, a huge release which includes a ton of core improvements and upgrades to Node 4 and MongoDB 3.2.
We originally built Saturn to use internally at Meteor as a way to hit the ground running when building GraphQL apps and not spend a big chunk of time setting up the right tooling. For example, Apollo Optics (http://www.apollostack.com/optics) is built on top of the Saturn framework.
Since then, the React team has released some nice tools (https://facebook.github.io/react/blog/2016/07/22/create-apps-with-no-configuration.html) that make it easy to get started building React apps so we don't want to replicate that effort within Saturn. So, although we don't have immediate plans to promote Saturn as the "standard" way to build Apollo apps, we would be glad to work with people who would like to use Saturn in production.
For authentication we recommend using a solution that's independent of GraphQL, and then passing the authentication context into GraphQL. For Express, Passport.js is a popular option, which we've used in our GitHunt example app. It's also described in this Medium post.
As for authorization, we're envisioning something along the lines of decorators, but we're waiting to see what the community comes up with while we work on other things.
Apollo is built on GraphQL, which despite its name is not a query language for graph databases. Facebook describes it as an application layer query language, and the easiest way I've found to think about it is a structured, strongly typed schema and query language that replaces or complements REST APIs.
What that means is that you can use Apollo together with TitanDB. GraphQL is the perfect technology to serve as a gateway in front of your various backend microservices or databases. This Medium post explains some of the concepts in more depth.
Apollo is still relatively new, but we've been testing it in production in our own apps and with contributors from the very beginning. Right now the main apps that I know of are:
- Meteor Galaxy - unfortunately the app itself is behind a paywall, but you can watch this talk on YouTube about how we did it: https://www.youtube.com/watch?v=xwz1aXkJLLA
- NewSpring Church giving app, see a video about it here: https://www.youtube.com/watch?v=RGfn8GfC_uE
- The preview of Apollo Optics, a production GraphQL insights service we're working on, is also built with Apollo from the start.
We need to do a good job of collecting a concrete set of apps built on it - I'm sure I've missed several out there. Hopefully soon we'll get a good list of production apps up on our website, I think that will help people decide if they should use it or not.
We're actually really happy with our setup on the Apollo Client repository, and we even blogged about it.
Here is a summary of what has been particularly helpful:
- TypeScript to get static typing and great editor integration with VS Code. This saves us from a huge potential set of refactoring errors, and is especially useful since we have to often deal with quite complex data structures. We also looked at Flow, but the simpler setup of TypeScript was a big win for getting contributors going quickly.
- Unit tests on CI, with test coverage reports on Coveralls. These really help us ensure that our tests are passing, and that all significant logic in the package is well-tested.
With these tools set up, we are pretty confident that if our CI builds pass the final build will work for people, although no setup is perfect of course.
Although it is not our immediate, top priority, we are in the process of implementing WebSocket support and GraphQL query subscriptions within Apollo. This will allow us to have real-time updates through GraphQL. As Lee Byron's talk at React Europe mentioned, there will also be additions to the GraphQL specification such as the
@live directive that will allow us to implement more real-time functionality within Apollo that may feel similar to Meteor's real-time functionality.
In terms of real-time within Meteor, the 1.5 release of Meteor will integrate with Apollo and GraphQL. Although it is not yet perfectly clear what this will look like, we expect that we will be able to leverage existing real-time portions of Meteor (e.g. livequery, a well-tested WebSocket transport) in order to deliver strong real-time support for GraphQL.
Given GraphQL's data source-independent nature, it should also be possible to implement connectors for data sources, thereby allowing livequery-like real-time functionality for applications using the Apollo Stack.
Now that we have a lot of the basic features working in Apollo Client, we're starting to look at performance as well. Since we are using it in production, this is a big deal for us as well. We did two things in particular recently to improve performance based on what we saw in our production app:
- Aligned poll intervals so that multiple polling queries from different components are sent in one request
- Did data comparisons in observable results to avoid unnecessary UI rerenders
These resulted in some great improvements already, and we're always looking for ideas about performance wins.
Read all about it in our blog post here: Snappier UIs with Apollo Client and GraphQL
This isn't mobile-specific, but any performance improvements about reducing CPU usage will help a lot there.
One thing that I will say is that Apollo Client internal logic about normalization has never showed up in our CPU profiles at all, so I don't think it's a big problem right now. In fact, it already saves you a lot of work because you don't have to write manual
shouldComponentUpdate functions in your UI components after the new features.
- Mostly over GitHub - we reply to pull requests and have discussions on issues. We also have a community slack channel that you can join to talk about GraphQL/Apollo stuff, were we also talk to contributors in more depth. When it comes to complex discussions we try to do video calls, since sometimes comments just aren't enough.
- Honestly I'm terrible at productivity. My only hack is trying to clear out huge chunks of time to do coding without being interrupted by meetings. Perhaps one more useful thing is splitting all tasks into the smallest chunks possible, so that a huge task doesn't get interrupted in the middle. The worst thing is having a long-running branch that can't be merged because of tons of conflicts.
This is something we've always been interested in, but would probable be best driven by a community contributor planning on using it in production.
Apollo Client interacts with Redux in exactly three places:
- It passes in a special Apollo reducer, which should just work with ngrx out of the box
- It uses dispatch to fire some actions, which should just work out of the box
- It uses a middleware to catch store updates and broadcast them to the observable queries: https://github.com/apollostack/apollo-client/blob/f76ad1bc7a5f2fb1e31f75a02332a398e022423e/src/index.ts#L268
(3) is the only part that wouldn't just work with ngrx, since it doesn't have the same middleware API as Redux, but it seems like it would be trivial to just observe the store in some different way, and might just require a change in that one function and some basic tests to check that it works.
I'd be happy to work with you on a pull request to Apollo Client to integrate with ngrx if you're interested!
What are some of the challenges that Apollo is facing now?
Right now the biggest challenge is scoping down our goals to a sustainable level. GraphQL is such an exciting new opportunity that it's easy to get distracted and build a ton of stuff, but we need to stick to only what we can reliably maintain in the long term. Of course as we grow our organization we'll be able to tackle more cool ideas!
What's next in the pipeline?
Given the above, right now we are focusing on creating a great set of open source GraphQL clients that let you integrate your GraphQL data into any of your new or existing apps. This includes, primarily:
- React + React Native
It will include some cool bells and whistles to make GraphQL fun for example possible subscription support, but the main goal is to build something straightforward that people can start using right away.
On the other side of the house, we are working on some great production tools to help people learn about, build, and scale GraphQL in their organization. More news coming soon about these products -- I'm working more on the open source side, so I don't have as much info on the services aspect.
We had our very first GraphQL meetup about two months ago, and it was a great success. You can watch all of the talks and the panel on Youtube.
We already have some swag! I'm wearing an Apollo T-shirt as I'm writing this, and we also have stickers and water bottles, which we send to our contributors. You can also buy the stickers on stickermule.
Incrementally-adoptable means that you can start using Apollo in your existing app today, by just building or rewriting a small part with it, and integrating it with the rest of your app.
If you're starting from scratch, the incrementally-adoptable part doesn't really matter, but if you have an existing app, it's a pretty big deal. That's why we emphasize it.
Apollo, developed by Meteor team, is an incrementally-adoptable data stack that manages the flow of data between clients and backends. Based on GraphQL, it gives you a principled, unified, and scalable API for developing modern apps on top of services.
This is a great opportunity for you to get in touch with the core team behind Apollo Stack and interact with them. Shoot any questions you want the team to answer!
The all-in-one cloud platform developers & their teams love. Get started free for 60 days.Learn more
6 Reasons to join Hashnode, now!
- Friendly and inclusive
- Ask questions, Read blogs and share news
- Voice your opinion without being judged
- Question everything and quench your curiosity
- Earn appreciations and be the coolest nerd
- Hang out with smart developers from across the world