Angular PR

【Angular】provideHttpClientで実現する安全で効率的なHTTP通信

【Angular】provideHttpClientで実現する安全で効率的なHTTP通信
記事内に商品プロモーションを含む場合があります

こんにちは!

Angular 15で導入されたprovideHttpClient

provideHttpClientってどう使うの?
オプションの設定方法がわからない…
デフォルトの設定って何があるんだろう?

もしかすると、そんな疑問を抱えているかもしれません。

この記事では、AngularでのHTTP通信に欠かせないprovideHttpClientについて、基本的な使い方からオプション設定、具体的な実装方法までを詳しく解説していきます。

この記事は、以下のような方におすすめです。

この記事はこんな人におすすめ!
  • Angularでバックエンドと通信する機能を実装したい方
  • provideHttpClientの設定方法を知りたい方
  • HTTP通信のオプション設定について詳しく知りたい方
  • より安全で効率的なHTTP通信を実現したい方

この記事を読めば、provideHttpClientの基本から応用まで理解できるだけでなく、具体的なプロジェクトですぐに活用できるようになります。

provideHttpClientとは?

まずは、provideHttpClientの基本的な概念と重要性について見ていきましょう。

provideHttpClientの役割

provideHttpClientは、AngularアプリケーションでHTTP通信を行うための準備を整えるプロバイダーです。このプロバイダーを使用することで、以下のような機能が利用可能になります。

  • RESTful APIとの通信
  • ファイルのアップロード・ダウンロード
  • HTTPリクエストの加工とレスポンスの処理
  • エラーハンドリング
  • リクエストの進捗監視

従来の方法との違い

Angular 14以前とAngular 15以降では、HTTP通信の設定方法が大きく変わりました。

設定項目 従来の方法
(HttpClientModule)
新しい方法
(provideHttpClient)
設定場所 NgModuleのimports アプリケーション設定
カスタマイズ性 モジュールレベルでの設定が必要 関数型で柔軟な設定が可能
パフォーマンス 余分なバンドルサイズ 必要な機能のみをバンドル
テスト容易性 モジュール全体の準備が必要 個別の機能をテスト可能

provideHttpClientの基本的な使い方

provideHttpClientの基本的な使い方を見ていきましょう。

セットアップ手順

最新のAngularアプリケーションでprovideHttpClientを使用するには、まずapp.config.tsファイルで設定を行います。

import { ApplicationConfig } from '@angular/core';
import { provideHttpClient } from '@angular/common/http';

export const appConfig: ApplicationConfig = {
  providers: [
    provideHttpClient()
  ]
};

この設定により、アプリケーション全体でHTTP通信機能が使用可能になります。

デフォルトの設定

provideHttpClientには、以下のようなデフォルト設定が含まれています。

設定項目 デフォルト値 説明
withCredentials false クロスオリジンリクエストでのクッキー送信
responseType ‘json’ レスポンスの形式
reportProgress false アップロード進捗の報告
observe ‘body’ 監視対象(body/response/events)

これらの設定は、必要に応じて変更することができます。

provideHttpClientでよく使用されるオプション設定

provideHttpClientには、様々な便利なオプションが用意されています。それぞれのオプションについて、詳しく見ていきましょう。

withInterceptors(HTTP通信の加工と監視)

withInterceptorsは、HTTPリクエストやレスポンスを加工・監視するための強力な機能です。例えば、以下のようなケースで活用できます。

  • すべてのリクエストに認証トークンを自動で付与
  • エラーが発生した際の共通エラーハンドリング
  • リクエストとレスポンスのログ記録
  • レスポンスデータの共通的な加工処理

具体的な実装例を見てみましょう。

import { HttpResponse, provideHttpClient, withInterceptors } from '@angular/common/http';
import { HttpInterceptorFn } from '@angular/common/http';
import { ApplicationConfig } from '@angular/core';
import { tap } from 'rxjs';


