Way to organize REST API endpoints in a React project
An example on how to place your API files in a project
Way to organize API endpoints in a React project
Hello π, I really like to have everything well-organised, clean and readable in a project. Below I wanted to share with you how we can achieve structure for API client files, that will make your eyes π happy.
TL;DR
Keep your API endpoints files separate from configuration.
src/
...
config/
api/
index.ts <- Configuration
services/
Api/
index.ts <- API Endpoints
// or
Users.ts
Groups.ts
Posts.ts
or
src/
...
services/
Api/
base.ts <- Configuration
index.ts <- API Endpoints
// or
base.ts
Users.ts
Groups.ts
Posts.ts
Intro
Divide your API files into two groups, configuration and endpoint list. Itβs easier to maintain and read them after all. However when you will do that once properly, you will never get back to configuration file.
Config
Base configuration file. If you will create this file covering all cases π, you will not need to get back.
Example configuration files:
Axios:
import axios from "axios";const apiClient = axios.create({
baseURL: API_URL, // <- ENV variable
});apiClient.interceptors.request.use((config) => {
return ({
...config,
headers: {
...
},
})
},
error => Promise.reject(error),
);
apiClient.interceptors.response.use((response) =>
response,
async (error) => {
...
return Promise.reject(error.response.data);
},
);
const { get, post, put, delete: destroy } = apiClient;
export { get, post, put, destroy };
Ky:
import ky from "ky";const apiClient = ky.create({
prefixUrl: API_URL, // <- ENV variable
headers: {
...
}
hooks: {
beforeRequest: (request) => {...}
afterResponse: (response) => {...}
});const { get, post, put, delete: destroy } = apiClient;
export { get, post, put, destroy };
Endpoints
Here you can decide if you want to keep endpoints in one file or create separate files scoped by context of API usage.
Naming:
Itβs good to have a naming convention. This is what I use:
Basic CRUD:
index <- GET all items
single <- GET single item by id
create <- POST an item
update <- PUT data to an item
remove <- DELETE an itemSpecific:
singleByEmail
removeAll
e.g.
import { get, post, put, destroy } from 'config/api';export const Users = {
index: () =>
get('/users'),
single: (id) =>
get(`/users/${id}`),
singleByEmail: (email) =>
get(`/users?email=${email}`),
create: (params) =>
post('/users', params),
update: (id, params) =>
put(`/users/${id}`, params),
remove: (id) =>
destroy(`/users/${id}`),
}
I hope you enjoy π! Check docs for more information about configuration options for above API clients on their github repository: