NuxtMeetup #8
2019/05/07
@nakajmg
じまぐ
@nakajmg
Frontend Engineer at PixelGrid Inc. + 副業
技術書典5でコンポーネント設計の本を出しました
axios-moduleをaxiosに置き換えた
async sendForm() {
const url = '/api/users'
const users = await this.$axios.$post(url, this.formData)
this.$router.push('/uses')
}
async fetch({ store, app }) {
const url = `/api/users/${this.$route.params.id}`
const users = await app.$axios.$get(url)
store.commit('setUsers', { users })
}
{
async fetch({ app, store, route }) {
const path = `/users/${route.params.id}`
const res = await app.$axios.$get(path)
store.commit('setUserData', { data: res })
},
methods: {
async updateUserData() {
const path = `/users/${this.$route.params.id}`
await this.$axios.$put(path, this.formData)
this.$route.push('/users')
}
}
}
プロジェクトに人を追加したときの初速が出しづらくなったり、負債となる可能性が高い
axios-moduleに限らず起こりうる問題だがthisやcontextに注入されるという性質上、
共通化や抽象化をする余地が少なく負債として顕在化しやすい
抽象化と共通化 (Client-Side Gatewayの作成)
axiosを直接使わずにリクエストだけを行うモジュールを、$axiosと同じようなインターフェースで実装する
今後 sindresorhus/ky に乗り換えたい!となったとしても同じインターフェースを実装すれば交換できる
// src/utils/request.js
import axios from 'axios'
const apiRoot = '/api'
export default {
get(url, config = {}) {
return axios({
method: 'GET',
url: `${apiRoot}${url}`,
...config
})
.then(res => res.data)
.catch(err => err)
},
post(url, config = {}) {
return axios({
method: 'POST',
url: `${apiRoot}${url}`,
...config
})
.then(res => res.data)
.catch(err => err)
},
...
}
エンドポイントごとに関数化して、関数ごとにファイルをわける。
1ファイル1関数1export
パスが一緒でもMethodが異なれば別の関数にする
// src/api/updateUserData.js
import request from '~/utils/request'
function updateUserData({ userId, data }) {
const path = `/users/${userId}`
return request.put(path, { data })
}
export default updateUserData
// src/api/getUserData.js
import request from '~/utils/request'
function getUserData({ userId }) {
const path = `/users/${userId}`
return request.get(path)
}
export default getUserData
名前をつけることで、パスやMethodを見なくても何をするものか推測できるようになる
エディタの解析が効く!
TypeScriptやJSDocで補完を強化できて圧倒的生産性向上!
// src/api/index.js
import getUserData from '~/api/getUserData'
import updateUserData from '~/api/updateUserData'
export default {
getUserData,
updateUserData
}
$axiosを使用している箇所を、作成した関数で置き換える
'$axios'で検索してパスとMethodをみて地道に…
import api from '~/api'
export default {
async fetch({ store, route }) {
const res = await api.getUserData({ userId: route.params.id })
store.commit('setUserData', { data: res })
},
methods: {
async updateUserData() {
await api.updateUserData({ userId: this.$route.params.id, data: this.formData })
this.$route.push('/users')
}
}
}
export default {
async fetch({ app, store, route }) {
const path = `/users/${route.params.id}`
const res = await app.$axios.$get(path)
store.commit('setUserData', { data: res })
},
methods: {
async updateUserData() {
const path = `/users/${this.$route.params.id}`
await this.$axios.$put(path, this.formData)
this.$route.push('/users')
}
}
}
何かを簡単に使えるようにするモジュールやプラグインは、何かを簡単じゃなくしていることもある
「プラグインやモジュールを使わない」ということではなく、アプリケーションの性質や成長に合わせて選定・交換する