HttpClientModuleが非推奨になった理由と代替手段
問題の核心
Angular 18から従来のHttpClientModule
が非推奨になりました。モジュールベースのプロジェクトで次のように使用すると警告が発生します:
typescript
@NgModule({
imports: [
BrowserModule,
HttpClientModule, // 非推奨
...
],
})
export class AppModule {}
非推奨の主な理由は:
- モジュール方式が冗長:
HttpClientModule
は内部でprovideHttpClient()
関数を実行しているだけ - スタンドアロンAPIとの統一:関数型プロバイダーを標準化する設計方針
- 誤用の削減:モジュールと関数プロバイダーの併用による混乱を解消
適切な代替方法
1. 基本設定 (provideHttpClient()
)
HttpClientModule
の完全な代替としてprovideHttpClient()
を利用:
typescript
import { provideHttpClient } from '@angular/common/http';
// モジュールベースプロジェクトの場合
@NgModule({
providers: [provideHttpClient()], // モジュールのimportsではなくprovidersに追加
})
export class AppModule {}
// スタンドアロンコンポーネントの場合 (Angular 18デフォルト)
export const appConfig: ApplicationConfig = {
providers: [provideHttpClient()],
};
重要な変更点:
@NgModule
のimports
から削除providers
配列に追加
2. Fetch APIの利用(オプション)
XHRベースのデフォルト通信を変更する場合:
typescript
providers: [
provideHttpClient(
withFetch() // Fetch APIを使用
)
]
3. インターセプター設定
認証インタセプターなどのカスタマイズ例:
typescript
providers: [
provideHttpClient(
withInterceptors([authInterceptor])
)
]
実装コード (auth.interceptor.ts
):
typescript
import { HttpInterceptorFn } from '@angular/common/http';
export const authInterceptor: HttpInterceptorFn = (req, next) => {
const token = sessionStorage.getItem('JWT');
if (token) {
const authReq = req.clone({
headers: req.headers.set('Authorization', `Bearer ${token}`)
});
return next(authReq);
}
return next(req);
};
移行時に発生するエラーと対応
タイプエラー Type 'EnvironmentProviders' is not assignable to type 'Provider'
- 原因:コンポーネント内で
HttpClientModule
をインポート - 解決策:該当コンポーネントから
HttpClientModule
の参照を完全削除
No provider for HttpClient
- 原因:
- モジュールの
providers
にprovideHttpClient()
追加漏れ app.config.ts
をbootstrapApplication
に渡し忘れ
- モジュールの
- 解決策:
typescript
// main.ts
bootstrapApplication(
AppComponent,
appConfig // 構成情報を明示的に渡す
);
推奨される設計パターン
サービスレイヤー構成例 (user.service.ts
)
typescript
import { HttpClient } from '@angular/common/http';
@Injectable({ providedIn: 'root' })
export class UserService {
constructor(private http: HttpClient) {}
fetchUsers() {
return this.http.get<User[]>('/api/users');
}
}
app.config.ts
標準構成
typescript
import { ApplicationConfig } from '@angular/core';
import { provideHttpClient, withInterceptors } from '@angular/common/http';
export const appConfig: ApplicationConfig = {
providers: [
provideHttpClient(
withInterceptors([loggingInterceptor]) // 複数インターセプター可
),
UserService // サービスを直接提供可能
]
};
非推奨の背景と公式方針
Angularの公式ソースコードでは、HttpClientModule
が単なるラッパーである事が明示されています:
typescript
@NgModule({
providers: [provideHttpClient(withInterceptorsFromDi())],
})
export class HttpClientModule {} // 実質空クラス
移行のメリット:
- ツリーシェイキング効率化
- スタンドアロン/モジュール構造の統一
- 機能拡張の容易さ (
withInterceptors
等の拡張関数追加)
公式ドキュメントはHTTPガイドで詳細を解説しています。