見出し画像

Nuxt.jsでRails API(RESTful)リポジトリパターンを適用させる

久々の投稿です😉
今回、Nuxt.jsのバックエンド側がRails API(RESTful)の場合を想定した時のリポジトリパターンを紹介します。

環境
・Rails 6.0.0(APIモード)
・vue/cli 4.2.3
・Nuxt.js 2.4.2

こちらの記事を参考にしました。

具体的に何ができるようになるのかというと、Rails APIでrails g scaffold user name:stringするとこんな感じのRESTfulなルートが追加されると思います。

GET /users(.:format) users#index
POST /users(.:format) users#create
GET /users/:id(.:format) users#show
PATCH /users/:id(.:format) users#update
PUT /users/:id(.:format) users#update
DELETE /users/:id(.:format) users#destroy

これをNuxt.js側で以下のようなRESTfulにリクエストを送るのが目的です

this.$repositories.users.index();
this.$repositories.users.create({ name: 'mesufu' });
this.$repositories.users.show(1);
this.$repositories.users.update(1, { name: 'osufu' });
this.$repositories.users.delete(1);

これの何が良いのかというとAPIのエンドポイントが全て同じになるのでデバッグ、変更が楽になるのとコードがDRYになります。

※Nuxt.jsにaxiosが導入されている前提で進めていきます

リポジトリパターンの作成

// api/repository.js

export default $axios => resource => ({
  index() {
    return $axios.$get(`/${resource}`);
  },
  create(payload) {
    return $axios.$post(`/${resource}`, payload);
  },
  show(id) {
    return $axios.$get(`/${resource}/${id}`);
  },
  update(id, payload) {
    return $axios.$put(`/${resource}/${id}`, payload);
  },
  delete(id) {
    return $axios.$delete(`/${resource}/${id}`);
  },
});

それぞれresourceに合ったRESTfulな関数を定義してあげます

resourceの定義

先ほどのリポジトリパターンを使用して各resourceをNuxt.jsに注入します
今回は例としてusersとpostsのresourceを定義しています。

// plugins/repository.js

import createRepository from '~/api/repository.js'

export default (ctx, inject) => {
  const repositoryWithAxios = createRepository(ctx.$axios)

  const repositories = {
    users: repositoryWithAxios('users'),
    posts: repositoryWithAxios('posts'),
  }

  inject('repositories', repositories)
}

最後のinjectをすることでNuxt.jsのプラグインとして機能させることができます。

プラグインに追加する

// nuxt.config.js

...

  plugins: [
    ...
    '~/plugins/repository',
  ],

...

これでどこからでもthis.$repositoriesから定義したAPIを呼び出すことができます。

使用例

// id 1 のユーザー取得
const user = await this.$repositories.users.show(1);

リポジトリパターンを追加する

例として検索のパターンを追加したいなってなった時

// api/repository.js

export default $axios => resource => ({
  index() {
    return $axios.$get(`/${resource}`);
  },
  create(payload) {
    return $axios.$post(`/${resource}`, payload);
  },
  show(id) {
    return $axios.$get(`/${resource}/${id}`);
  },
  update(id, payload) {
    return $axios.$put(`/${resource}/${id}`, payload);
  },
  delete(id) {
    return $axios.$delete(`/${resource}/${id}`);
  },
  search({ query }) { // ←追加
    return $axios.$get(`/${resource}/search`, { params: query });
  },
});

呼び出し例(qパラメータでキーワード検索する、みたいな)

const res = await this.$repositories.users.search({
  query: {
    q: 'sufu'
  }
})

Rails側ではこんな感じのリクエストがきます

Started GET "/users/search?q=sufu"
Parameters: {"q"=>"sufu"}

以上です

他、resourceのファイル分割化とか、RESTful以外のresource固有のAPIの呼び出しとか、どうするべきか検討中です。

この記事が気に入ったらサポートをしてみませんか?