Apollo-client: Create repositories and basic implementations of view layer integrations

Created on 31 Mar 2016  ·  16Comments  ·  Source: apollographql/apollo-client

Two to start with:

  1. ✅ React: https://github.com/apollostack/apollo-react
  2. Angular 2

Other candidates, to do as people need them:

  1. Blaze
  2. Riot.js
  3. Angular 1
  4. Ember
  5. Vue

Most helpful comment

I got a vue integration running!

All 16 comments

A big :+1: for building that, we are getting closer to an Apollo MVP!

I wonder if it would be possible to customize the reactivity layer, for instance by using MobX + React, instead of Redux + React? Also there are some decisions to make on the API design, for instance I imagine that higher-order functions/components/decorators are much more recommendable these days than Tracker-like mixins.

I wonder if it would be possible to customize the reactivity layer, for instance by using MobX + React, instead of Redux + React?

I wonder if you have an idea for how this would work? At the end of the day, we need a state object that can be modified by firing actions. If MobX offers that, I imagine it wouldn't be hard to integrate. Also, what's the benefit here? Is it to integrate with some kind of MobX tooling?

Also there are some decisions to make on the API design, for instance I imagine that higher-order functions/components/decorators are much more recommendable these days than Tracker-like mixins.

I think each view layer's integration should be the best practice for that view layer. So for React it will be a container component similar to Relay, not sure what people do in Angular these days. In Blaze it would probably be some kind of Tracker-enabled function.

I already have a private demo app using the apollo client and React, and I built a trivial container that is used like this:

const TopicWithData = createContainer({
  getQuery: ({ params, loginToken }) => {
    const maybeLoginToken = loginToken ? `(token: "${loginToken}")` : '';

    return `
      {
        root${maybeLoginToken} {
          oneTopic(id: "${params.id}") {
            id
            category_id
            title
            posts {
              pages {
                posts {
                  username
                  score
                  cooked
                }
              }
            }
          }
        }
      }
    `;
  },
}, Topic);

This is probably the most basic thing we could build at first, if we don't want to dive into query aggregation and fragments and whatnot. (The code isn't open source yet because it's straight up just bad code, but we want to release this full-stack demo and a basic server this week or next)

There have been a bit of discussion about MobX in https://github.com/apollostack/apollo/issues/1. MobX basically does the same thing as Tracker, as it allow you to have some reactive data sources (in this case it could be a GraphQL query) and a reactive context that will be re-ran every time one of its dependency gets invalidated. With this model you are able to run arbitrary computation reactively (like with Tracker.autorun) including rendering React components. It allows a clear dependency graph and have various optimizations so that you can modify a bunch of data before flushing or register a dependency on only a subset of a reactive data source. By the way MobX has some good docs and introductions that give way better explanations that what I just wrote. You could also take a look at a MobX+React example written in Typescript here, and on MobX benefits more specifically, you might take a look at positive feedbacks it received on HN.

The point is that the update model is different if you use Redux (re-render the whole tree, probably use Immutable and implement a pure wrapper that generate the shouldComponentUpdate accordingly) or if you use MobX (where a reactive context can have some dependencies that generate a dependency tree/flow) and that’s something the Apollo view layer should take into account. So maybe one easy solution would be to have one apollo-react package that is basically the container that you demonstrated above and a completely separate package apollo-mobx that would transform Apollo queries into MobX observables and then we could use mobx-react as the actual view layer.

Not that this is super important in this early stage, but I just think it’s good to have in mind the various update models that people will want to use.

One of the core ideas I'm working with for this package is versioning the entire store as an immutable object, very much in the style of Redux. I think this is the most natural approach for a store which is normalized and shared between all queries, and immutable JS will hopefully let us determine relatively easily which parts of the query result have changed.

If this makes MobX integration a bit more work, for now that's just a cost we'll have to pay.

For what it's worth, I think most or maybe all people should be using this library via the view connector, and not by interacting with Redux or whatever directly. So we can make that layer do the work of determining if a particular query result actually changed or not, regardless of that Redux says.

But one’s might as well want to perform some arbitrary computation using a Apollo/Graphql query as a data source, say for instance that you want to display an HTML5 notification when a new message is posted in a thread. How would that work if it is the view connector that is determining if a query result changed or not?

Sorry, I misspoke. It should be some layer between the Redux store and the view connector. So you could think of the MobX integration as a view connector.

And I agree that not firing spurious events on queries when their result didn't change should be a priority! Otherwise many things would become very hard to do and people would have to build custom result diffing, which kind of defeats the purpose.

Started a repo for React here: https://github.com/apollostack/apollo-react

Also, we're going to get going on Angular pretty soon.

Closing this issue in favor of having individual issues for each view layer.

114 for Angular

115 for React

Riot.js would be awesome! :+1:

Please open a new issue about it!

Would love to see support for Blaze 👍

Please open a new issue instead of commenting on a closed old one!

Would love to see vue-apollo come together. I'll be working on this myself as mentioned in the linked thread above.

Scott

I got a vue integration running!

Wow, that's awesome!

Was this page helpful?
0 / 5 - 0 ratings