arunkumar413 / task-force

A task manger app
MIT License
3 stars 6 forks source link

Redux state structure for storing the API data #2

Open arunkumar413 opened 1 month ago

arunkumar413 commented 1 month ago

As there will be numerous API calls that will be made to backend we need to have a proper structure to store the API data in redux state. The structure should include: 1) API name 2) Unique naming convention to easily identify the API, 3) Http status code of the fetch operation 4) Whether the fetch operation is loading 5) default data 6) Error handling

ksmcod commented 1 month ago

Will it be ok to use RTK Query for this purpose ? This will ensure that all the api logic is stored in one place, and the api hooks can simply be called as and wherever needed

arunkumar413 commented 1 month ago

@ksmcod Ideally we want to follow "do not repeat yourself" philosophy and just use a library for this scenario. But as this is the initial version I wouldn't want to depend on another library. May be we can see in later versions if required. Also we'll reuse the same logic pattern across all the APIs. So if we can come up with a proper structure for one API that's enough for our requirement to apply to all APIs.

On a side note as the project is opensource I wouldn't want it to be locked to depend on too many external libraries.

arunkumar413 commented 1 month ago

common status/response handler for all APIs

import store from './store'; // assuming you have a configured store
import { apiSuccess, apiError } from './actions';

const handleResponse = async (response, apiName) => {
  if (!response.ok) {
    const { status } = response;
    let errorMessage = 'An error occurred';

    switch (status) {
      case 400:
        errorMessage = 'Bad Request';
        break;
      // more status codes 
      default:
        break;
    }

    store.dispatch(apiError(errorMessage, apiName));
    throw new Error(errorMessage);
  }

  const data = await response.json();
  store.dispatch(apiSuccess(data, apiName));
  return data;
};

const fetchWithHandler = async (url, options, apiName) => {
  const response = await fetch(url, options);
  return handleResponse(response, apiName);
};

export default fetchWithHandler;
arunkumar413 commented 1 month ago

// redux reducer structure

import { createSlice } from "@reduxjs/toolkit";

const initialState = {
  getProducts: {
    err: "",
    data: [],
  },
  getUsers: {
    err: "",
    data: [],
  },
};

export const apiSlice = createSlice({
  name: "API_ACTION",
  initialState,
  reducers: {
    setAPIdata: (state, action) => {
      state[action.payload.apiName].data = action.payload.data;
    },

    setAPIerror: (state, action) => {
      state[action.payload.apiName].err = action.payload.err;
    },
  },
});

// Action creators are generated for each case reducer function
export const { setAPIdata, setAPIerror } = apiSlice.actions;

export default apiSlice.reducer;
MrCyberlord commented 4 weeks ago

Hi I would like to work on it. Also will appreciate it if you mark this issue with hactoberfest label.

arunkumar413 commented 4 weeks ago

@MrCyberlord Let us know if you have a better structure than what I have suggested above

MrCyberlord commented 4 weeks ago

image

@arunkumar413 I am getting this error while starting the backend! Any solution in mind ?

arunkumar413 commented 4 weeks ago

Please log this as a separate issue