Angular v4.3 で追加された HttpClient を使ってみた
Angular v4.3 で新たに追加された HttpClient というモジュールを使ってみた。
これは既存の Http モジュールとは別モノで提供されていて、JSON のパースを勝手にやってくれたり、レスポンスの型指定ができたりと便利なようなので、ちょっとだけ使ってみた。
Angular v4.3 プロジェクトを用意する
前提環境は Angular CLI で作れる Angular アプリの雛形相当。これに Angular v4.3 のモジュール群をインストールする。
Angular は毎週パッチバージョンが上がるので、執筆時点では v4.3.2 になっている。npm outdated
でバージョンを確認し、npm update
で @angular
の各パッケージを v4.3.2 にアップデートする。npm-check-updates
というパッケージを使えば一気に更新できるので、これをグローバルインストールして ncu -a
とするのが楽かも。
HttpClient モジュールを追加する
次にアプリのモジュールに HttpClient モジュールを追加する。
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { HttpClientModule } from '@angular/common/http'; // ← コレ
@NgModule({
imports: [
BrowserModule,
HttpClientModule // ← コレ
],
// 以下略
})
export class AppModule {}
HttpClient を使用するサービスを作る
次に HttpClient を使用するサービスを作る。ココでは GET・POST 通信をそれぞれ行うメソッドを用意した。
import { Injectable } from '@angular/core';
import { HttpClient, HttpParams } from '@angular/common/http';
/**
* GET・POST 通信を行うサンプル
*/
@Injectable()
export class SampleService {
/**
* コンストラクタ
*
* @param http HttpClient を DI する
*/
constructor(private http: HttpClient) { }
/**
* GET 通信のサンプル
*
* @return GET 通信の結果を持った Promise
*/
get(): Promise<any> {
const url = 'http://example.com/sample-api';
const myParameter = 'MyParameterValue';
return this.http.get(url, {
params: new HttpParams().set('myParameter', myParameterValue);
}).toPromise();
}
/**
* POST 通信のサンプル
*
* @return POST 通信の結果を持った Promise
*/
save(): Promise<any> {
const url = 'http://example.com/sample-api';
const body = {
myPostData: 'MyPostDataValue'
};
return this.http.post(url, body).toPromise();
}
}
GET 通信のサンプル
一番簡単な GET 通信のサンプルは以下のとおり。
this.http.get(url)
.subscribe((response) => {
// response は Object 型
});
これで指定の URL に GET 通信ができる。
これまでの Http モジュールは戻り値が Observable<Response>
であり、JSON パースする必要があったが、HttpClient では Observable<Object>
で返されるので JSON パースが要らなくなった。
上述の SampleService では、パラメータを指定している他、Observable を Promise に変換している。以下のように扱うことができる。
this.http.get(url, {
params: new HttpParams().set('myParameter', 'MyParameterValue');
// レスポンスのフォーマットを指定する場合は以下
responseType: 'text'
})
.toPromise()
.then((response) => {
// 処理
});
これで、【url】?myParameter=MyParameterValue
という URL で GET 通信したのと同じ結果が得られる。
POST 通信のサンプル
POST 通信の場合も、基本的なやり方は同じ。
this.http.post(url, {
myPostData: 'MyPostDataValue'
})
.subscribe((response) => {
// 成功
}, (error) => {
// 失敗
});
GET パラメータに対応する、POST 時の body は Object で記せば良い。
これも SampleService の方では Promise 化している。
this.http.post(url, body)
.toPromise()
.then((response) => {
// 成功
})
.catch((error) => {
// 失敗
});
ユニットテストのやり方
HttpClient モジュールはユニットテストでのモック化も楽になっている。少しだけつまづいたところがあるので紹介。
import { HttpClientTestingModule, HttpTestingController } from '@angular/common/http/testing';
import { inject, TestBed } from '@angular/core/testing';
import { SampleService } from './sample.service';
describe('SampleService', () => {
beforeEach(() => {
TestBed.configureTestingModule({
imports: [HttpClientTestingModule],
providers: [SampleService]
});
});
// テスト対象サービス
let sut;
// 通信先のモック
let httpMock
// テスト対象サービス・モックの用意
beforeEach(inject([SampleService, HttpTestingController], (sampleService: SampleService, httpTestingController: HttpTestingController) => {
sut = sampleService;
httpMock = httpTestingController;
}));
it('GET 通信を行う', () => {
// アクセスを期待する URL : HttpParams を指定している場合はパラメータを含めて URL とする
const url = 'http://example.com/sample-api?myParameter=MyParameterValue';
// モックの戻り値
const result = 'Mock GET Result';
// テスト対象関数の実行
sut.get()
.then((data) => {
// モックとして返却したデータが受け取れていること
expect(data).toEqual(result);
})
.catch((error) => {
fail(`GET 通信のテストに失敗 : ${error}`);
});
// モック API を用意する
const request = httpMock.expectOne(url);
// モック API からの応答を返す
request.flush(result);
// モック化した API がコールされたか検証する
httpMock.verify();
});
it('POST 通信を行う', () => {
// アクセスを期待する URL
const url = 'http://example.com/sample-api';
// モックの戻り値
const result = 'Mock POST Result';
// テスト対象関数の実行
service.post()
.then((data) => {
// モックとして返却したデータが受け取れていること
expect(data).toEqual(result);
})
.catch((error) => {
fail(`POST 通信のテストに失敗 : ${error}`);
});
// モック API を用意する
const request = httpMock.expectOne(url);
// モック API からの応答を返す
request.flush(result);
// モック化した API がコールされたか検証する
httpMock.verify();
});
});
- テスト時は
HttpClientTestingModule
をimports
に指定する。 HttpTestingController
がモック API を担当する。HttpTestingController#expectOne()
の引数に指定した URL に対してアクセスがあれば OK となる。- GET 通信にパラメータを指定している場合は、パラメータを含めて URL が一致しないとテストが通らない。
HttpTestingController#verify()
で、「アクセスを待ち構えていたけど呼ばれなかった URL」が分かったりする。
こんな感じ。他にも色々便利な機能があるっぽいけど、新しすぎて文献不足。
参考
- Angular Docs
- Angular 4.3で追加されたHttpClientModuleについてのメモ - Qiita
- Angular HTTP Client - QuickStart Guide
- A Taste From The New Angular HTTP Client – Netanel Basal
- Introduction to Angular's HttpClient ← Alligator.io
- Angular - How to use HttpClientModule? | Ninja Squad
「Observable って何?」という方は以下などをドウゾ。簡単に言うと高機能 Promise。