Vue.jsでのAPIリクエストをaxios&RepositoryFactoryパターンで実装する
- 公開:
- 更新:
- カテゴリ: JavaScript Vue.js
- タグ: JavaScript,Factory,Vue,API,Repository,axios
Vue.jsに限らずJavaScriptフレームワークでフロントエンドを実装していると、アプリケーションによって データを取得したりなど、外部のAPIなどと通信を行う機会も多く発生します。
今回、API周りを良い感じに実装できるパターンが無いかなと探していたところ、以下の記事でRepository&Factoryパターンでの実装パターンを紹介していました。
【Vue.js】Web API通信のデザインパターン
https://qiita.com/07JP27/items/0923cbe3b6435c19d761
今回はVue.jsでのAPIリクエストをaxios&RepositoryFactoryで実装してみます。
- アジェンダ
開発環境
今回の開発環境は以下の通りです。
- Vue.js 2.x
- Vue CLI 3.x
- axios 0.18.0
- Node.js 12.x
- npm 6.5
axios
axiosは、ブラウザ及びnode.js用のPromiseベースのHTTPクライアントです。
axios
https://github.com/axios/axios
- ブラウザからXMLHttpRequestsを作成する
- node.jsからhttpリクエストを行う
- Promise APIをサポート
- リクエスト・レスポンス内容の出力(interceptors)
- リクエスト及びレスポンスデータの変換
- リクエストのキャンセル
- JSONデータの自動変換
- XSRFから保護するためのクライアント側のサポート
今回はaxiosを使ってサーバ側へリクエストを投げます。
インストール
axiosのインストールはnpmなら以下コマンドで出来ます。
npm install axios
その他、yarn/bowerでもインストール可能。詳細は公式参照。
RepositoryFactoryパターン
Repositoryパターンは永続化の隠蔽、Factoryパターン(ここではFactoryMethodの方)はオブジェクトの生成に関するデザインパターン。
紹介記事ではRepositoryFactoryとして、RepositoryパターンとFactory(FactoryMeyhod)パターンの両方を用いて実装しています。
Repository
では実装してみます。まずは大本のリソースを定義します。
- Repository.js
-
import axios from 'axios'
const baseDomain = 'localhost:8000'
const baseURL = `http://${baseDomain}`
export default axios.create({
baseURL: baseURL
})
変更の必要の無い部分をベースのURLとしてaxiosのインスタンス生成時に渡しています。
userRepository
次はエンティティのリソース定義です。 今回はユーザーに関するCRUD操作を仮定して、userRepositoryを作成します。
- userRepository.js
-
import Repository from './Repository'
const resource = 'store.php'
export default {
register (payload) {
Repository.defaults.headers.post['Content-Type'] = 'multipart/form-data'
return Repository.post(`${resource}`, payload)
}
}
ユーザー登録を想定して記述しています。画像などのファイルもアップロードするので、 ContentTypeをmultipart/form-dataに指定しています。
例えばユーザー情報を取得したりする場合には、ここにメソッドを追加していく流れになります。
RepositoryFactory
続いてFactoryです。
- RepositoryFactory.js
-
import userRepository from './userRepository'
const repositories = {
user: userRepository,
}
export const RepositoryFactory = {
get: name => repositories[name]
}
repositories に必要なリポジトリを登録していき、RepositoryFactory のgetメソッドで必要なリポジトリを取得する流れです。
コンポーネント実装
これらを使用する為にコンポーネント側を実装します。
- sameComponent.vue
-
import { RepositoryFactory } from "./Repositories/RepositoryFactory";
const UserRepository = RepositoryFactory.get('user')
export default {
/*
* 省略
*/
methods: {
async send () {
const response = await UserRepository.register({/* something form data */})
if (response.data.success) {
this._sendSuccess(response)
} else {
this._sendError(response.data.message)
}
}
/*
* 省略
*/
Repository使用部分のみ抜粋して記載しています。 FactoryからUserRepositoryを取得し、registerメソッドでフォームデータを投げています。
バックエンド側処理
このセクションはおまけです。今回リクエストを投げる関係で折角なら一通り動作させたいので、PHPで簡単に受け側を実装しました。
- store.php
-
<?php
header("Access-Control-Allow-Origin: *");
if(!empty($_FILES)) {
$file_path_dir = "uploads";
try {
foreach ($_FILES as $key => $file) {
$store_path = sprintf("%s/%s", $file_path_dir, $file['name']);
if (!move_uploaded_file($file['tmp_name'], $store_path)) {
throw new Exception('ファイルの保存に失敗しました');
}
}
$response = [
'success' => true,
'message' => ''
];
} catch(Exception $e) {
$response = [
'success' => false,
'message' => $e->getMessage()
];
}
echo json_encode($response);
} else {
echo json_encode([
'success' => false,
'message' => 'FILE None'
]);
}
データベースは使いませんが、代わりにファイルを保存します。 処理後は、結果をjsonで返します。
もしMacでPHPが動作する環境であれば、以下のコマンドで開発用ビルトインウェブサーバーを起動できます。
# ドキュメントルートへ移動
cd /path/to/project
# ビルトインウェブサーバーの起動
php -S localhost:8000
まとめ
RepositoryFactoryを用いるとそれぞれが分離されて、拡張や保守も簡単になります。
コンポーネント側の実装もaxiosやAPI部分が隠蔽されているのでコードもすっきりしていていい感じです。
JavaScriptでもしっかり設計して実装していきたいですね。