APIを構築した経験があれば、難しさが分かるでしょう。プロジェクトは収拾がつかないほど複雑になり、ドキュメントを作成してみても、結局すっきりしません。
以前簡単に紹介したツールPostmanを試しました。Postmanなら、認証、テスト、ドキュメント作成、バージョン管理などAPIの多くの要素を統合して開発できる環境で、API構築の強力な助けになると分かりました。
Postmanの多彩な機能と統合環境で、APIを簡潔に開発する方法を紹介します。
リクエストする
PostmanでシンプルなAPIリクエストを送信して、レスポンスを取得します。
上記のスクリーンショットで、ビューにたくさんの要素が配置されていていることが分かります。上部のバーにはリクエストメソッド(この場合は GET)、その横にはリクエストのエンドポイントを入力します。リクエストに引数がある場合は、Paramsボタンをクリックして開いたテーブルに入力します。準備ができたら、Sendボタンをクリックしてリクエストを開始します。
次のセクションにはタブが5つあります。
- Authorization:Basic AuthやOAuth2など、リクエストの認証方法を指定する
- Headers:content-typeやAuthorizationなど、リクエストヘッダーを指定する
- Body:PostやPUTなどの場合に指定するリクエストボディー
- Pre-request Script:リクエスト前に実行するJSコード(詳しくはあとで説明)
- Tests:レスポンスペイロードの妥当性を検証するJSコード
下のボタンのセクションには、レスポンスの情報(status、time、size)が表示されます。Tests以外の3つのタブは名前から意味が分かるので、説明は省略します。Testsのタブには、Testsの結果が表示されます(詳しくはあとで説明します)。
認証
Postmanは多くの認証方式をサポートしています。この記事では、ヘッダーで設定するトークン認証を使います。認証について詳しくはこちらを参照してください。
Postmanのヘッダー形式です。
Authorization: Bearer <TOKEN>
今後のリクエストで使うトークンを取得します。ここでは私が開発中のアプリケーションでテストしますが、ほかのアプリケーションでも可能です。テスト用のアプリケーションをLaravelで立ち上げてテストする方法もあります。
トークンを得られたので、認証済みユーザーとしてAPIからデータを取得できます。ただし、リクエストのたびにトークンをコピーペーストするのは手間です。
環境変数
Postmanには、環境変数を1カ所に集約してコピーペーストを不要にする機能があります。環境とはローカルやテスト、ステージングなどの条件のことです。以下の変数のスコープを定めます。
- グローバル
- 環境
- ローカル
- データ
グローバル変数は指定した環境とは無関係でどこからでも利用できます。詳しくはドキュメントを参照してください。
現時点では少なくとも3つの変数が必要です。
- domain:company1やcompany2などの現時点でアクティブなサブドメイン
- url:アプリのURL
- token:今後の認証に使うトークン
ログインエンドポイントを更新して、新しい環境を利用可能にします。まずは右上部のボックスで環境を選択します。
URLやパラメーター、Testsに含まれている変数を使えます。
トークンを使う方法は2つあります。1つ目はトークンをコピーして、トークン変数としてペーストする方法です(手間なので避けるべきです)。
2つ目は、リクエスト終了後にコードを実行してトークンを設定する方法です。ここでTestsが役立ちます。
テスト
アプリケーション開発では、APIから適切な結果が返ってきたか確認することが大切です。Testsなら、レスポンスの内容が適切か、いろいろな方法で検証できます。基本的な手法を試します。
Testsタブへ移動し次のコードを入力して、ログインリクエストを送信してください。
tests["Successful request"] = responseCode.code === 200;
responseCodeにはレスポンスステータスオブジェクトが含まれているので、レスポンスが200 OKか確認しています。ほかのオブジェクトを使えば、レスポンスボディー(responseBody)やレスポンスヘッダー(responseHeaders)、レスポンス時間(responseTime)も確認できます。テストスクリプトはここを読んでください。
testsオブジェクトには想定通り動作しているかを示すboolean値のリストが格納されていますが、任意のJSコードも追加できます。たとえば、レスポンスのトークンを取得して、環境変数に設定するコードを追加できます。
ステータスを確認し、レスポンスボディーをJSON形式でパースして、トークンを取得します。環境変数ビューを開くと、トークンが適切に設定されているか確認できます。
コンソールの使用方法
コンソールは、オブジェクトを操作したりレスポンスの中身を確認したりできます。cmd+alt+CかView > Show Postman Consoleコマンドでコンソールを開きます。
コンソールにはリクエストとレスポンスオブジェクトのログが詳細に表示され、問題発生時に原因を調べるのに役立ちます。
ヘルプライブラリー
JSON構造の属性種別の確認をはじめ、レスポンス検証をいちから構築するのは手間です。
PostmanにはLodashやtv4 JSONスキーマ検証など、テストに使えるライブラリーが充実しています。全リストはこちらです。
ログインエンドポイントのテストと、少し複雑なテストを解説します。ログインエンドポイントはトークンを返すだけなので、レスポンス中にトークンの値が設定さているか確認します。
let jsonData = JSON.parse(responseBody);
let ok = responseCode.code === 200;
tests["Successful request"] = ok;
tests["Token is set"] = _.has(jsonData, "token");
if(ok) {
pm.environment.set("token", jsonData.token);
}
リソースが返ってきたことを確認すると、たちまち複雑なコードになります。複雑なテストの例です。
var data = JSON.parse(responseBody);
tests["Response OK"] = responseCode.code === 200;
tests["Data is OK"] = data.hasOwnProperty("data") && Object.isObject(data.data);
var requiredKeys = ["uuid", "student_number", "title", "first_name", "last_name", "email", "last_login_at"];
tests["Response structure is OK"] = _.every(requiredKeys, _.partial(_.has, data.data));
上記のテストは、リソースキーが存在することとレスポンスステータスがOKであることを確認しています。これを何度もテストするのは大変です。
そこでtv4の検証スキーマを使います。
let courseSchema = {
"title": "Course",
"type": "object",
"properties": {
"name": {
"type": "string"
},
"code": {
"type": "string"
},
"uuid": {
"type": "string"
},
"is_active": {
"type": "boolean"
},
"is_free": {
"type": "boolean"
},
"is_enrollable": {
"type": "boolean"
},
"in_catalogue": {
"type": "boolean"
},
"price": {
"type": "integer",
"minimum": 0
},
"total_duration": {
"type": "integer",
"minimum": 0
},
"cover_image": {
"type": ["string", "null"]
},
"demo_video": {
"type": ["string", "null"]
}
}
}
let jsonData = JSON.parse(responseBody);
tv4.addSchema("course", courseSchema);
tests["Response is valid"] = tv4.validate(jsonData.data, {
"type": "array",
"items": {
"$ref": "course"
}
});
上記のコードは、コースリソースのスキーマを作成して、JSONレスポンスをパースし、tv4で検証します。
JSONスキーマを構築する方法について詳しくはこちらを参照してください。
このテストの問題点は、スキーマをテストごとにコピーペーストする必要があることです。そこでスキーマを環境変数に保存して、再利用可能にします。
メモ:スキーマを環境変数に保存することに違和感があるかもしれませんが、環境変数には値に限らずなんでも格納できます。
解決したように思えますが、アプリケーションにはたくさんのエンドポイントがあります。開発が進むほど数が増えるので、適切な方法で管理します。
コレクション
コレクションは、たとえるなら同種のものを集約しておくフォルダーです。コレクションの作成と管理方法はドキュメントに書かれており、この記事でも同じ方法を使います。
まずは左端のメニューからnew folderをクリックします。新しいリクエストを作成するときには、Saveボタンをクリックしてフォルダーを選択します。
フォルダー構造はシンプルなほうが良いのですが、統合テストとして分類するため、機能ごとにフォルダーを作成します。
このアプリケーションでは組織ごとにコースのリストがあり、ユーザーはコースに登録して、登録したコースをコースリストで確認できます。この機能のテストを作成して、テスト名を付けたフォルダーに保存します。どうすれば意図した順序でテストを実行できるのでしょうか?
テストのコレクション
Postmanには、リクエストとテストのチェーンを作成して統合テストを実行する便利な機能があります。この記事のテストチェーンを示します。
- 認証トークンを取得(Get auth token)
- 組織別にコースを表示(List organization courses)
- ユーザーをコースに登録(Enroll to a course)
- ユーザー別にコースを表示(List my courses)
// Get auth token
var jsonData = JSON.parse(responseBody);
tests['Token is set'] = jsonData.hasOwnProperty('token');
pm.environment.set("token", jsonData.token);
postman.setNextRequest("List organization courses");
postman.setNextRequestメソッドでテストの順番を指定します。「Get auth token」テストのあとに「List organization courses」を実行します。チェーンを終了するには、nullを渡します。
// List organization courses
let jsonData = JSON.parse(responseBody);
let courseSchema = JSON.parse(pm.environment.get('courseSchema'));
tv4.addSchema("course", courseSchema);
tests["Response OK"] = responseCode.code === 200;
tests["Data is OK"] = jsonData.hasOwnProperty("data") && Array.isArray(jsonData.data);
tests["Response is valid"] = tv4.validate(jsonData.data, {
"type": "array",
"items": {
"$ref": "course"
}
});
pm.environment.set('courseId', jsonData.data[0].uuid);
postman.setNextRequest("Enroll to a course");
pm.environment.set('courseId', jsonData.data[0].uuid);の行では、リストの先頭のコースを取得して、enroll requestで利用可能な環境変数を設定しています。
// Enroll to a course
tests["Response OK"] = responseCode.code === 201;
postman.setNextRequest("List my courses");
// List my courses
let jsonData = JSON.parse(responseBody);
let courseSchema = JSON.parse(pm.environment.get('courseSchema'));
tv4.addSchema("course", courseSchema);
tests["Response OK"] = responseCode.code === 200;
tests["Data is OK"] = jsonData.hasOwnProperty("data") && Array.isArray(jsonData.data);
tests["Response is valid"] = tv4.validate(jsonData.data, {
"type": "array",
"items": {
"$ref": "course"
}
});
tests["Enrolled course added"] = jsonData.data[0].uuid === pm.environment.get('courseId');
postman.setNextRequest(null);
フォルダーに機能を表す名前を付けて、すべてのテストを保存します。
コレクションを実行
コレクションを実行するには、左端のバーの右矢印をクリックしてメニューを開き、Runを選択します。
コレクションではなくフォルダーでも実行できます。テストの実行中にエラーが発生すれば、コンソールを開いてログを確認します。テストのコレクションはドキュメントを読んでください。
事前に用意したデータでコレクションを実行する機能もあります。詳しくはここを確認してください。
ドキュメント作成
APIにはドキュメントが欠かせません。Postmanにはドキュメント作成を支援するツールがあります。
ドキュメントの作成は、コレクションを選択してview in webをクリックします。コレクションとリクエストのドキュメントが開き、リクエストの詳細(ボディー、パラメーター、ヘッダー、メソッドなど)を確認できます。ドキュメントの作成について詳しくはここに書かれています。
ドキュメントにはレスポンスも含められます。PostmanにはExampleをドキュメントに組み込む機能があります。
Exampleを使う
Exampleはレスポンスを切り取り、APIの一部として利用できます。リクエストを実行して得られるものを実際に実行せずに確認できます。
Postmanでリクエスト実行後に、Save responseボタンを押してヘッダーやパラメーターなどを定義します。
そのあとでドキュメントをWebで開くと、先ほどのExampleが表示されます。
ドキュメントの公開
ドキュメントはAPIの使用者がアクセスでき、APIの使い方を確認します。Postmanにはドキュメントを共有する方法が数種類あります。プロアカウントなら、プライベートなドキュメントの共有やチームの構成ができます。ドキュメントのリンクを生成して共有する機能もあります。
ドキュメントページ上部にPublishボタンがあります。
モック
モックは、アプリケーションのプロトタイプを作成してAPIの構造を検討するときに使用します。チーム開発の場合は、モックに合意したら、各自の作業(バックエンド、フロントエンド、モバイルなど)をして、パーツを作り、環境を新しいサーバーに変更します。
モックサーバーのリンクを生成して、認証用にPostman APIキーを取得します。2つ目のスクリーンショットにはAPIキー取得の警告が表示されています。Get your Postman API keyリンクをクリックして、新しいキーを生成します。
モックURLとAPIキーがあれば、<mockUrl/api/auth/login>などでAPIエンドポイントを呼び出せます。
Postmanのモックは重要なトピックです。詳しくはモックサーバーを立ち上げるやモック例を読んでください。
エクスポートとインポート
チームメンバーやAPI利用者とドキュメントを共有する方法を説明しましたが、API開発には環境の共有や進捗の集約も必要です。Postmanには、エクスポート・インポートできる機能が備わっています。
Postmanアカウントを持っていればチームメンバーと簡単に共有できます。ツールのテスト中にはエクスポート・インポート機能が役立ちます。
コレクション
コレクションをエクスポートするには、左端のバーのコレクションリストからコレクションメニューを開いてExportをクリックします。するとエクスポート形式を選択するポップアップが開きます。おすすめはv2形式です。
コレクションをインポートするには、トップメニューのImportをクリックして、インポートするJSONファイルを選択します。
環境
コレクションと同じく、環境もManage Environmentsメニューから簡単にエクスポート・インポートできます。
コレクションの実行をはじめ、共有に関する機能はほかにもたくさんあります。ドキュメントを確認ください。
便利な資料
- https://www.getpostman.com/docs/
- http://blog.getpostman.com/2017/07/28/api-testing-tips-from-a-postman-professional/
- https://medium.com/@codebyjeff/using-postman-environment-variables-auth-tokens-ea9c4fe9d3d7
最後に
Postmanを使ってAPI開発を進める方法を説明しました。いくつかの機能を紹介しましたが、ほかにもできることはたくさんあります。ドキュメントに目を通して、API開発にPostmanを活用してください。
(原文:How to Master Your API Workflow with Postman)
[翻訳:内藤 夏樹/編集:Livit]