TypeScriptでAxiosインスタンスを共通設定!初心者向け型定義とAPI通信の基本ガイド
生徒
「ホームページとデータをやり取りする仕組みを作りたいのですが、毎回同じ設定を書くのが大変です。TypeScriptとアクシオスというものを使うと便利になると聞いたのですが、パソコン初心者でもできますか?」
先生
「大丈夫ですよ!アクシオスという道具を使うと、データのやり取りがとても簡単になります。さらに、共通の設定を一つにまとめる仕組みを作れば、何回も同じことを書かなくて済むようになります。」
生徒
「共通の設定をまとめるのは便利そうですね!型定義というものも一緒に使うと、エラーが起きにくくなると聞きました。具体的なやり方を知りたいです!」
先生
「それでは、基本的な使い方から共通の設定方法まで、順番に詳しく見ていきましょう!」
1. ネットのデータ通信とアクシオスの基本
私たちが普段、スマートフォンやパソコンでインターネットのページを見るとき、画面の裏側ではデータのやり取りが行われています。これをAPI通信(エーピーアイつうしん)と呼びます。API通信とは、自分のパソコンから別の場所にある大きなコンピューター(サーバー)に対して、「このデータをください」とお願いしたり、「この情報を保存してください」と頼んだりする仕組みのことです。
このデータ通信をプログラムで行うときに、とても便利で世界中でよく使われている道具がAxios(アクシオス)です。アクシオスを使うと、複雑なインターネットの通信を、短い命令で簡単に行うことができるようになります。初めてパソコンに触る方でも、お作法さえ覚えればすぐに使いこなすことができます。
データを引っ張ってくることを「取得(しゅとく)」と呼び、データを送ることを「送信(そうしん)」と呼びます。アクシオスは、この取得と送信の両方を強力にサポートしてくれる、魔法の道具のようなものです。
2. インスタンスという共通化の仕組み
プログラムを書くとき、同じことを何度も書くのは面倒ですし、間違いの元になります。例えば、毎回「通信先の住所(URL)」や「通信のタイムアウト時間(何秒待っても返事が来なかったら諦めるかという設定)」を書き込むのは大変です。そこで登場するのがインスタンスという考え方です。
インスタンスとは、専門用語で「実体(じったい)」という意味ですが、分かりやすく例えるなら「専用の通信設定を詰め込んだ特製のスタンプ」のようなものです。あらかじめ通信先の住所やルールを設定した特製スタンプを作っておけば、次からはそのスタンプをポンと押すだけで、いつでも同じ設定で通信ができるようになります。
このスタンプを作る作業のことを「インスタンス化(か)」と呼び、作られた設定済みの塊を「Axiosインスタンス」と呼びます。これを作ることで、プログラムの記述がすっきりと綺麗になり、管理がとても楽になります。
3. 実際にインスタンスを作ってみよう
それでは、実際にアクシオスの特製スタンプ(インスタンス)を作るプログラムを見てみましょう。ここでは、インターネット上のテスト用お天気データ置き場と通信するための、基本的な共通設定を作ります。ベースとなるURLを設定することで、その後の通信の記述を省略できるようになります。
import axios from 'axios';
// 共通の設定を持った特製の通信スタンプ(インスタンス)を作ります
const myAxiosInstance = axios.create({
baseURL: 'https://api.example.com/v1',
timeout: 5000,
headers: {
'Content-Type': 'application/json'
}
});
上記のプログラムについて解説します。axios.createという命令を使って、新しい設定の塊を作っています。baseURL(ベースユーアールエル)には、通信したい大元の住所を書いておきます。これによって、後から具体的な通信をするときに、後半の短い住所だけを書けば良くなります。
timeout(タイムアウト)は、通信の制限時間です。ここでは「5000ミリ秒(5秒)」を指定しています。もしインターネットの調子が悪くて5秒間返事が返ってこなかったら、自動的に通信を中断してエラーにしてくれる安全装置です。headers(ヘッダー)は、通信のお手紙につける「付箋」のようなもので、ここでは「データはジェイソンという形式の綺麗なテキストで送りますよ」という宣言をしています。
4. 型定義を使ってデータの形を固定する
タイプスクリプトを使う最大のメリットは、型(かた)を決めることができる点です。型とは、データが入る「箱の形」や「ラベル」のようなものです。例えば、数字しか入れてはいけない箱に間違って文字を入れてしまうと、パソコンは混乱してフリーズしてしまいます。タイプスクリプトは、そのような間違いをプログラムを実行する前に見つけて注意してくれます。
インターネットの通信では、どのようなデータが返ってくるか事前には分かりません。名前という文字が返ってくるのか、年齢という数字が返ってくるのかをプログラムに教えてあげる必要があります。このデータの設計図を作ることを型定義(かたていぎ)と呼びます。型定義をしっかり行うことで、中身が分からない不安なデータを、安心して使える安全なデータに変えることができます。
今回は、ユーザーの情報をやり取りすることを想定して、名前と識別番号を持ったデータの設計図を作ってみましょう。これをインターフェースという仕組みを使って表現します。
5. データの設計図を作成するプログラム
では、実際に通信で受け取るデータの形を定義してみましょう。今回は、会員サイトの会員情報をイメージした型定義を作成します。初めての方でも分かりやすいように、名前と年齢、そして会員番号の3つの要素を持ったシンプルな設計図にします。
// 会員情報のデータの形を定義する設計図です
interface UserResponse {
id: number;
userName: string;
age: number;
}
このプログラムの解説をします。interface(インターフェース)という言葉は、データの設計図を宣言するためのキーワードです。その横にあるUserResponse(ユーザーレスポンス)は、この設計図に付けた自由な名前です。通信の返事という意味を込めてレスポンスという名前を付けています。
中身を見てみると、id: numberは「識別番号は数字ですよ」という意味です。userName: stringは「ユーザー名は文字列(テキスト)ですよ」という意味になり、age: numberは「年齢は数字ですよ」という意味になります。このように、事前にデータの種類を指定しておくことで、後から間違った使い方をしたときに、パソコンがすぐに警告を出してくれるようになります。
6. 共通インスタンスと型定義を組み合わせる
ここまでで、共通の設定を作ることと、データの設計図を作ることができました。次はいよいよ、この2つを合体させて、実際にデータを取得するプログラムを書いてみましょう。アクシオスには、ジェネリクスという仕組みがあり、通信を行う瞬間に「この設計図の形でデータを読み込んでください」と指定することができます。
// 先ほど作った特製スタンプと設計図を使ってデータを取得します
async function getUserData() {
const response = await myAxiosInstance.get<UserResponse>('/users/1');
console.log(response.data.userName);
}
このプログラムには、少し難しい言葉がいくつか並んでいます。まずasync(エイシンク)とawait(アウェイト)です。これは、インターネットの通信待ちをしている間に、パソコンがフリーズしないようにするための仕組みです。通信には時間がかかるため、「データが届くまでここで少し待っていてね」という指示を出すのがアウェイトの役割です。
そして、get<UserResponse>の部分が最も重要なポイントです。括弧の中に先ほど作った設計図の名前を入れることで、「今から取得するデータは、この設計図通りの形をしています」と指定しています。これにより、response.data.userNameと書いたときに、パソコンが「あ、ここには文字列の名前が入っているな」と正しく理解できるようになります。
7. エラーが起きたときの安全な対処法
インターネットの通信は、常に成功するとは限りません。パソコンのケーブルが抜けてしまったり、相手のサーバーが壊れていたりすると、通信は失敗してしまいます。プログラムが通信に失敗したときのことをエラーと呼びます。エラーが起きたとき、何も対策をしていないと、画面が真っ白になったりアプリが突然終了したりしてしまいます。
そのため、通信を行うときは必ず「もし失敗したらこうする」という予備のルートを用意しておく必要があります。これをエラーハンドリングと呼びます。アクシオスでは、トライとキャッチという構文を使って、安全にエラーを捕まえることができます。
// 通信が失敗しても途中で止まらないようにする安全なプログラム
async function safeGetUserData() {
try {
const response = await myAxiosInstance.get<UserResponse>('/users/1');
console.log("成功しました", response.data.userName);
} catch (error) {
console.log("通信に失敗しました。電波の状況を確認してください。");
}
}
このプログラムでは、try(トライ)のブロックの中に、本来やりたかった成功させたい通信の処理を書きます。もし、その処理の途中でインターネットが切れるなどのハプニングが起きると、プログラムは即座に中断され、下のcatch(キャッチ)のブロックへとジャンプします。キャッチの中には、画面に「失敗しました」という優しいメッセージを出す処理などを書いておくことで、アプリが異常終了するのを防ぐことができます。
8. 実践的な通信の出力結果を確認しよう
最後に、これまで書いたプログラムが実際に動いたとき、パソコンの画面(コンソール画面と呼ばれるデバッグ用の出力場所)にどのように表示されるかを確認してみましょう。成功した場合と失敗した場合の表示のされ方を知っておくことで、実際にプログラムを作るときのイメージが湧きやすくなります。
まずは、インターネット通信が正常に完了し、無事に会員情報が取得できた場合の画面の表示結果です。
成功しました 太郎
このように、設計図通りにデータが解析され、名前の部分だけが綺麗に画面に表示されます。次に、もしも通信相手の住所が間違っていたり、インターネットが繋がっていなかったりした場合の表示結果です。
通信に失敗しました。電波の状況を確認してください。
エラーが発生しても、プログラムが途中で壊れることなく、キャッチで用意した親切なメッセージが出力されていることが分かります。これで、安全で効率的なデータ通信の仕組みが完成しました。共通設定と型定義を意識して、これからの開発に活かしていきましょう。