Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Grouping requests by datatype #336

Open
zeraien opened this issue Apr 29, 2020 · 4 comments
Open

Grouping requests by datatype #336

zeraien opened this issue Apr 29, 2020 · 4 comments

Comments

@zeraien
Copy link

zeraien commented Apr 29, 2020

I might be completely off base here, but I feel like there needs to be a way to group requests by data type.

If you have two requests, LOAD_OBJECT+requestKey and LOADS_OBJECTS, and you decide to delete an OBJECT, you need to write a mutation that mutates both requests, which I suppose is fine, unless you happen to have even more requests like LOAD_OBJECTS_BY_JOB and LOAD_OBJECTS_BY_CLIENT etc, all need to be added in the delete mutator.
But then, you also need to make LOAD_OBJECT+requestKey mutate the LOADS_OBJECTS request, and maybe even LOAD_OBJECTS_BY_CLIENT need to mutate LOAD_OBJECTS, depending on your situation. In theory it is doable, but it might become an issue down the road, and turn into a spaghetti of mutations.

In theory you could group the requests by some arbitrary key and mutate that key instead?

For example, I have a situation where I LOAD_OBJECTS, but when a single OBJECT is updated, I actually push a WebSockets update to the client with the new OBJECT, which then triggers a fake requests request (I wrote a simple driver that allows me to make local requests hehe), anyway, I digress, this new updated OBJECT triggers LOAD_OBJECT+requestKey, but in order to update the remaining OBJECTS in LOAD_OBJECTS, it needs to mutate this.
Subsequently, if any OBJECT is deleted, the DELETE_OBJECT request is triggered which needs to mutate both LOAD_OBJECTS and LOAD_OBJECT+requestKey...

And then you have to add to that all the different update mutators etc. In theory, because of normalization, the data is updated anyway, but if you want to do optimistic updates you need to write mutations for every request that touches those objects...

I don't have a full idea yet because I'm still trying to figure out the best way to handle mutations in my own code... This library is really cool and offers quite a bit of epic functionality so I am trying to make it work for me :-)

Anyway, I'm not sure it's a good idea, but I figure I'll start the conversation and we'll see where it goes.

@klis87
Copy link
Owner

klis87 commented Apr 29, 2020

I dont have much time to go deep in your post at this time, but I hope I got the whole idea.

Generally with normalisation all data updates will be automatic, apart from array mutations (and only those top level, will show you what I mean).

The issue is, you can have query ALL_BOOKS, and FAVOURITE_BOOKS, if you have a mutation add book, how we can know this should mutate 1 query or both. In Apollo this is also not possible, because probably there is no way to predict that. Maybe we could think about some helpers, but full automation is not possible like in case of object updates.

However, if you have an object like { id: '1', name: 'book name', 'authors': ['1', '2'] }, then returning { id: '1', 'authors': ['1', '2', '3'] } will work because this is not top level array mutation, but array child of an object with id.

Speaking about optimistic updates, you have meta.optimisticData, did you try it? also there is revertedData if optimistic update fails and localData for local updates

@klis87
Copy link
Owner

klis87 commented Apr 29, 2020

I also thought about this, but have other important todos, very curious indeed where conversation will lead us :)

I am also very interested with fragment idea from your another issue to fetch objects by id, this will be added for sure.

@zeraien
Copy link
Author

zeraien commented Apr 29, 2020

Well, I'll throw in some thoughts.
It's true that thanks to your epic normalization feature, all data within the objects is shared and updated, so most use cases are already solved.
But there are still some I feel that could be considered.

The case you mentioned, FAVOURITE_BOOKS and ALL_BOOKS, could be interesting. If a book is marked as favorite, it will need a mutation to come to FAVORITE_BOOKS (especially if you don't make a new request), but what if the FAVORITE_BOOKS request could sense new favorite books automatically based on a group+criteria...

The bigger use case is if you have ALL_BOOKS and BOOKS_BY_AUTHOR+requestKey, if a new book appears under BOOKS_BY_AUTHOR, it will not appear in ALL_BOOKS without a specific mutation. And if you happen to have BOOKS_BY_YEAR as well and BOOKS_BY_TAG, you're in for a lot of mutation when something is deleted or it's tag or year changed.

So if we have a grouping key, perhaps even with a function that tells us what data fits here...
Like:

const booksByAuthor = (author) => ({
    type: BOOKS_BY_AUTHOR,
    meta: {
        requestKey: author,
        groupKey: "book",
        grouper: (book)=>book.author===author
    }
})

const favoriteBooks = {
    type: FAVORITE_BOOKS,
    meta: {
        groupKey: "book",
        grouper: (book)=>book.favorite===true
    }
}

Not sure if it's a good idea or not, but in theory it should allow ALL_BOOKS to push all the books into the various sub-requests and if there is a change, like a book is updated, it can be distributed to it's groups using the grouper functions...

Eh, I'm not sure.

@klis87
Copy link
Owner

klis87 commented Dec 5, 2020

@zeraien thx for those snippets, this topic is super interesting, I cannot work on it though as there are other important stuff on TODO list, but surely I will come back to this at some point, will definitely let you know about potential API before implementation!

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

No branches or pull requests

2 participants