Skip to content

Instantly share code, notes, and snippets.

@LeeDDHH
Last active December 31, 2023 03:18
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save LeeDDHH/9594e7ebd29a8c1888f1164934e766f4 to your computer and use it in GitHub Desktop.
Save LeeDDHH/9594e7ebd29a8c1888f1164934e766f4 to your computer and use it in GitHub Desktop.
typescriptでaxiosを使う際のサンプルコード
  • laravelとapi通信することを前提にしている
  • axios のインスタンス生成とリクエスト前処理、レスポンス後処理を1つのモジュールにまとめる
  • axios のインスタンスを使ってGET・POST・PUT・DELETEのエンドポイントを1つのモジュールにまとめる
import type { AxiosResponse, InternalAxiosRequestConfig } from 'axios';
import axios from 'axios';
// @see https://github.com/domchristie/humps
import { camelizeKeys, decamelizeKeys } from 'humps';
// import { camelizeKeys, decamelizeKeys } from '@/utils/namingConventionsConverter';
const requestInterceptor = (config: InternalAxiosRequestConfig) => {
return {
...config,
params: decamelizeKeys(config.params),
data: config.data instanceof FormData ? config.data : decamelizeKeys(config.data),
};
};
const responseSuccessInterceptor = (response: AxiosResponse) => {
response.data = camelizeKeys(response.data);
return Promise.resolve(response);
};
const responseFailedInterceptor = (error: unknown) => {
return Promise.reject(error);
};
export const axiosInstance = axios.create({
baseURL: 'http://localhost:8080',
withCredentials: true,
headers: {
'X-Requested-With': 'XMLHttpRequest',
},
});
axiosInstance.interceptors.request.use(requestInterceptor);
axiosInstance.interceptors.response.use(responseSuccessInterceptor, responseFailedInterceptor);
import type { Axios, AxiosInstance, AxiosResponse } from 'axios';
import type { GetServerSidePropsContext, NextPageContext } from 'next';
import { axiosInstance } from '@/lib/axios';
import { mergeCookie } from './cookie/mergeCookie';
export interface ApiClientInterface {
get: Axios['get'];
post: Axios['post'];
put: Axios['put'];
del: Axios['delete'];
}
export class ApiClient implements ApiClientInterface {
private client: AxiosInstance;
constructor(
instance: AxiosInstance,
private ctx?: GetServerSidePropsContext | NextPageContext,
) {
this.client = instance;
}
setCookies(axiosResponse: AxiosResponse) {
if (!this.ctx) return;
const mergedCookie = mergeCookie(this.ctx.res?.getHeader('set-cookie'), axiosResponse.headers['set-cookie']);
this.ctx.res?.setHeader('set-cookie', mergedCookie);
}
async get<Response>(url: Parameters<Axios['get']>[0], config?: Parameters<Axios['get']>[1]): Promise<Response> {
return this.client
.get<Response>(url, { headers: this.ctx?.req?.headers ?? {}, ...config })
.then((res) => {
this.setCookies(res);
return res.data;
})
.catch((err) => {
throw err;
});
}
async post<Response>(
url: Parameters<Axios['post']>[0],
data: Parameters<Axios['post']>[1],
config?: Parameters<Axios['post']>[2],
): Promise<Response> {
return this.client
.post<Response>(url, data, { headers: this.ctx?.req?.headers ?? {}, ...config })
.then((res) => {
this.setCookies(res);
return res.data;
})
.catch((err) => {
throw err;
});
}
async put<Response>(
url: Parameters<Axios['put']>[0],
data: Parameters<Axios['put']>[1],
config?: Parameters<Axios['put']>[2],
): Promise<Response> {
return this.client
.put<Response>(url, data, { headers: this.ctx?.req?.headers ?? {}, ...config })
.then((res) => {
this.setCookies(res);
return res.data;
})
.catch((err) => {
throw err;
});
}
async del<Response>(url: Parameters<Axios['delete']>[0], config?: Parameters<Axios['delete']>[1]): Promise<Response> {
return this.client
.delete<Response>(url, { headers: this.ctx?.req?.headers ?? {}, ...config })
.then((res) => {
this.setCookies(res);
return res.data;
})
.catch((err) => {
throw err;
});
}
}
const apiClient = new ApiClient(axiosInstance);
export default apiClient;
import type { Axios, AxiosResponse } from 'axios';
import type { GetServerSidePropsContext, NextPageContext } from 'next';
import { axiosInstance } from '@/lib/axios';
import { mergeCookie } from './cookie/mergeCookie';
type NextContext = GetServerSidePropsContext | NextPageContext;
const setCookies = (ctx: GetServerSidePropsContext | NextPageContext | undefined, axiosResponse: AxiosResponse) => {
if (!ctx) return;
const mergedCookie = mergeCookie(ctx.res?.getHeader('set-cookie'), axiosResponse.headers['set-cookie']);
ctx.res?.setHeader('set-cookie', mergedCookie);
};
export const apiClient = {
get: async <Response>(
url: Parameters<Axios['get']>[0],
config?: Parameters<Axios['get']>[1] | Record<string, never>,
ctx?: NextContext,
) => {
const response = await axiosInstance.get<Response>(url, { headers: ctx?.req?.headers ?? {}, ...config });
setCookies(ctx, response);
return response.data;
},
post: async <Response>(
url: Parameters<Axios['post']>[0],
data: Parameters<Axios['post']>[1],
config?: Parameters<Axios['post']>[2] | Record<string, never>,
ctx?: NextContext,
) => {
const response = await axiosInstance.post<Response>(url, data, { headers: ctx?.req?.headers ?? {}, ...config });
setCookies(ctx, response);
return response.data;
},
put: async <Response>(
url: Parameters<Axios['put']>[0],
data: Parameters<Axios['put']>[1],
config?: Parameters<Axios['put']>[2] | Record<string, never>,
ctx?: NextContext,
) => {
const response = await axiosInstance.put<Response>(url, data, { headers: ctx?.req?.headers ?? {}, ...config });
setCookies(ctx, response);
return response.data;
},
del: async <Response>(
url: Parameters<Axios['delete']>[0],
config?: Parameters<Axios['delete']>[1] | Record<string, never>,
ctx?: NextContext,
) => {
const response = await axiosInstance.delete<Response>(url, { headers: ctx?.req?.headers ?? {}, ...config });
setCookies(ctx, response);
return response.data;
},
};
export default apiClient;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment