Skip to content
This repository has been archived by the owner on Apr 14, 2023. It is now read-only.

Client Side API #1

Closed
arunoda opened this issue Jan 26, 2016 · 59 comments
Closed

Client Side API #1

arunoda opened this issue Jan 26, 2016 · 59 comments

Comments

@arunoda
Copy link
Contributor

arunoda commented Jan 26, 2016

Hi,

I'm really looking at how the client of this will work? What's are the plans?
For the reactive part, I suggest to use something like Rx.js instead making it Tracker based.

And distribute it via NPM. Not sure whether Lokka fits into this or now. But I like to discuss.
May be we can share some ideas.

@faceyspacey
Copy link

I also think the Client Side API is very important. Basically GraphQL and Relay have no sufficient client side story. Om Next has an API to supply a client-side datasource. Basically I think you should be able to make GraphQL types client-side and query/mutate them just as you would the server.

In addition, to do this really right, requires a way to have a hybrid type (one that lives on both the client and server), and then give the developer the ability to persist a corresponding client object to the server when it is complete (canonical example: a wizard where you complete a model over several steps, which must be cached client side along the way).

As far as Rx, @arunoda are you suggesting we use observables to represent data coming from the server? Like in Cycle? Basically, this is a major decision we gotta make. One of I've been grappling with for a while. Observables are true time-varying values, whereas what React does with state (coming from within itself or from Relay or Redux) is just re-run your code with no intelligent awareness of which primitives are reactive.

I can't even say which path I'd choose right now. I love the concept of first class time-varying primitives/variables. But at the same time, the React style is currently much more accessible than Elm and Cycle.


In general, this is why I've been saying it's all about Relay. From the application developer's perspective they will be concerning themselves more with the client-side state management interface more than simple graphql queries and mutations. If the system is done correctly, the graphql aspect is just little strings you sprinkle in obvious places, whereas the client-side state management architecture that brings it all together defines the readability, extensibility and overall quality of your code.

Redux isn't the final answer. Either is Relay. However, a final [enough] answer worth sticking to (like React is generally for the view layer) is coming. That's the hard part. It's not gonna be this never-ending "fatigue" sort of situation--we'll eventually land on something like we have GraphQL and React. For a while I thought Relay was the final answer, but it's not. There's many cross-cutting concerns like Routers which are causing distortions in the main state management play. That's why we're seeing solutions come out that try to merge some other aspect of state such as Routing with Redux.

You guys already know my main points. But the point is that this area of "research" is not solved--but it's also not far off. Whatever we do, we must stay flexible here (and I do think that's @stubailo's goal), but at the same time start thinking of our own vision for an all-encompassing interface here. I certainly wouldn't like to see it be just a hodge-podge of different tools each specialized in a different aspect of state. We're either gonna have to wait for the javascript community to evolve this client side state management system of choice, wait for Relay to become it, or put out something forward-thinking of our own.

@stubailo
Copy link
Contributor

What do we gain from using any reactive programming library for the internal implementation over something super basic and core like an event emitter? Like what features does Rx.js get us?

@stubailo
Copy link
Contributor

To clarify some of the other basic points:

  1. It will 100% be distributed on NPM, with whatever wrapper needed to make it work well in Meteor.
  2. My goal is to reuse as much of relay as humanly possible - they already have great query aggregation, the relay store, AST manipulation, etc. I'm going to take an in depth look at the relay architecture for that. I implemented a prototype with Lokka but I don't think it's enough compared to what Relay internals have, for example query and fragment variables.

@faceyspacey
Copy link

Something tells me @arunoda was talking about the basic point where the data arrives on the client and you can start using it. So he's basically talking about the "low level" client side API and I'm talking about the high level architecture. Both of which are important. ..It seems to me that the low level API should be sufficiently "low level" enough to allow it to present itself as Rx observables, event emitters, or even Tracker datasources. What Meteor endorses as it's documented API, I'm not sure. It should tell a consistent story with the architecture though.

@faceyspacey
Copy link

It will 100% be distributed on NPM, with whatever wrapper needed to make it work well in Meteor.

