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の呼び出しとか、どうするべきか検討中です。
この記事が気に入ったらサポートをしてみませんか?