jamesplease / redux-resource

3kb resource management for Redux
https://redux-resource.js.org
MIT License
237 stars 28 forks source link

Create caveats guide #381

Closed jamesplease closed 4 years ago

jamesplease commented 6 years ago

Redux Resource isn't perfect. Although you should be able to do everything you need to do with the API (it has been working well for a few teams at Netflix), sometimes it isn't as obvious to do or as few lines of code as it could or should be.

Here are some of the limitations/problems that I see:

  1. It is a simple idea, but the API is complicated. It shares this in common with Redux, but it is an even more extreme version, because Redux Resource is more complex than Redux itself. Even as the author, I find myself using the website frequently to remember how the API works. I used to have the API memorized, but I forget it now. It must be worse for users who did not write it or who never had it memorized.

  2. The normalization story going "into" the store is good, but it is bad when reading from the store to "put things back together," so to speak. Because there are no model definitions for your data nor a special place to store relationships, you must manually piece de-normalized data back together, which makes for verbose code in the view layer. If you have a resource with, say, 10 relationships that you have normalized, you can get that into the store in just a few lines of code, but pulling it out will take at least 10 different calls to getResources. That is no good.

  3. In the same vein, making a request and setting a status is relatively straightforward once you do it a few times. But then all of the getStatus calls that you need to call in mapStateToProps can add up. Add to that aggregation for "serial" requests, and the code can be difficult to read.

What caused these things?

  1. By making the barrier of entry lower (by making the resource definition so flexible), the consequence is that it puts more work on the developer using the API. With either a model or a stricter resource definition (such as a special relationships attribute), you could call getResource(...) and get back the model and all of its relationships in one call.

  2. Without React bindings, there is a disconnect between making a request and receiving the data from the request. The React bindings would simplify this considerably (if you make a request, you would be subscribed to all of the resources returned from the request, and their future updates).

  3. Redux Resource, like any Redux library, has two goals: the first is to help you do the thing that you are trying to do. The second is to help reduce Redux boilerplate. I think it is a problem with anything built around Redux that the motivations are split like this. I probably put too much emphasis in the "reduce Redux boilerplate" part and not enough in the first part. It's not that it is impossible to do, by the way (Apollo is a great example, as it was built on Redux originally, and they had a really solid wrapping API for it. With that said, their scope is, in some sense, narrower given GraphQL's organized structure). It is just that a solution here does not currently exist.


Anyway, I am happy with the positive feedback I have gotten from Redux Resource. It is just that, with all things, there are improvements to be made!

If I am being honest, I think that a normalization layer built around context will be more fruitful. IMO Redux has been, and continues to be, the wrong solution in pretty much every situation for storing data in a UI app. The boilerplate cost for time travel debugging is too high, and not everybody takes advantage of it. The Redux alternative libraries can reduce boilerplate by a tremendous amount at the expense of losing time travel. That is worth it imo.

That doesn't mean I am giving up on Redux Resource, or anything. I have a lot of apps that depend on it, and I think that these problems can be solved. I will likely spend time this year improving Redux Resource and also considering a similar solution but with context/Unstated as the storage layer.

Thanks for reading!