// 認証トークンを追加するインターセプター
const authInterceptor: HttpInterceptorFn = (req, next) => {
  // ローカルストレージから認証トークンを取得
  const token = localStorage.getItem('auth_token');

  // トークンが存在する場合、リクエストヘッダーに追加
  if (token) {
    const authReq = req.clone({
      headers: req.headers.set('Authorization', `Bearer ${token}`)
    });
    return next(authReq);
  }
  return next(req);
};

// ログを記録するインターセプター
const loggingInterceptor: HttpInterceptorFn = (req, next) => {
  console.log(`🌐 送信リクエスト: ${req.method} ${req.url}`);

  return next(req).pipe(
    tap(response => {
      if (response instanceof HttpResponse) {
        console.log(`✅ 受信レスポンス: ${response.status} ${req.url}`);
      }
    })
  );
};

// アプリケーション設定
export const appConfig: ApplicationConfig = {
  providers: [
    provideHttpClient(
      withInterceptors([authInterceptor, loggingInterceptor])
    )
  ]
};

このように設定することで、以下のような利点が得られます。

認証の自動化
すべてのリクエストに認証トークンが自動的に付与されるため、個別の設定が不要になります。
デバッグの効率化
通信ログが自動的に記録されるため、問題の特定が容易になります。
コードの再利用性
共通的な処理をインターセプターにまとめることで、コードの重複を防げます。
保守性の向上
認証やログ記録などの横断的な処理を一箇所で管理できます。

withRequestsMadeViaParent(階層的な HTTP クライアントの管理)

withRequestsMadeViaParentは、親子関係のあるコンポーネント間でHTTPクライアントの設定を共有するための機能です。この機能は以下のような場合に特に有用です。

  • マイクロフロントエンド構成でのHTTP通信管理
  • 異なるモジュール間での設定の共有
  • 特定のコンポーネントツリーでの通信設定の一元管理

具体的な使用例を見てみましょう。

// ルートレベルの設定(app.config.ts)
export const appConfig: ApplicationConfig = {
  providers: [
    provideHttpClient(
      withRequestsMadeViaParent(),
      withInterceptors([baseUrlInterceptor])
    )
  ]
};

// 子モジュールの設定(feature.config.ts)
export const featureConfig: ApplicationConfig = {
  providers: [
    provideHttpClient(
      withRequestsMadeViaParent(),
      withInterceptors([featureSpecificInterceptor])
    )
  ]
};

この設定により、以下のような利点が得られます。

設定の継承
子コンポーネントは親の設定を自動的に継承できます。
モジュール固有の設定
必要に応じて、モジュール固有の設定を追加できます。
設定の一元管理
共通設定を親コンポーネントで一元管理できます。
柔軟なカスタマイズ
モジュールごとに異なる設定を適用できます。

具体的なユースケースとして、以下のような例が考えられます。

// 共通のベースURL設定(親レベル)
const baseUrlInterceptor: HttpInterceptorFn = (req, next) => {
  const apiUrl = 'https://api.example.com';
  const apiReq = req.clone({
    url: `${apiUrl}${req.url}`
  });
  return next(apiReq);
};

// 特定機能用の設定(子レベル)
const featureSpecificInterceptor: HttpInterceptorFn = (req, next) => {
  // 特定の機能に関連するヘッダーを追加
  const customReq = req.clone({
    headers: req.headers.set('X-Feature-Version', '1.0')
  });
  return next(customReq);
};

このように、階層的な設定により、効率的で管理しやすいHTTP通信の実装が可能になります。

withXsrfConfiguration(クロスサイトリクエストフォージェリ対策)

withXsrfConfigurationは、Webアプリケーションのセキュリティを高めるための重要な機能です。CSRF(Cross-Site Request Forgery)攻撃から保護するために使用されます。

CSRFとは

CSRF攻撃は、ユーザーが認証済みの状態を悪用して、不正なリクエストを送信する攻撃です。例えば、以下のような被害が想定されます。

  • ユーザーの意図しない商品の購入
  • パスワードやメールアドレスの変更
  • 個人情報の流出