excellent! That makes me so much more excited to contribute to it, being that I've been so bummed lately about Meteor falling behind. This way I know I'm contributing to something that I can use even if I don't continue to choose Meteor (which if all goes well hopefully won't be the case).

My goal is to reuse as much of relay as humanly possible

I think that's a good approach too. The problem domain is sufficiently complex that we can only learn our path forward by the steps taken by the innovator in the space. Same with Redux, but the code is a lot smaller there. I'm in no way married to Relay itself. I've come around to what I think you guys were saying the other day about GraphQL being the driver here--the only thing really to consider is whether Relay does become a standard and any marketing edge we'll lose by building something separate. I think we can all agree that we can't have another Blaze to React situation. It will be very interesting to see if Relay gets any major updates at React conf. As it currently stands, it desperately needs someone to take their concept and get it right like Redux did to Flux. The only difference is that with Relay they released a whole lot more than the initial Flux example, which always indicated to me that it might not be a Redux situation and might be able to stand on its own like React originally did. We gotta be wary about that before we go competing with Facebook again. However, that should never stop us if we think we've come up with something truly innovative and effective.

I feel like the general path forward (for the client side state management architecture) should be:

  1. attempt to add features to Relay itself (the optimum scenario)
  2. if that's not possible, fork it.
  3. If we find out they somehow really got it wrong and their architecture isn't as expansive as we need, we take what we learned and perhaps some code and set out on our own.

In addition, we need to know what Falcor and Om Next are doing in and out, and basically monitor everything that comes out that's related. There's a perfect architecture all these tools are leading us toward. We just gotta find what that is. The nutshell that sums up the starting concept is Redux + Relay in one (UI state + Domain State in one). Then pin-point any other types of state and envision a consistent interface for it all.

@arunoda
Copy link
Contributor Author

arunoda commented Jan 26, 2016

@stubailo

What do we gain from using any reactive programming library for the internal implementation over something super basic and core like an event emitter? Like what features does Rx.js get us?

Since we don't have Blaze, tracker's use case is very minimal. And Mobservable is doing a Great job in the React world and there won't be a good space for Tracker.

Rx.js is has the stuff a subscription API should have. It's used everywhere else.

As you said it in the podcast. It's just another tool. I thought it'll be useful when we are starting from the scratch.

  1. It will 100% be distributed on NPM, with whatever wrapper needed to make it work well in Meteor.
    My goal is to reuse as much of relay as humanly possible - they already have great query aggregation, the relay store, AST manipulation, etc. I'm going to take an in depth look at the relay architecture for that.
  2. I implemented a prototype with Lokka but I don't think it's enough compared to what Relay internals have, for example query and fragment variables.

+1 to that. Was curious to learn what you guys are building.

@stubailo
Copy link
Contributor

@arunoda I understand it will be valuable to have the external interface integrate with a reactive programming library, and I'm sure we will have an integration with Tracker, Rx.js, and people can build others as well.

But should we be using one of these internally as an implementation component? And what do we gain from that? Perhaps that is a different thread, since this is about "client side API".

@arunoda I'm curious if you have taken a deep look at Relay's components - I've been doing some in-depth code diving to see how the query aggregation, data fetching, and the cache work, have you done anything similar that you could share?

@arunoda
Copy link
Contributor Author

arunoda commented Jan 26, 2016

@stubailo

I understand it will be valuable to have the external interface integrate with a reactive programming library, and I'm sure we will have an integration with Tracker, Rx.js, and people can build others as well.

That's a good plan.

I'm curious if you have taken a deep look at Relay's components - I've been doing some in-depth code diving to see how the query aggregation, data fetching, and the cache work, have you done anything similar that you could share?

I tried to digging it. I was hard and very tightly coupled. They said, they are working on a store isolation on the roadmap. I was waiting for that and plan was to use it in Lokka.

@sebakerckhof
Copy link

@stubailo Since you've already done the work, it might enhance community feedback in this project if you could write an article on how the query aggregation etc in relay actually works. I'd be very interested to read about this.

