Using Redux Toolkit Query to Create an Authentication API with ``injectEndpoints``
Published: 2024-07-05 01:41:25

When working with modern web applications, managing API calls efficiently is crucial. Redux Toolkit Query (RTK Query) simplifies this process by providing powerful tools to define and interact with your APIs. In this blog post, we will explore how to use RTK Query to create an authentication API, focusing on the **`injectEndpoints`** method. Additionally, we'll cover how to handle cookies for session management and provide a crucial tip about enabling CORS.

## Setting Up Your Base API

First, let's set up your base API using RTK Query. This base API is where you will inject your endpoints.

```javascript
import { createApi, fetchBaseQuery } from "@reduxjs/toolkit/query/react";

export const baseApi = createApi({
  reducerPath: "baseApi",
  baseQuery: fetchBaseQuery({
    baseUrl: "http://localhost:5000/api/v1",
    credentials: "include", // Ensure cookies are included in requests
  }),
  endpoints: () => ({}),
});
```

## Injecting Endpoints

To manage authentication, we will inject an endpoint for the login function. This is done using the **`injectEndpoints`** method provided by RTK Query.

```javascript
import { baseApi } from "../../api/baseApi";

const authApi = baseApi.injectEndpoints({
  endpoints: (builder) => ({
    login: builder.mutation({
      query: (userInfo) => ({
        url: "/auth/login",
        method: "POST",
        body: userInfo,
      }),
    }),
  }),
});

export const { useLoginMutation } = authApi;
```

In this example:
- We call **`injectEndpoints`** on our `baseApi`.
- Inside **`injectEndpoints`**, we define our endpoints using a function that receives a `builder` object.
- We use `builder.mutation` to define a `login` mutation. This mutation sends a `POST` request to the `/auth/login` endpoint with the user information as the body.

## Using the Login Mutation in Your Component

With the endpoint defined, you can now use the `useLoginMutation` hook in your React components to perform login actions.

```javascript
import React, { useState } from 'react';
import { useLoginMutation } from './path-to-your-api-file';

const Login = () => {
  const [login, { isLoading, isError, isSuccess, data }] = useLoginMutation();
  const [userInfo, setUserInfo] = useState({ username: '', password: '' });

  const handleLogin = async () => {
    try {
      await login(userInfo).unwrap();
      // handle successful login
    } catch (error) {
      // handle login error
    }
  };

  return (
    <div>
      <input
        type="text"
        placeholder="Username"
        value={userInfo.username}
        onChange={(e) => setUserInfo({ ...userInfo, username: e.target.value })}
      />
      <input
        type="password"
        placeholder="Password"
        value={userInfo.password}
        onChange={(e) => setUserInfo({ ...userInfo, password: e.target.value })}
      />
      <button onClick={handleLogin} disabled={isLoading}>
        {isLoading ? 'Logging in...' : 'Login'}
      </button>
      {isError && <p>Error logging in</p>}
      {isSuccess && <p>Login successful</p>}
    </div>
  );
};

export default Login;
```

In this component:
- We use the `useLoginMutation` hook to get the `login` function and its state.
- We manage user input using `useState`.
- When the login button is clicked, we call the `login` function with the user information.

## Important Tip: Enable CORS on the Backend

One common mistake beginners make is forgetting to enable Cross-Origin Resource Sharing (CORS) on the backend. CORS is essential when your frontend and backend are hosted on different domains or ports. Without it, your frontend will not be able to communicate with your backend, leading to errors.

### Example of Enabling CORS in Node.js with Express

To enable CORS in an Express application, you can use the `cors` middleware:

```javascript
const express = require('express');
const cors = require('cors');
const app = express();

app.use(cors({
  origin: 'http://localhost:3000', // Adjust this to your frontend's URL
  credentials: true, // This allows cookies to be included in requests
}));
```

Make sure to adjust the `origin` to match your frontend's URL and set `credentials` to `true` to allow cookies.

## Conclusion

RTK Query makes it straightforward to manage API calls in your Redux application. By using **`injectEndpoints`**, you can easily define and use endpoints for various API operations, including authentication. Handling cookies during the login process ensures secure and persistent sessions, enhancing user experience. Remember to enable CORS on your backend to avoid common issues with cross-origin requests.

---

This blog post provides a quick overview of setting up an authentication API using RTK Query, handling cookies for session management, and the importance of enabling CORS. For more advanced use cases and configurations, refer to the [Redux Toolkit Query documentation](https://redux-toolkit.js.org/rtk-query/overview).