Ben Nadel
On User Experience (UX) Design, JavaScript, ColdFusion, Node.js, Life, and Love.
Ben Nadel at the jQuery Conference 2010 (Boston, MA) with: Adam Kirschner
Ben Nadel at the jQuery Conference 2010 (Boston, MA) with: Adam Kirschner@hikirsch )

AngularJS $http Interceptors vs. Redux Middleware - Why The Disconnect?

By Ben Nadel on

Yesterday, I came out strongly against the use of Middleware in Redux claiming that I felt it was Redux taking on too much responsibility. But, after I wrote that post, I got to thinking about the $http service in AngularJS. The $http service allows us to define interceptors which wrap around the AJAX request in the promise-chain that executes the HTTP workflow. Well, you don't have to squint all that hard to interpret the $http interceptors and the promise chain as a sort of "middleware" for the AJAX request. So, why does that approach seem "OK" to me while the Redux middleware makes me so uncomfortable?


 
 
 

 
AngularJS $http interceptors vs. Redux middleware - basically the same flow of control.  
 
 
 

First of all, there's no doubt in my mind that some of the pushback I feel towards Redux middleware comes from my own fear and insecurities about new technology and, especially, the trouble that I've personally had in learning Redux. To not admit that would be foolish and naive. But, even when I try embrace that fact, the two different workflows still feel like they have a fundamental difference. Maybe if I could outline some of the differences, it would help get at the root of the disconnect.

The AngularJS $http service will always be asynchronous. No matter what you do in the $http interceptors, the result always comes back in an asynchronous promise. In Redux, you can use middleware to fundamentally change the flow of control, converting it from synchronous process to an asynchronous process.

With an AJAX request workflow, there is an inherent need to transform data. The AngularJS $http service uses the interceptors internally to convert configuration data into an AJAX payload and then to convert an AJAX response into a result. With the Redux action, there is no inherent need to trasform incoming data - that is the job of the reducers (to translate action data into state change).

While not a critical difference, implementing an AngularJS $http interceptor is more straightforward - it's just another .then() in a single promise chain. Implementing Redux middleware, on the other hand, is a whole dance of decorators and factories inside of factories. I am sure that the increased implementation complexity and layers of abstraction make if feel more different than it actually is (going back to pushback ala insecurities).

So, mechanically speaking, AngularJS $http interceptors and Redux middleware are different. But, really, they're not that different. As such, I don't think that my pushback stems from the mechanical differences.

I think that my pushback somehow comes from the use-cases. But, even that is hard to define. I feel like the AngularJS $http interceptors are used as "hooks" into the AJAX life-cycle. But, you could also say that the Redux middleware provides "hooks" into the state mutation life-cycle. Which it does.

I think my issue is when those "hooks" get too heavily co-opted as a platform for business logic orchestration. Meaning, when they become less of a "convenience" and more of a "critical" part of the application workflow. For example, using the Redux middleware as a means to initiate API request feels like an overreach of middleware responsibilities for a library.

NOTE: I am being explicit on this last point about it being for a "library." If you're using something like Express, whose whole "reason for being" is about coordinating application control flow, the expectation is different.

Unfortunately, I can't seem to articulate it any better than that. I think that, as an idea, Redux middleware is good; and, that my pushback yesterday was perhaps more fueled by fear than I would like to admit. But, I do think that Redux middleware can be used in inappropriate ways. And, for me, that can be generally interpreted as when the middleware is becoming overly critical in the core functionality of an application. I think a good litmus test would be to remove the middleware and see what happens. When you do that, how much stuff in your application breaks? If just a few small things break, you're probably on the right track. But, if the application fundamentally stops working, you're very likely abusing middleware responsibilities (in my opinion).




Reader Comments

Post A Comment

You — Get Out Of My Dreams, Get Into My Comments
Live in the Now
Oops!
Comment Etiquette: Please do not post spam. Please keep the comments on-topic. Please do not post unrelated questions or large chunks of code. And, above all, please be nice to each other - we're trying to have a good conversation here.