0

I have simple API that my React App can use to communicate with my backend. The API has different endpoints and 3 different versions and works like this:

  • We have the public URL, that anonymous users can use (public.api.mysite.com)
  • We have the private URL, that only signed in users can use with their credentials(private.api.mysite.com)
  • Some endpoints on the private API may simply point to the same code which would just ignore the credentials
  • theres also a API URL for testing, which most of the time runs on localhost

I was thinking of creating a REACT component that is used for handling all API communication that might look like this:

<APIConsumer 
   url="posts/7daa4649-14bd-4521-83a3-87609da277d9" method="post" 
   payload={data} 
   handleError={(e)=>setLabel("Error occured because "+e.message)}
   handleLoading={()=>setLabel("Loading please wait")}
   handleSuccess={
          (data)=>{
                 setLabel(null);
                 setPosts((oldPosts)=>[...oldPosts,data])
          }
    }
/>

The advantage with this is I can just change the backend URL in one place if the user logs in or during development. I can also create a user context with user credentials which can be consumed within APIConsumer.

But it also feels like an antipattern, since it handles state changes at the lower component (APIConsumer instead of its parent component).

Theres also the fact that I never saw a pattern like this in the wild. I usually see a large chunk of code handling interaction with the api using fetch or axios at the top level component (including all post, get, patch, etc.. operations).

So is this approach to generalizing api communication a good idea or is it an antipattern?

2
  • Is the private API actually private (as in access is enforced by fire walls)? Or do you mean private in the sense that you don't tell anyone about it? Commented Feb 21, 2021 at 17:08
  • no, theres logged on users and not logged in users. not logged in users use the public api, logged in users use the private. In the private you need valid credentials to access the methods Commented Feb 21, 2021 at 17:11

1 Answer 1

1

This functionality doesn't belong in a component.

Guessing from the props you have presented, nothing will ever be rendered by the component. It only serves as a vessel for the logic inside of it.

Don't tie app logic to the React lifecycle

What happens when you need to call your API in response to a button click? Do you set a "button clicked" state that renders the component, then hide the component once complete? Worse, what if you have to call your API in the middle of some other logic?

Re-renders cause another issue. Depending on how you implement this component, it will repeat the API call every time parent state changes!

Separate logic and presentation code

One simple option is to move the API access code to a class. The constructor would accept and store the user credentials and any other consistent information, such as the "base" url or domain. It can have a function that gets called with the url, method, payload, and callbacks.

You can store an instance of this class in context (like you were doing with your credentials) and pull it out whenever you need to use it. Once the instance is acquired, you can pass it to other functions, objects, or components as a simple object without any dependence on React or its render cycle.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.