Use Axios in Calling Secured APIs in React Apps
Context
Many applications depend on backend data these days, and one of the best ways to fetch that data, process it and show it to your customers is through API calls.
Also, the moment your APIs contain sensitive information, or should be only available to paid customers, you’ll need to secure them against unauthorised access.
In this post, I will cover how to call REST or GraphQL APIs from your app. I will also cover how to provide authentication headers with each request to call secured APIs, and how to retry the requests when those auth tokens expire.
By the way, this topic belongs to the series to set up a Single Page Application using React, Redux and Asp.NET 5.0.
- Styling and Theme Management
- Global Navigation
- Responsive Layout
- Forms and Input Validation
- Routing
- Configuration Management
- API Call and Activity Indicator (Spinner)
- Monitoring, Logging and Instrumentation
- Toast Notification
- Redux and Store Setup
- Google Maps with Polygons
- SEO — Search Engine Optimisation
- Running React App on .NET Stack
- Deploy React App to Azure App Service
Libraries
Axios is a popular library to call backend APIs. It comes with a log of capabilities and flexibility and I am using that in this post to show how to structure your API handling functions.
You should be able to use any other library and replace axios, and still have the rest of your app unaffected if you follow the approach in this post.
End Result
Here is how the end result will look like, and the functions the below snippet performs for you:
- Authorisation: Attaching Authorization headers to all the requests that need the headers
- Headers: Attaching all the common headers your requests need
- Failing Gracefully: When the requests fail
- Retrying: the requests with refreshed auth tokens, when the tokens expire. This also includes updating the token store with the new tokens, so the next requests won’t fail due to the same expired tokens.
- Centralised: All the above logic will be centralised, enabling you to change any of that logic, or replacing the whole library with no side effect to the rest of the application.
Implementation
1. API Object
Before I’d be able to call any API, I need to create an instance of Axios with certain functions attached to it. At a high level, this is what we need for each request in order to achieve the objectives I mentioned above:
Now let’s cover them one by one.
1.1 Instance
I need an raw instance with the baseUrl, which is your FQDN (Fully Qualified Domain Names). That would be the initial part of your URL, such as https://yahoo.com.
const instance = axios.create({ baseURL: base });
1.2 Request Handling
Once the instance was created, I need to attach any necessary information to the request, such as common headers, Auth headers, etc, and that’s where interceptors come into play. They help me to modify the request before the request is sent.
axiosInterceptor = instance.interceptors.request.use(config => { });
1.3 Response Handling
Same concept applies to the response. If the response was in 200, 400, 500 ranges, you would need to treat them differently, and there are some common functions that apply to all the requests, and hence you need to keep them here to avoid repeating yourself.
A typical example is 401, in which I’d need to call an identity endpoint to refresh the auth token, and retry the same request with the refreshed token.
instance.interceptors.response.use((response) => {}, async function (error) {});
1.4 Instance Reset
To ensure none of the settings for one request gets injected to the other requests, we will need to reset the request/response configurations we just set:
if (!!axiosInterceptor || axiosInterceptor === 0) {}
Now that we know what is happening, here is the full code including the implementation of the above steps:
Note
Configuration, plumbing and troubleshooting your software foundation take a considerable amount of time in your product development. Consider using Pellerex which is a complete foundation for your enterprise software products, providing source-included Identity and Payment functions across UI (React), API (.NET), Pipeline (Azure DevOps) and Infrastructure (Kubernetes).
2. Call API
I trust with the above notes, you find the implementation straightforward. Now all you need to do is the replace the config values in the above implementation with your desired values, and to use the below snippet, get a new instance, and call your API.
2.1 REST or GraphQL
Using the mechanism I have here, it really doesn’t matter if you are calling graphQl or REST. All you need to change is the body of your query. In the case of REST, it would be a JSON content, and in the case GraphQL, it would be GraphQL body with a Post request.
Pellerex Foundation: For Your Next Enterprise Software
How are you building your current software today? Build everything from scratch or use a foundation to save on development time, budget and resources? For an enterprise software MVP, which might take 8–12 months with a small team, you might indeed spend 6 months on your foundation. Things like Identity, Payment, Infrastructure, DevOps, etc. they all take time, while contributing not much to your actual product. These features are needed, but they are not your differentiators.
Pellerex does just that. It provides a foundation that save you a lot development time and effort at a fraction of the cost. It gives you source-included Identity, Payment, Infrastructure, and DevOps to build Web, Api and Mobile apps all-integrated and ready-to-go on day 1.
Check out Pellerex and talk to our team today to start building your next enterprise software fast.