nuxtjsでDIをする
nuxtjsでフロントエンドを構築することが多くなり、データ取得をAPIで実装しています。
APIを開発している間は、フロントエンドが開発できなくなったりAPIの不具合があったりすると、フロントエンドの開発が止まってしまうためDIがほしくなり調べました。
plugins
envの値により、APIを使用するかテストデータを使用するか切り替えられるように作成しています。
export default ({$axios}, inject) => { const environment = process.env.environment || 'development'; let factory = new DependenciesFactory(); inject('deps', factory.dependencyFactory(environment, $axios)); }; export interface Dependencies { userRepository: IUserRepository; } export class DependenciesFactory { dependencyFactory(environment, $axios): Dependencies { let userRepository: IUserRepository; userRepository = this.getUserRepository(environment, $axios) return { userRepository, } } getUserRepository(environment, $axios) { if (environment === 'offline') { return new StubUserRepository(); } return new HttpUserRepository($axios) } }
export interface IUserData { 'id': any; 'name': any; } export interface IUserDataList { list: Array<IUserData>; } export interface IUserRepository { fetchById(id): Promise<IUserData>; fetchList(param): Promise<IUserDataList>; // リスト取得 }
import {NuxtAxiosInstance} from "@nuxtjs/axios"; export class HttpUserRepository implements IUserRepository { client: NuxtAxiosInstance; constructor(client: NuxtAxiosInstance) { this.client = client; } async fetchById(id): Promise<IUserData>{ return await this.client.$get("/user/show", {params: {id: id}}); } async fetchList(param): Promise<IUserDataList> { return await this.client.$get("/user/list", param); } }
export class StubUserRepository implements IUserRepository { fetchById(id) : Promise<IUserData> { return new Promise(resolve => { resolve({ param: this.findById(id), }); }); } fetchList(param): Promise<IUserDataList> { return new Promise(resolve => { resolve({ param: { count: 2, list: this.listData() } }); }); } findById(id) { const list = this.data(); for (let i = 0; i < list.length; i++) { if (list[i].id == id) { return list[i] } } return list[0]; } data(){ return [ { 'id': 1, 'name': "sei mei", }, { 'id': 2, 'name': "hoge fuga", }, ] } }
nuxt.config.jsでplugin使用設定
plugins: [ {src: '~/plugins/dependencies'}, ],
呼び出し
page側で必要に応じて呼び出し
methods: { getData() { this.$deps.userRepository.fetchById(this.user_id).then(res => { this.user = res }).catch(err => { console.log(err) }) } }
感想
特別なplugin等は使っていなかったので、コードを読む手間がなかったのがありがたかったです。
準備に手間がかかりますが、作業分離もできテストにも使えるためかなり便利だと思っています。
どれくらいAPIの変更があるのか、メンテナンス性については運用で試していきたいと思っています。