-
Notifications
You must be signed in to change notification settings - Fork 424
Client Side API #1
Comments
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. |
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? |
To clarify some of the other basic points:
|
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. |
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).
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:
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. |
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 to that. Was curious to learn what you guys are building. |
@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? |
That's a good plan.
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. |
@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. |
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. |
I have a feeling it's going to work very well with Angular 2.0 |
@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. |
@stubailo Yeah! I really like that. But I think that should be something we can add later on if needed. Publish it and write some simple app. |
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. |
@stubailo That's exactly what I was trying to do with Lokka. I think statically checking is not required for most cases. We can live with runtime errors at development. |
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! |
Awesome! |
@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. |
@stubailo yeah. I think it's better if we discuss it there as well. |
@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.
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):
That being said, I really love redux and the methodology around it. With the reactivity of Apollo, setting up an |
@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. |
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. |
There's also a redux GraphQL cache called adrenaline which seems nice. |
(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. |
@stubailo that sounds good me to me. Redux is pretty great, and when combined with redux-saga, makes for super easy to understand code.
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)
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. |
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. |
@jbaxleyiii I'm glad you're excited about this approach!
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 |
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. |
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. |
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. |
@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. |
I couldn't agree with @arunoda more. |
+1 for @arunoda |
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. |
I think this came from this statement I made, which was wrong of me to say:
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". |
Well said All the best, Jeremy Yoda of YodaCom Standard Disclosure: On Sun, Feb 28, 2016 at 5:45 PM, Sashko Stubailo [email protected]
|
@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?
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.
But, only a very few use it in the Angular world. |
@arunoda is absolutely right. |
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:
Here are the options for building it:
Bottom lineAfter 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. |
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. |
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 |
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.
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:
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. |
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. |
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. |
I completely agree! |
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.
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.) 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.
|
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. |
Great. |
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. |
This might be another interesting approach: https://github.com/relax/relate |
@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! |
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:
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:
Next up (not necessarily in this order):
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! |
|
@funnyprinter great question! Just opened a PR for a design doc: apollographql/apollo-client#7
|
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.
The text was updated successfully, but these errors were encountered: