はじめに
フロントエンド開発するにおいて、APIを叩くなどfetchを行うことは多々あると思います。
今回は実案件で使ってfetchのパターンをいくつか紹介したいと思います。
実案件ではtypescriptを使っているので、今回はtypescriptベースで型にも気をつけて行きたいと思います。
実用例
普通にfetch
APIの内容は適当なんでこんなのがあるかわからないですが、Userデータをfetchで取得する場合。
interface
を使って最初にどんなデータが来るのかの型を定義しておきます。これはtypescript特有の操作ですね。
// 型定義
interface User {
id: number;
name: string;
email: string;
}
// fetch関数
const fetchData = async (url: string, headers: HeadersInit): Promise<User> => {
const response = await fetch(url);
if (!response.ok) {
throw new Error('response error');
}
const data: User = await response.json();
return data;
};
// URLを入れてfetchする
const url = 'xxxxx.example.com';
const headers = {
'Content-Type': 'application/json',
'Authorization': 'Bearer YOUR_TOKEN_HERE'
};
// 実際に実行する
fetchData(url, headers)
.then(data => {
console.log('Data received:', data);
})
.catch(error => {
console.error('Error fetching data:', error);
});;
複数のfetchが終わった後に関数を実行
続いて、複数のfetchを行った後に処理を実行したい時ってありますよね。
しかし、すべてのfetchの型が同じ場合ではない場合もあります。
そういう時、fetchの関数を型のためだけに増やしたくないですよね。。。
そんな時は Generics(ジェネリックス) を使います。
Generics(ジェネリックス)とは?
Genericsとはtypescriptなど型が明確に決まっている言語に関して、汎用的に型を設定してくれる機能のことです。
「複数のfetchを行うとき」 + 「それぞれのfetchの返り値の型が決まってないもの」
に関して使うにはもってこいですね。
// 型定義
interface User {
id: number;
name: string;
email: string;
}
interface Product {
id: number;
name: string;
discription: string;
price: string;
}
// Generics(ジェネリックス)<T>でfetchを実行(大文字ならアルファベットは特に意味ないらしい)
const fetchData = async <T>(url: string): Promise<T> => {
const response = await fetch(url);
if (!response.ok) {
throw new Error('response error');
}
const data: T = await response.json();
return data;
};
// 返り値格納用のグローバル変数の定義
let user: User;
let product: Product;
// fetch1
const getUser = async (url: string): Promise<void> => {
user = await fetchData<User>(url);
};
// fetch2
const getProduct = async (url: string): Promise<void> => {
product = await fetchData<Product>(url);
};
// fetchすべてのfetchを実行
const getAllEvents = async () => {
try {
await Promise.all([getUser('xxxxx.example.com'), getProduct('xxxxx.example2.com')]);
console.log('処理の開始');
// 両方正常に実行された時に処理される。
} catch (error) {
console.error('Error fetching data:', error);
}
};
このようにそれぞれのfetchごとに型を定義しておくので、fetchする関数は一つですみますね。
ちなみにこの下のPromise.allは配列に入ったものを並列で処理してくれるので、一度に複数のAPIを叩くと言った場合(特に速度などを気にしない場合)はいいかもしれないですね。
Promise.all([getHoliday('xxxxx.example.com'), getEvent('xxxxx.example2.com')]);
fetchDataを呼び出す関数の後に処理を書けばそれぞれの完了のタイミングで処理を実行できます。
終わりに
今回は実案件でfetchをよく使うことがあったので、簡単によく使うパターンを紹介してみました。
Generics(ジェネリックス)はtypescriptを使う民にとっては重宝されるものだと思うのでぜひ使ってみてください。
Promise.allも並列処理してくれる点では覚えておくといいかもしれません。