JavaScript
デザインパターン
DesignPatterns
Vue.js

【Vue.js】Web API通信のデザインパターン (個人的ベストプラクティス)


はじめに

Vue.jsを使用したアプリケーションでのWeb API呼び出しのデザインパターンについて調べてみました。

しかし検索して出てくるチュートリアルやサンプルは、コンポーネント内でaxiosをインスタンス化していたり、Vuexの中でaxiosを使用するというサンプルがほとんどでした。

しかし実際のプロダクトでこれをしてしまうと


  • コンポーネント内でAPIアクセスの直書きによって単体テストが困難に

  • Vuex(actions)の肥大化(使い回さない処理はStoreに記述しないほうがいいとする文献もある)

  • API通信部分をPureJSでモジュール化しても依存度がイマイチ下がらない(コンポーネントでモジュールをインポートするため)。

などなど問題になることが多そうでした。

ある日、Jorge氏が投稿した「Vue API calls in a smart way」という記事にたどり着きました。

結果から言うとこのデザインパターンは自分にはベストな方法であったため、著者の許可を得て紹介します。以下拙訳(一部意訳)です。


ここから翻訳

長い間、APIを呼び出すための様々な方法を公開したいと思いました。この章では私にとって最適なパターンについて話したいと思います。RepositoryFactoryを紹介させてください。

私はこのアプローチが非常によくスケールでき、ほぼいつも上手くいくため大好きです。


なぜかを説明しましょう:

1つはリポジトリパターンを使用して、データを返す以外のロジックなしで分離された方法でリソースにアクセスできます。

もう1つはファクトリパターンを使用して、各ケースで必要なリポジトリ、または環境のロジックをインスタンス化します。必要に応じて、ファクトリがモックリポジトリと本番リポジトリのどちらをインスタンス化するかを決定できるという利点があります。

各コンポーネント内にaxiosのインスタンスを使用したサンプルをどれだけ見たでしょうか。

私はそれを見るたびに毎回疑問に思います🤔


  • 呼び出し処理を再利用するときはどうなりますか?

  • エンドポイントが変わったときはどうなりますか?

  • ほかのプロジェクトでAPI呼び出し処理を再利用したい場合はどうなりますか?

  • コードをリファクタしたり、Vuexのactionsに移動する場合はどうなりますか?

  • 複数のリソースがありますが、4つの異なるエンドポイントを定義する必要がありますか?

  • テストのためにモックなどのエンドポイントをどのように扱うことができますか?

0_5m-dDbSZ3gb8oaCJ.gif

30個のファイルを変えるよりも1個のファイルを変えるほうが簡単でしょう?🤯


正しい方法

このケースではコードをシンプルにして、さまざまなリソースを定義するために、POJO(Plain Old JavaScript Objects)を使用します。(もちろん、必要に応じてクラスを使えます)axiosの設定を定義しましょう。ファイル名はリソースの接続を確立する責任があるため、Repository.jsとします。

serviceまたは単にAPIという用語を使う人もいますが、Repositoryがその機能を最もよく定義しているように思えます。

image.png

それから、それぞれのエンティティのリソース定義をする必要があります。

例えばブログがあるとしましょう。postsエンティティがあり、すべてのCRUD操作を独自のリポジトリファイルに定義できます。

postsRepositoryはこんな感じです。

image.png

そしてファクトリを作成します。

image.png

見ての通りリクエストしたリソースのシンプルなオブジェクトが返されます。

この段階でget()メソッドにさらにロジックを追加して複数の環境を扱ったり、モックリポジトリをインポートしたりできることに気付いたでしょう。

たとえば、現在私がいる会社(Snap.hr)では、いくつかの異なる環境が必要です。環境に応じて、モックまたは対応するエンドポイントに変更します。これはあなたが望むものと同じような複雑さでしょう。

でもこの例ではシンプルにしましょう🙃

.vueファイルのSFCでどのように使用するかお見せしましょう。

image.png

ロジックは完全に分離されているので、異なるパラダイムを持つ別のエンドポイントをGraphQLとして使用することもできます。


💡結論

常に銀の弾丸は存在しないものです。このパターンは私のほとんど全部のプロジェクトでうまくいっていますが、あなたのプロジェクトにとって最適という意味ではありません。

しかし、以下のアドバンテージがあると思います。


  • 簡単な方法でテスト可能なコードを実行できます。

  • コンポーネントのコードがきれいになります。

  • 簡単に拡張できますよね?


  • DRYを保つことができます。

実用的なサンプルCodesandbox で作成し、このアプローチを実際に実装してみました。

この種の手法を既に使用しているのであれば、ぜひお聞かせください。

👋

提案や質問がありますか?お気軽にコメントやTwitterでコンタクトください!

この記事は2018年に最も人気のあったVue.js記事の1つに選ばれました。


ここまで翻訳


謝辞(Appreciation)

Dear Jorge

Thank you for your amazing article!