💡

【フロントエンドエンジニア必見】Web アプリケーションでの API 呼び出しを一元管理する

2024/09/10に公開

冒頭

今日は、API 呼び出しの処理方法を変更することで、アプリを大幅に改善する方法を皆さんに共有したいと思います。フロントエンド開発に不慣れな方も心配しないでください。すべてを簡単な言葉で説明します。

開発者として、私たちは常に API を扱ってデータを取得したり送信したりしていますが、大規模なアプリケーションでは API管理が混乱しやすくなります。

今回の事象

次のようなシナリオを想像してみてください。大規模な Next.js(TypeScript)アプリがあります。動きはしますが、問題が繰り返し発生します。サーバーからデータを取得する必要があるたびに 、繰り返しコードを記述することになります。
コードは次のような形式になることが多いです:

const getData = async () => {
  try {
    const response = await fetch('https://my-api.com/data', {
      method: 'GET',
      headers: {
        'Content-Type': 'application/json',
      },
    });
    const data = await response.json();
    return data;
  } catch (error) {
    console.error('Oops, something went wrong:', error);
  }
};

このコードはアプリ全体に散らばっている可能性があります。乱雑で追跡が困難です。さらに、何かを変更したい場合 (エラーの処理方法など)、複数の場所で変更する必要が出てくることが多々あります。

解決策: API呼び出しの集中化

この問題の解決策は、「HTTP サービス」を作成することです。これは、API 関連のすべてのコードが集中管理されているファイルを作成することです。実装方法は次のとおりです。
1.httpService.tsという新しいファイルを作成します。このファイルはすべての API 呼び出しを担当します。
2.このファイルで、requestというメイン関数を作成します。この関数は、サーバーと通信して必要なデータを取得してきます。
3.getpostなどのヘルパー関数を追加します

onst API_BASE_URL = 'https://my-api.com';

const defaultHeaders = {
  'Content-Type': 'application/json',
};

const request = async (method, url, payload, customHeaders) => {
  const headers = { ...defaultHeaders, ...customHeaders };
  let body;

  if (payload) {
    body = JSON.stringify(payload);
  }

  try {
    const response = await fetch(`${API_BASE_URL}${url}`, {
      method,
      headers,
      body,
    });

    const data = await response.json();

    if (!response.ok) {
      throw { status: response.status, data };
    }

    return data;
  } catch (error) {
    console.error(`Oops, something went wrong with ${url}:`, error);
    throw error;
  }
};

const get = (url, customHeaders) => request('GET', url, null, customHeaders);
const post = (url, payload, customHeaders) => request('POST', url, payload, customHeaders);
const patch = (url, payload, customHeaders) => request('PATCH', url, payload, customHeaders);
const del = (url, customHeaders) => request('DELETE', url, null, customHeaders);

export { get, post, patch, del };

たくさんあるように見えるかもしれませんが、これを一度書くだけで、アプリ全体で使用することができます

メリット

  1. 繰り返しの削減: 同じ API コードを何度も記述する必要がなくなります

  2. エラーの修正が簡単: すべてが 1 か所にまとめられているため、API 呼び出しで問題が発生した場合、どこを調べればよいか簡単にわかります。

  3. 変更が簡単: API 呼び出しの動作を変更する必要がある場合 (セキュリティ機能の追加など)、1 か所で変更でき、アプリ内のすべての場所で更新されます。

  4. クリーンなコード: コンポーネント (アプリの構成要素) の見た目が格段にすっきりし、APIコードが乱雑に管理されなくなります。

  5. テストが簡単: アプリが正しく動作していることを確認したい場合、API 呼び出しをテストするのが簡単になります。

  6. セキュリティの向上: 認証トークンなどをすべての API 呼び出しに簡単に追加できるようになります。

実際の例: ログイン システム

これがどのように役立つか、実際の例を見てみましょう。アプリのログインシステムを構築しているとします。以前は、次のようなことをしていたかもしれません。

const login = async (username, password) => {
  try {
    const response = await fetch('https://my-api.com/login', {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
      },
      body: JSON.stringify({ username, password }),
    });
    const data = await response.json();
    if (!response.ok) {
      throw new Error('Login failed');
    }
    return data;
  } catch (error) {
    console.error('Login error:', error);
  }
};

httpServiceを使用すると、

import { post } from '../httpService';

const login = async (username, password) => {
  try {
    const data = await post('/login', { username, password });
    return data;
  } catch (error) {
    console.error('Login error:', error);
  }
};

はるかにわかりやすくなりました。ログインの動作を変更する必要がある場合 (新しいセキュリティ チェックの追加など) は、httpServiceで変更することができ、すべての API 呼び出しに自動的に適用されます。

まとめ

API 呼び出しを一元管理すると、コードの品質と保守性が大幅に向上します。これは開発者の作業がはるかに楽になります。また、コードがわかりやすくなり、新しい機能の追加が容易になり、何か問題が発生した場合、その理由を突き止めるのがはるかに簡単になります。

至る所で API 呼び出しが多すぎて困惑している場合は、このアプローチを試してみてください。最初は多少の作業が必要になるかもしれませんが、長期的には価値があります。

良いコードとは、単に物事を機能させることだけではありません。物事をうまく機能させ、開発者としての生活を楽にすることです。

一旦、鳥の目でコード全体を眺めてみることも必要なことだと思います。

最後に

ファイル名はhttpController.tsでも命名は良かったかも。
いいね、フォローお願いいたします。

Discussion