具体的な使用方法を見ていきましょう。

import { provideHttpClient, withXsrfConfiguration } from '@angular/common/http';

export const appConfig: ApplicationConfig = {
  providers: [
    provideHttpClient(
      withXsrfConfiguration({
        cookieName: 'XSRF-TOKEN',
        headerName: 'X-XSRF-TOKEN'
      })
    )
  ]
};

設定できる主なオプションは以下の通りです。

オプション 説明 一般的な設定値
cookieName XSRFトークンを保存するクッキーの名前 ‘XSRF-TOKEN’
headerName リクエスト時に使用するヘッダーの名前 ‘X-XSRF-TOKEN’

動作の仕組み

1. トークンの生成と保存

// バックエンド側でトークンを生成しクッキーに保存
app.get('/api', (req, res) => {
  res.cookie('XSRF-TOKEN', generateToken());
  res.send('OK');
});

2. トークンの自動送信

// Angularが自動的にヘッダーにトークンを追加
this.http.post('/api/data', payload).subscribe(
  response => console.log('✅ 安全な通信が完了しました')
);

3. サーバー側での検証

// バックエンド側でトークンを検証
app.post('/api/data', validateXsrfToken, (req, res) => {
  // トークンが有効な場合のみ処理を実行
});

セキュリティのベストプラクティス

1. 適切なトークン管理

  • トークンは十分な長さと複雑さを持たせる
  • 定期的にトークンを更新する
  • セキュアなクッキー設定を使用する

2. エラーハンドリング

const xsrfErrorInterceptor: HttpInterceptorFn = (req, next) => {
  return next(req).pipe(
    catchError(error => {
      if (error.status === 403) {
        console.error('🚫 XSRFトークンが無効です');
        // トークンの再取得などの対応
      }
      return throwError(() => error);
    })
  );
};

withJsonpSupport(クロスオリジン通信のサポート)

withJsonpSupportは、異なるドメイン間でのデータ取得を可能にする機能です。特に、CORSが利用できない場合の代替手段として活用できます。

JSONPとは

JSONP(JSON with Padding)は、同一オリジンポリシーを回避してデータを取得する手法です。以下のような特徴があります。

  • scriptタグを使用してデータを取得
  • コールバック関数でデータを受け取る
  • GETリクエストのみ対応

基本的な設定

import { provideHttpClient, withJsonpSupport } from '@angular/common/http';

export const appConfig: ApplicationConfig = {
  providers: [
    provideHttpClient(
      withJsonpSupport()
    )
  ]
};

具体的な使用方法

JSONPを使用したデータ取得の例を見てみましょう。

import { HttpClient } from '@angular/common/http';
import { Injectable } from '@angular/core';

@Injectable({
  providedIn: 'root'
})
export class WeatherService {
  constructor(private http: HttpClient) {}

  getWeatherData() {
    // JSONPリクエストの送信
    return this.http.jsonp(
      'https://api.weather.example.com/forecast',
      'callback'
    );
  }
}

エラーハンドリングと注意点

JSONPを使用する際は、以下の点に注意が必要です。

1. タイムアウト処理

getWeatherData() {
  return this.http.jsonp(
    'https://api.weather.example.com/forecast',
    'callback'
  ).pipe(
    timeout(5000),
    catchError(error => {
      if (error instanceof TimeoutError) {
        console.error('⏰ リクエストがタイムアウトしました');
      }
      return throwError(() => error);
    })
  );
}

2. エラー発生時の代替手段

getWeatherData() {
  return this.http.jsonp(
    'https://api.weather.example.com/forecast',
    'callback'
  ).pipe(
    catchError(error => {
      console.warn('⚠️ JSONPリクエストに失敗しました。代替手段を試行します');
      // 代替のAPIエンドポイントを使用
      return this.http.get('https://backup-api.example.com/weather');
    })
  );
}

JSONPのユースケース

JSONPは以下のような場合に特に有用です。

