kazu22002の技術覚書

PHPer, Golang, AWS エンジニアの日々

nuxtjsでDIをする

f:id:kazu22002:20200916060758p:plain

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の変更があるのか、メンテナンス性については運用で試していきたいと思っています。

参考

tech.cydas.com

qiita.com