3月8日、Angular公式ブログで「httpResourceを用いたシームレスなデータフェッチ(Seamless data fetching with httpResource)」と題した記事が公開された。
この記事では、Angularにおける新しいsignalベースの非同期データ取得API「httpResource」について詳しく紹介されている。
以下に、その内容を簡潔にまとめて紹介する。
本記事は、以下のエキスパートに監修していただきました:
httpResource
について
httpResource
は、AngularのHttpClient
を内部で用いて動作するAPIである。Angular標準のHTTPスタックを利用するため、インターセプターなどの既存の仕組みやテスト手法をそのまま活用できる。
たとえば、以下のようにhttpResource
を定義し、currentUserId
というSignalを用いてリクエストURLを動的に変更できる。
currentUserId = getCurrentUserId(); // currentUserIdはSignal
// Signalを含むリアクティブな関数を引数に取っている
user = httpResource(() => `/api/user/${currentUserId()}`);
デフォルトでは、httpResource
はGETリクエストを行い、JSONとしてレスポンスをパースして返す。通常のHttpClient
と異なるのは、購読(subscribe)を待たずにリクエストが即時に発行される点だ。ソースとなるSignalの値が変化すれば、自動的に新たなHTTPリクエストが送られる。
また、次のようにリクエストオブジェクトを用いて詳細な設定を加えることも可能である。
user = httpResource(() => ({
url: `/api/user/${currentUserId()}`,
method: 'GET',
headers: {
'X-Special': 'true',
},
params: {
'fast': 'yes',
},
reportProgress: true,
withCredentials: true,
transferCache: true,
}));
httpResource
は基本的に非同期データの取得を目的として設計されており、サーバーへのデータ更新のような用途には推奨されない。フォーム送信などを行いたい場合は、これまで通りHttpClient
のメソッドを使うべきだ。
また、以下のように返却されるデータ型をJSON以外にすることも可能であり、専用のメソッドが用意されている。
httpResource.text(() => ({ … })); // value()でテキストを返す
httpResource.blob(() => ({ … })); // value()でBlobを返す
httpResource.arrayBuffer(() => ({ … })); // value()でArrayBufferを返す
httpResource
の構造
httpResource
が返すオブジェクトは、次のようなSignalを持っている。
value()
— HTTPリクエストの結果(成功時)を保持する。プログラム的に上書きも可能status()
— リソースの状態(idle、loading、errorなど)を表すerror()
— リクエストエラーやパースエラーなどを保持するisLoading()
— リクエストが進行中かどうかを示す真偽値
さらに、レスポンスに関する追加情報を得るためのSignalとして、以下が用意されている。
headers()
— レスポンスヘッダーstatusCode()
— HTTPステータスコードprogress()
— リクエストの進捗状況(リクエストオブジェクトで指定されている場合)
HttpClient
の場合、レスポンスヘッダーやステータスコードを取得するには明示的な指定が必要だが、httpResource
ではこれらの値を専用のSignalで取得できるため、コードの見通しが良くなる。
型安全性の追求
HTTPリクエストのレスポンスが期待する型かどうかを検証する「スキーマバリデーション」は、ZodやValibotなどがよく利用されている。httpResource
はこれらのライブラリと直接連携できる仕組みを備えており、parse
パラメータにバリデーション関数を指定すると、その戻り値の型を自動的に推論してくれる。
次の例では、外部のAPI(StarWars API)を呼び出してレスポンスをZodでパースしている。パース結果の型がhttpResource
の型として反映されるため、型安全性が保たれる。
export class AppComponent {
id = signal(1);
swPersonResource = httpResource(
() => `https://swapi.dev/api/people/${this.id()}`,
{ parse: starWarsPersonSchema.parse }
);
}
const starWarsPersonSchema = z.object({
name: z.string(),
height: z.number({ coerce: true }),
edited: z.string().datetime(),
films: z.array(z.string()),
});
実験的APIについて
httpResource
はAngular v19.2リリースに含まれる実験的機能であり、まだ本番環境での使用は推奨されない。将来的にAPIの仕様が変わる可能性があるが、開発チームは幅広いフィードバックを求めているため、興味がある開発者は積極的に試してみるとよい。詳細については、GitHub上のRFCにも情報が公開されている。
詳細はSeamless data fetching with httpResourceを参照していただきたい。