レガシーAPIとの通信
  • CORSに対応していない古いAPI
  • サードパーティの天気予報API
  • 株価データ提供サービス
静的なデータ取得
  • 公開されている統計データ
  • 地理情報データ
  • 外部サービスのメタデータ

provideHttpClientを使った高度な設定

より効果的にprovideHttpClientを活用するための高度な設定を見ていきましょう。

複数オプションの組み合わせ

複数のオプションを組み合わせることで、より柔軟な設定が可能です。

import { provideHttpClient, withInterceptors, withXsrfConfiguration, withJsonpSupport } from '@angular/common/http';

export const appConfig: ApplicationConfig = {
  providers: [
    provideHttpClient(
      withInterceptors([authInterceptor, loggingInterceptor]),
      withXsrfConfiguration({
        cookieName: 'XSRF-TOKEN',
        headerName: 'X-XSRF-TOKEN'
      }),
      withJsonpSupport()
    )
  ]
};

エラーハンドリングの設定

エラーハンドリングは、インターセプターを使用して効果的に実装できます。

import { HttpErrorResponse, HttpInterceptorFn } from '@angular/common/http';
import { catchError, throwError } from 'rxjs';

export const errorHandlingInterceptor: HttpInterceptorFn = (req, next) => {
  return next(req).pipe(
    catchError((error: HttpErrorResponse) => {
      if (error.status === 0) {
        console.error('🔌 ネットワークエラーが発生しました');
      } else if (error.status === 401) {
        console.error('🔒 認証エラーが発生しました');
      } else if (error.status === 404) {
        console.error('❓ リソースが見つかりません');
      } else {
        console.error('⚠️ サーバーエラーが発生しました');
      }
      return throwError(() => error);
    })
  );
};

キャリア形成/給与還元
ひとつひとつ真摯に向き合う企業
ONE_WEDGE社員募集

株式会社 ONE WEDGEでは、新たな仲間を募集しています!

私たちと一緒に、革新的で充実したキャリアを築きませんか?
当社は、従業員が仕事と私生活のバランスを大切にできるよう、充実した福利厚生を整えています。

  • 完全週休2日制(土日休み)で、祝日や夏季休暇、年末年始休暇もしっかり保証!
  • 様々な休暇制度(有給、慶弔、産前・産後、育児、バースデー休暇)を完備!
  • 従業員の成長と健康を支援するための表彰制度、資格取得支援、健康促進手当など!
  • 生活を支えるテレワーク手当、記事寄稿手当、結婚祝金・出産祝金など、様々な手当を提供!
  • 自己啓発としての書籍購入制度や、メンバー間のコミュニケーションを深める交流費補助!
  • 成果に応じた決算賞与や、リファラル採用手当、AI手当など、頑張りをしっかり評価!
  • ワークライフバランスを重視し、副業もOK!

株式会社 ONE WEDGEでは、一人ひとりの従業員が自己実現できる環境を大切にしています。
共に成長し、刺激を与え合える仲間をお待ちしております。
あなたの能力と熱意を、ぜひ当社で発揮してください。
ご応募お待ちしております!

ホームページ、採用情報は下記ボタンからご確認ください!

応募、ご質問など、LINEでお気軽にご相談ください♪

まとめ

ここまで、provideHttpClientについて詳しく解説してきました。改めて、重要なポイントをおさらいしましょう。

  • provideHttpClientは、Angularの最新のHTTP通信設定方法
  • デフォルト設定を理解し、必要に応じてカスタマイズが可能
  • インターセプターを活用することで、柔軟な通信制御が実現可能
  • セキュリティ対策は必須で、XSRFトークンなどの適切な設定が重要
  • 複数のオプションを組み合わせることで、より高度な機能を実現可能

provideHttpClientは、Angularアプリケーションにおける安全で効率的なHTTP通信の基盤となります。この記事で解説した内容を参考に、プロジェクトに最適な設定を行ってください。

COMMENT

メールアドレスが公開されることはありません。 が付いている欄は必須項目です