Managing API requests reducers in the best way

Today as we are using the API middleware, we reduced a large amount of code to do something that was implemented differently in many places…

We can do even better by removing many reducers files which do exactly the same:
maintain the API request cycle of Request, Success, Failure.

There are two approaches I’ve been investigating:

  1. create higher order API reducer which will be consumed in every component’s reducer file.
    Every component will have the ability to choose the name of the reducer, create its own selectors etc…
  2. create API reducer which will save all of the API processes under its namespace, e.g:
  {
    ...reducers,
    API: {
      FACT_CHART: { status, error, results, ...payload },
      POWER_STATUS:  { status, error, results, ...payload },
    }
  }

The second option will save the reducer by a unique key which is already being provided in all of the API requests which are using the API middleware,
without the need to create a reducer by yourself, or a selector.

In both options you could override the default behavior.

Which path in your opinion we should go? I must say that I like the second one as it create things automatically and need less boilerplate, take a look on the draft PRs:

  1. create higher order API reducer - https://github.com/theforeman/foreman/pull/7217
  2. create main API reducer - https://github.com/theforeman/foreman/pull/7222
1 Like

Thanks for bringing it up @Ron_Lavi :+1:

I tend to prefer option 2 since there are less things to do as a consumer.

1 Like

After thinking about it for a while (and deleting my post draft :stuck_out_tongue: ) I think option 2 makes the most sense to me.

At first I was confused why we were adding feature-specific data into a store section named “API.” But then I realized that key is just to keep the status of “is there an inflight request”, “what was the last error,” etc.

Therefore I think the key should be named API_STATUS and not just API.

I’m skeptical that we should store actual results and payload in this API_STATUS section. I think it’s better to put the actual data payload on the actual feature where it belongs (e.g. powerStatus). We could use a new custom Redux middleware to do this.

The API namespace will store not only status, but also results, error, the url so we could implement debounce or throttle functions on top of it.

So basically instead of any feature implement the same behavior, we could make this automatically and provide a selector to the API with the unique key that they provided in the API action.

It will reduce a lot of code and we could also reuse API requests that affects multiple features, instead of creating a request per feature.