@stubailo
Copy link
Contributor

Yeah I definitely will - first I need to make a rough map of everything though. I also want to have that as a starting point to talk to the relay people at Facebook about it.

@jeveloper
Copy link

I have a feeling it's going to work very well with Angular 2.0
Looking forward.
thx

@stubailo
Copy link
Contributor

stubailo commented Feb 9, 2016

@arunoda I'm going to publish the following package to make it easier to use Relay without Babel 6 and special plugins: #7

Let me know what you think of that? I already have something working privately, but it was one of the things that made Lokka a lot simpler to use for me - that I could just pass a string instead of having a complicated compilation process.

@arunoda
Copy link
Contributor Author

arunoda commented Feb 9, 2016

@stubailo Yeah! I really like that.
I hope FB went with babel plugin because, they can give better error messages.
(Because relay knows the schema already).

But I think that should be something we can add later on if needed.
When trying out, the we need to have the simplest possible way.

Publish it and write some simple app.
I hope this will be a great starting point.

@stubailo
Copy link
Contributor

stubailo commented Feb 9, 2016

I hope FB went with babel plugin because, they can give better error messages.
(Because relay knows the schema already).

My plan is to have the client fetch the schema when it initializes. So we should get good error messages too! Only thing is, you will only check the queries that run, you don't get it statically at build time.

@arunoda
Copy link
Contributor Author

arunoda commented Feb 9, 2016

@stubailo That's exactly what I was trying to do with Lokka.
I think this is good and we can have multiple schemas if needed.

I think statically checking is not required for most cases. We can live with runtime errors at development.

@stubailo
Copy link
Contributor

stubailo commented Feb 9, 2016

OK, hopefully I can make this a nice package and we can integrate it into Lokka. My main goal is to slowly unpack all of the Relay magic until I understand how every piece works!

@arunoda
Copy link
Contributor Author

arunoda commented Feb 9, 2016

Awesome!
Can't wait to see that and initial draft.

@stubailo
Copy link
Contributor

@arunoda here's the package!

https://github.com/meteor/relay-runtime-query

Should make Relay a lot easier to drop in to any app. Although it has a lot of dependencies right now like React and friends, so it's not yet a good replacement for something lightweight like Lokka. Perhaps I can talk to the Relay team about when they are planning on splitting that out.

@arunoda
Copy link
Contributor Author

arunoda commented Feb 19, 2016

@stubailo yeah. I think it's better if we discuss it there as well.

@jbaxleyiii
Copy link
Contributor

@stubailo not sure if this is the best place for this but I've been thinking about the localized / in device state versus the remote data a little bit. At first I was planning on keeping our current redux model for local app state and using the client side of Apollo (relay store) for keeping track of remote data. This would get hairy quickly as action dispatchers would be creating mutations to send to the GQL server.

However I think this gets confusing quickly and at the end of the day doesn't seem like a good long term solution for developer experience / testing. I think, if possible, modeling a localized GQL endpoint and allowing local nodes to coexist with remote nodes could be great. This isn't a new idea and facebook/relay#114 goes into a lot of it.

fragment Foo on User {
  name,                     # server field
  drafts(first: 10) {       # client-only field
    edges { node { title } }
  }
}

This could allow for state concerns to be binary from a UI standpoint (at least from a react standpoint, although blaze and angular would be applicable):

  • local to this component - this.state
  • part of the app state (local or remote) - Apollo queries / mutations

That being said, I really love redux and the methodology around it. With the reactivity of Apollo, setting up an @connect() decorator for a react component would work for both remote and local data.

@stubailo
Copy link
Contributor

@jbaxleyiii more and more I'm starting to think that Relay might be more complicated than necessary for most use cases - what do you think about the idea of making a simple Redux GraphQL client with some of the features people like in Relay (optimistic UI, query merging, etc)?

If you already have a start on this I'd love to check it out and help improve it.

@stubailo
Copy link
Contributor

