Based on my personal experience, sometimes even if the API is yours, making changes can be difficult. The example I first think of is my last company.
We had a backend and frontend team, both working on the same product but the two teams disagreed a lot and would take weeks to make a small change even if it wasn't a breaking change.
To add to it all, there wasn't a standard to deprecating APIs so even a simple key rename could cause everything to blow up. Things weren't fun so I can see the need for these kinds of tools.
There is another pattern/benefit of such "client-side" transformations. You write your react components in a very generic way and rename / reshape data to fit them easily.
Sure, most people probably do. But some don't, and I guess in those cases it's good to have nice tooling to handle that.
Consider web applications without any backend using P2P technology, then you can't control the API, because you get sent data from other users directly. Once you deploy a new version, its useful to be able to transform that old data into the new format, if needed.
I would argue that its the opposite. It seems that redux is adamantly resisting the temptation to expand its scope and is sticking to its original promise of being a state container that undergoes state transitions via the composition of functionally-pure reducer functions and nothing more.
One of the primary intents behind the creation of Redux was that it would provide structure for synchronous state updates, but leave handling of async logic and methodology as a plugin system. Middleware was explicitly intended to be an extension point that would allow users to plug in their preferred approach for handling async behavior (as opposed to libs like Flummox, which had a promise-handling capability built in, but no way to modify it or use anything else). I recapped the intentions behind Redux's creation in my blog post "The Tao of Redux, Part 1 - Implementation and Intent" [0].
The idea of Redux middleware has been an unqualified success. There's several hundred middlewares now available, covering a wide range of capabilities like general async side effects, API abstractions, logging, action transformation, and much MUCH more. I have a list of just about every existing Redux middleware [1] in my Redux addons catalog [2] .
The most common Redux async side effect middlewares allow you to handle your async logic via your preference of syntax and implementation: simple functions, promises, generators, observables, or even Elm-style descriptive effects. I listed the most popular side effects libs in "The Tao of Redux, Part 2 - Practice and Philosophy" [3], there's a really good article comparing the various approaches at [4], and I have more articles on Redux side effects listed at [5].
This particular middleware appears to be primarily for transforming the contents of actions as they pass through the middleware pipeline, with the ability to resolve the transformations synchronously or asynchronously. This would likely be useful in ensuring that responses from an API have been transformed into a consistent format before they are processed by the Redux store. So, it doesn't look like it handles or implements async behavior itself, but rather allows you to write transformation logic that can be async.
Maybe I'm not getting it, but with the above methods I can already transform my actions and responses. I can also use async/await if I want to mix async and sync logic in a readable way. This just seems to layer an abstraction over that sort of thing, but for what benefit? Is this actually intended to be an alternative to redux-thunk or redux-promise-middleware, and not used in conjunction with them?
Genuinely asking for information and not trying to be critical, sometimes it's hard to see use cases and benefits of new patterns when you first encounter them :-)
redux-transform:
1. lets you transform an arbitrary number of fields with an arbitrary number of transformations
2. runs the transformers for each field concurrently
It is true that there are other opportunities to transform actions, but you would have to implement the logic to perform arbitrary transformations. You can use async/await to mix async and sync logic, but you will have to be careful about concurrency. With redux-transform, you can just focus on implementing transformers, and specifying which ones to perform.
redux-transform is intended to complement other middleware. You can use it in conjunction with both redux-thunk and redux-promise.
15 comments
[ 3.1 ms ] story [ 55.9 ms ] threadI feel like I see many projects like this with the goal of transforming data or making more requests and things after each request (redux-saga).
If you have control over the api you are interacting with, most of these things aren’t needed. Plus, less work done on the client the better, right?
We had a backend and frontend team, both working on the same product but the two teams disagreed a lot and would take weeks to make a small change even if it wasn't a breaking change.
To add to it all, there wasn't a standard to deprecating APIs so even a simple key rename could cause everything to blow up. Things weren't fun so I can see the need for these kinds of tools.
Consider web applications without any backend using P2P technology, then you can't control the API, because you get sent data from other users directly. Once you deploy a new version, its useful to be able to transform that old data into the new format, if needed.
Why do I need a framework on top of another framework to manage asynchronicity? Async should be figured out by now.
Is this just "enterprise Java" again?
The idea of Redux middleware has been an unqualified success. There's several hundred middlewares now available, covering a wide range of capabilities like general async side effects, API abstractions, logging, action transformation, and much MUCH more. I have a list of just about every existing Redux middleware [1] in my Redux addons catalog [2] .
The most common Redux async side effect middlewares allow you to handle your async logic via your preference of syntax and implementation: simple functions, promises, generators, observables, or even Elm-style descriptive effects. I listed the most popular side effects libs in "The Tao of Redux, Part 2 - Practice and Philosophy" [3], there's a really good article comparing the various approaches at [4], and I have more articles on Redux side effects listed at [5].
This particular middleware appears to be primarily for transforming the contents of actions as they pass through the middleware pipeline, with the ability to resolve the transformations synchronously or asynchronously. This would likely be useful in ensuring that responses from an API have been transformed into a consistent format before they are processed by the Redux store. So, it doesn't look like it handles or implements async behavior itself, but rather allows you to write transformation logic that can be async.
[0] http://blog.isquaredsoftware.com/2017/05/idiomatic-redux-tao...
[1] https://github.com/markerikson/redux-ecosystem-links/blob/ma...
[2] https://github.com/markerikson/redux-ecosystem-links
[3] http://blog.isquaredsoftware.com/2017/05/idiomatic-redux-tao...
[4] https://decembersoft.com/posts/what-is-the-right-way-to-do-a...
[5] https://github.com/markerikson/react-redux-links/blob/master...
You can use it to transform an API response. But more intriguingly you can use APIs to transform an action.
1) transforming actions directly inside action creators 2) transforming responses inside redux-thunk thunks or redux-promise-middleware promises
Maybe I'm not getting it, but with the above methods I can already transform my actions and responses. I can also use async/await if I want to mix async and sync logic in a readable way. This just seems to layer an abstraction over that sort of thing, but for what benefit? Is this actually intended to be an alternative to redux-thunk or redux-promise-middleware, and not used in conjunction with them?
Genuinely asking for information and not trying to be critical, sometimes it's hard to see use cases and benefits of new patterns when you first encounter them :-)
It is true that there are other opportunities to transform actions, but you would have to implement the logic to perform arbitrary transformations. You can use async/await to mix async and sync logic, but you will have to be careful about concurrency. With redux-transform, you can just focus on implementing transformers, and specifying which ones to perform.
redux-transform is intended to complement other middleware. You can use it in conjunction with both redux-thunk and redux-promise.
I'll definitely add this to my Redux addons catalog in the next update!