Mostly, people just really really love the ease of debugging and composing different data sources with Redux - as you said "I really love redux and the methodology around it." - so maybe it's worth trying to preserve that rather than adopting a more opaque data store like Relay.

@ansarizafar
Copy link

@stubailo
Copy link
Contributor

There's also a redux GraphQL cache called adrenaline which seems nice.

@stubailo
Copy link
Contributor

(I think you meant this link: https://github.com/mattkrick/cashay)

That looks cool but I think Adrenaline is much more complete: https://github.com/gyzerok/adrenaline

Also, I don't think you should have to call query manually - it should let you specify data requirements declaratively, that's like the best and most important part of Relay.

@jbaxleyiii
Copy link
Contributor

@stubailo that sounds good me to me. Redux is pretty great, and when combined with redux-saga, makes for super easy to understand code.

For example, here is a stripped down version of our login saga

function* login(getState) {
  const currentState = getState()
  const { data, state } = currentState.onBoard

  if (data.email && data.password) {
    let { email, password } = data

    // set the UI to show the loading screen
    yield put(actions.loading())

    try {
      // make the call to try and login
      // this calls a Meteor method to login through an exterior application
      let isAuthorized = yield cps(auth.login, email, password)

      if (isAuthorized) {
        // return Meteor login to parent saga
        // note Meteor.loginWithPassword will only return an Error, not a success
        const result = yield cps(Meteor.loginWithPassword, email, password)
        if (isAuthorized) {
          return { result: isAuthorized }
        } else {
          return { error: new Meteor.Error("An unkown error occured") }
        }
      }

    } catch (error) {
      return { error }
    }

  }

}

I haven't had the time yet to write a good system to combine GQL and Redux. Currently just doing the query on the container and updating custom stores as needed (which will be getting out of hand soon, but not before we launch so necessary evil)

here is a sample https://github.com/NewSpring/Apollos/blob/master/profile/pages/home/index.jsx#L23-L47

One of the things that is nice with redux when also using react router is the ability to setup a static fetchData method for server side rendering. With this we have been able to have close to full spec progressively enhanced sites.

I think adrenaline is pretty fantastic and had looked at integrating it but haven't found the time yet.

@jbaxleyiii
Copy link
Contributor

If we go the redux route, the connect method with react-redux is a great pattern to expand to Blaze. You can specify the data you want (much like a Mongo.Collection), and it will rerun the template on data change. Its a pretty easy way to add the reactive UI based on data.

@stubailo
Copy link
Contributor

@jbaxleyiii I'm glad you're excited about this approach!

I haven't had the time yet to write a good system to combine GQL and Redux. Currently just doing the query on the container and updating custom stores as needed (which will be getting out of hand soon, but not before we launch so necessary evil)

Maybe this is one of the first things we can collaborate on? We should decide if we want to collaborate with Adrenaline or build a new thing, a short conversation here: #14

@ansarizafar
Copy link

I don't think its a right approach. Considering the goals, MDG sets for new Data layer, creating wrappers/hacks around existing implementations GraphQL/Realy/Adrenaline etc, is not a good long term strategy. In my opinion, a custom GraphQL server/client should be developed from scratch , by utilizing GraphQL specification and MDG's new data layer design which has its own requirements like invalidation server. I know its more work but we will not be dependent on existing implementations and their shortcomings.

@stubailo
Copy link
Contributor

In my opinion, a custom GraphQL server/client should be developed from scratch

I dunno, in my opinion it's almost never a good idea to build anything from scratch. But yes, there is a big benefit to understanding all of the moving parts, which is why I would prefer something simpler like Redux.

@ansarizafar
Copy link

Redux addon!!! Is Apollo for React only? What about Angular, Ember, VueJS, Aurelia etc. Not everyone is a fan of Redux even in react community. Check this video from React.js Conf 2016 - Ben Alpert - What Lies Ahead .https://www.youtube.com/watch?v=-RJf2jYzs8A&list=PLb0IAmt7-GS0M8Q95RIc2lOM6nc77q1IY&index=2 Please also check these links https://github.com/mobxjs/mobx and http://survivejs.com/blog/mobservable-interview/ and https://news.ycombinator.com/item?id=11181980 Genuine solutions can only be build from scratch.

@arunoda
Copy link
Contributor Author

arunoda commented Feb 27, 2016

@stubailo I think it's better for us to focus on a pure JS client library for now. Let's worry about specific addons later on. I think, if we've a solid core, it'd be easy for the community to build amazing stuff on top of it.

@ansarizafar
Copy link

I couldn't agree with @arunoda more.

@laosb
Copy link

laosb commented Feb 27, 2016

+1 for @arunoda

@stubailo
Copy link
Contributor

As I understand, Redux is a very simple and small library for managing state. Even if the apollo client uses it internally, it would be trivial to hide that behind a standard callback or promise API to integrate with any data consumer you want. What's the benefit of avoiding a very small internal dependency to make data management simpler?

On the other hand, the benefits are huge: Redux has great developer tools and great semantics in regards to actions that can help implement optimistic UI and debugging. There are also many integrations between redux and many view layers (Angular, etc) that can serve as a template to build on.

I guess at the end of the day, as long as you don't have to care it has Redux inside, what does it matter? It's not like we will be asking people to build their whole app around Redux.

@stubailo
Copy link
Contributor

I think this came from this statement I made, which was wrong of me to say:

I totally agree that it should be an addon

Which I agree says "you need to use Redux in your app to use this" but I think I stated it incorrectly. I should have said something like "you would be able to use it as an addon if you are already using Redux, or standalone if you don't care about Redux".

@yodacom
Copy link

yodacom commented Feb 29, 2016

Well said

All the best,

Jeremy

Yoda of YodaCom
jb@yodacom.com
www.yodacom.com

Standard Disclosure:
YodaCom is a mobile application architect, strategist, and developer.
*
“YodaCom
is also a DMTA - Digital Marketing Technology Architect and Advisor. *

On Sun, Feb 28, 2016 at 5:45 PM, Sashko Stubailo notifications@github.com
wrote:

I think this came from this statement I made, which was wrong of me to say:

I totally agree that it should be an addon

Which I agree says "you need to use Redux in your app to use this" but I
think I stated it incorrectly. I should have said something like "you would
be able to use it as an addon if you are already using Redux, or standalone
if you don't care about Redux".


Reply to this email directly or view it on GitHub
#1 (comment).

@arunoda
Copy link
Contributor Author

arunoda commented Feb 29, 2016

@stubailo I'm bit curious and confused. According to your comment, it seems like we are going to use Redux(or Redux based GraphQL clients) internally. What happen to the Relay story?

As I understand, Redux is a very simple and small library for managing state. Even if the apollo client uses it internally, it would be trivial to hide that behind a standard callback or promise API to integrate with any data consumer you want. What's the benefit of avoiding a very small internal dependency to make data management simpler?

Yes, Redux is a simple library and has a great community.

But...

I think we should do this other way around. Build a great JavaScript cache layer for Apollo. Then extend from there.

There are also many integrations between redux and many view layers (Angular, etc) that can serve as a template to build on.

But, only a very few use it in the Angular world.

@ansarizafar
Copy link

@arunoda is absolutely right.

@stubailo
Copy link
Contributor

OK, let's start over - I think this conversation has gotten a bit muddled since I am changing my opinion from the beginning.

Here's what we need:

  1. A GraphQL client for JavaScript
  2. That supports optimistic UI
  3. That can refetch parts of queries
  4. That can aggregate queries from multiple UI components
  5. That can handle changing data needs gracefully without refetching everything
  6. That is easy to understand, work with, and debug

Here are the options for building it:

  1. Use the Relay Store from Facebook. It has a lot of nice features, including hooks to do many of the above, and is being constantly developed and improved. I've worked with the relay internals for a bit, and I feel like the majority of applications don't need many of the features there. On the other hand, it is very hard to debug and it takes a very long time to understand what is going on in the internals. Note that there is no Relay integration for any view layer that is not React - we would have to build this ourselves in this scenario.
  2. Write a new cache that uses Redux internally to manage state. We get a library that knows how to do a lot of useful debugging stuff like time-travel and do optimistic UI. On the other hand, we have to write the GraphQL specific parts from scratch. This means we won't have some of the fancy performance features in Relay, but we get something that we completely understand and can debug and optimize to fit our needs. We will also have to build integrations for different view layers ourselves.
  3. Write something from scratch that doesn't use Relay or Redux or any library for managing state. This doesn't seem like a very attractive option, because in this case we don't get the fancy features from Relay, or the debugging support from Redux. We have to build absolutely everything, including a way to manage the cache state and the GraphQL-related concerns. In this scenario we still have to build integrations for all of the view layers ourselves.

Bottom line

After working with Relay for a while, I think we could get a very usable GraphQL client the fastest if we don't rely on Relay internals at first. I think we would get a productivity boost from using Redux, which has lots of nice features that help with the specific use cases we need. Writing something from scratch doesn't make sense to me, since it's strictly more work than both of the other options for no benefit that I can see.

@bwhitty
Copy link

bwhitty commented Feb 29, 2016

This may be pedantic, but why doesn't 2 say "Wirte a new cache that uses some state management library internally". I see you mention time traveling debugging as a reason to use Redux, but there is another tool which offers that and does not require you to go the immutable state-as-a-tree route: https://github.com/mobxjs/mobx (previously mobservable). It is a transparent reactive programming library which seems to be heavily influenced by Tracker, but does a few key things differently. I only mention this because it feels very familiar. Not saying it's the best way to implement what you're trying to achieve internally (or as the public API), but wanted to throw it out there.

@ansarizafar
Copy link

Here is a generic relay version which doesn't depend on React https://github.com/andimarek/generic-relay Facebook Relay team is also working to separate Relay from React facebook/relay#559

@stubailo
Copy link
Contributor

but why doesn't 2 say "Wirte a new cache that uses some state management library internally"

As far as I can tell Redux has the most traction out of the alternatives. But I could be convinced otherwise with numbers. Also, Redux isn't just about reactive programming, I think the "immutable state as a tree" is exactly what a GraphQL cache needs to be. You shouldn't be reaching in and mutating the state of the cache directly since then the cache won't work.

Here is a generic relay version which doesn't depend on React https://github.com/andimarek/generic-relay Facebook Relay team is also working to separate Relay from React facebook/relay#559

Yes, these are great projects. I'm actually talking to the team from generic relay soon, maybe we can collaborate. If the generic relay thing goes well (and we should work with that team if we decide it is a good approach) then that's going to be great. But I have two fears about this:

  1. It will take too long to get a truly decoupled Relay store that doesn't depend on Relay Router, React, and a special Babel 6 plugin.
  2. Even if such a thing exists it will be very hard to understand, and most people will want something simple that "just works".

I'm excited to talk to the generic-relay team to see if they have any of the same concerns, and what their use case is for the Angular2-Relay project in production.

@ansarizafar
Copy link

Check this video from React.js Conf 2016 - Ben Alpert - What Lies Ahead .https://www.youtube.com/watch?v=-RJf2jYzs8A&list=PLb0IAmt7-GS0M8Q95RIc2lOM6nc77q1IY&index=2 to know what Facebook is thinking about the future of relay.

@stubailo
Copy link
Contributor

Are you referring to this slide and the surrounding content?

screenshot 2016-02-29 10 18 35

If anything, this supports using Redux IMO? At least until this great new data management solution comes out. Perhaps we could be that thing that unifies Redux data management and Relay-style caching and refetching.

@ansarizafar
Copy link

Yes I am referring to this part of the talk. It seems that Facebook is not happy with existing data management solutions as a whole and they want a new solution by combing the best ideas.

@stubailo
Copy link
Contributor

I completely agree!

@arunoda
Copy link
Contributor Author

arunoda commented Feb 29, 2016

@stubailo

I feel pretty sad about this decision to use Redux. This is why I think we should not need to worry about redux. If I am doing this this is the approach I used.

  • Create a JS client which has a superb Reactive GraphQL cache and a mutation API
  • Then create an API to watch it (Callback based, Rxjs or any)
  • Then create a thin wrapper for Redux
  • Then may be Mobx, Vue's data layer, Angular and Tracker (community will help us)

Redux devtools are fancy. But I'm not sure how useful they are in the real world. How ofter people need, replay and rewind. (If we follow a good architecture, we don't need it.)
(Anyway, that's not the issue here.)

Think what Redux will bring us to the table other than the Marketing push.

It seems like you are set on this and I'll help whatever I can. But I don't like this direction.

This is my last post on the Redux topic as I not a fan of debating.

@stubailo
Copy link
Contributor

Think what Redux will bring us to the table other than the Marketing push.

I agree, if the only benefit of Redux is marketing then we should not use it internally. I think the only answer is to build it and see what benefits we might or might not get. Hopefully I can get something built this week and we can talk in much more concrete terms.

@arunoda
Copy link
Contributor Author

arunoda commented Mar 1, 2016

Great.

@smooJitter
Copy link

I'd like to add a few words to this. I start following Mantra in October. I am new guy. I started on this personal project about 12 months ago. To make a long story short, as a guy who knows a little more about marketing, product life cycles, and diffusion of innovation than I do about Node.js. Everyday for the last 8 months, I have spent about 2 hrs checking to see what's new with Meteor, Meteor Guild, Mantra, and lately React (Wes Bos) and React-Native. I am probably biased (... no definitely biased ); but, it seems to me that Meteor + Apollo + Mantra does not need "Brand" support from Redux.

@schickling
Copy link

This might be another interesting approach: https://github.com/relax/relate

@stubailo
Copy link
Contributor

stubailo commented Mar 7, 2016

@schickling this is pretty similar to what I was thinking, but doesn't look quite finished. Always good to have more stuff to look at!

@stubailo
Copy link
Contributor

Hi guys!

I have started working on a GraphQL cache. So far, there is nothing related to Redux at all, so I think it will be interesting to everyone (we'll cross that bridge if we get there, maybe we don't need it). Basically, right now there are two functions:

  1. write to the cache
  2. read from the cache

So if you have already put a query result in the cache, you can run a new query that asks for the same data entirely client-side. This will allow (1) reducing roundtrips if you already have the data, and (2) very simple optimistic UI where you simply modify the cache and run the query again.

Take a look, I think the tests will be the most informative:

  1. writing to the cache: https://github.com/apollostack/apollo-client/blob/master/test/writeToStore.js
  2. reading from the cache: https://github.com/apollostack/apollo-client/blob/master/test/readFromStore.js
  3. doing both with the same query: https://github.com/apollostack/apollo-client/blob/master/test/roundtrip.js

Next up (not necessarily in this order):

  1. making a client that actually sends queries over the network
  2. increasing the space of working queries (right now it only works with queries and fragments, but not mutations, for example)
  3. investigating optimistic UI
  4. diffing queries against the cache - if we already have the data on the client, fetching only the fragments we don't have yet
  5. pagination and cursors

So far, I think I've been successful in keeping the logic and the cache format itself quite simple, and everything is in very plain functions. Ideally it will be very easy to understand what is going on and contribute improvements.

Everything is completely test-driven and fully linted. So the code is quite clean!

@manuelfink
Copy link

@stubailo

  1. Do you have any preferred frontend framework? Angular 2? React?
  2. Will combining multiple queries like in relay be part of the strategy? I like the idea of relay requesting data for nested components at once.

@stubailo
Copy link
Contributor

@funnyprinter great question! Just opened a PR for a design doc: apollographql/apollo-client#7

  1. I do personally prefer React right now. I think Angular 2 is also very exciting. At the end of the day, I want to make sure that there are exactly 0 references to React in the Apollo core, and have good documentation for integrating with any view layer you like.
  2. Yes, this is one of Relay's best features, and it's a great opportunity brought by GraphQL's nested structure. I think we should absolutely have it - a core version that is view-layer agnostic, and then integrations for React, Angular, etc.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests