|
| 1 | +# 在 nuxt 中优雅的管理 API |
| 2 | + |
| 3 | +## 背景 |
| 4 | + |
| 5 | +在使用 nuxt 开发复杂系统时,往往伴随着海量的 API 接口。如果单纯的使用 [@nuxtjs/axios](#),那么 API 将与业务代码耦合在一次。最糟糕的状况是每个开发者都在页面中写下面的代码 |
| 6 | + |
| 7 | +```javascript |
| 8 | +// Page 1 获取一个用户的信息 |
| 9 | +this.$axios.$get('/deepexi-cloud/users/1') |
| 10 | + |
| 11 | +// Page 2 创建一个用户 |
| 12 | +this.$axios.$post('/deepexi-cloud/users', body) |
| 13 | +``` |
| 14 | + |
| 15 | +对于 RESTful API 同一个资源,需要创建多个字符串来维护,即便可以通过抽离常量来维护,但对于调用者,还必须 import apiUrl,使用对应的 methods 来调用接口。 |
| 16 | + |
| 17 | +随着业务规模的扩张,需要一个能统一维护 API 的方案,来降低开发者的使用和维护成本。需要满足这几点: |
| 18 | + |
| 19 | +- 可以直接调用方法,而不是写 this.$axios.$get('string') |
| 20 | +- 可以获取一个基本的 RESTful 资源链接,方便 data-table 等组件使用 |
| 21 | +- 修改接口服务、版本、资源名称时,修改一处即可 |
| 22 | + |
| 23 | +## 使用 |
| 24 | + |
| 25 | +```javascript |
| 26 | +// 创建一个 API 资源,修改文件 src/api/index.js |
| 27 | + |
| 28 | +// 创建了一个菜单资源的 CRUD 接口方法 |
| 29 | ++ export const menus = new Repository(`${DEEPEXI_CLOUD_TENANT}/${VERSION}/menus`) |
| 30 | + |
| 31 | +// 获取一个菜单,只要能访问到 nuxt 上下文的地方都可以调用,最常见是 this |
| 32 | + |
| 33 | +// 在 page 中 |
| 34 | +mounted() { |
| 35 | + // 获取资源的服务器路径 |
| 36 | + this.$http.menus.uri() |
| 37 | + // 获取所有菜单资源,返回一个列表 |
| 38 | + this.$http.menus.list() |
| 39 | + // 获取某个菜单资源的详情 |
| 40 | + this.$http.menus.detail(MENUS_ID) |
| 41 | + // 创建一个菜单资源 |
| 42 | + this.$http.menus.create(payload) |
| 43 | + // 更新一个菜单资源 |
| 44 | + this.$http.menus.update(MENUS_ID, payload) |
| 45 | + // 删除一个菜单资源 |
| 46 | + this.$http.menus.delete(MENUS_ID) |
| 47 | +} |
| 48 | + |
| 49 | +// 在 store 中 |
| 50 | +export const actions = { |
| 51 | + async getMenus(store, payload) { |
| 52 | + const data = await this.$http.menus.detail(payload) |
| 53 | + ... |
| 54 | + } |
| 55 | +} |
| 56 | +``` |
| 57 | + |
| 58 | +## 进阶 |
| 59 | + |
| 60 | +有些时候,后端的接口并不是严格遵循 RESTful 的最佳实践,这个时候就需要自己重新实现默认的方法 |
| 61 | + |
| 62 | +```javascript |
| 63 | +// 在 src/api/repository.js 中增加一个类,继承 Repository |
| 64 | +export class ExampleRepository extends Repository { |
| 65 | + constructor(resource, id) { |
| 66 | + super(resource) |
| 67 | + this.id = id |
| 68 | + } |
| 69 | + |
| 70 | + uri(appId) { |
| 71 | + return `${this.resource}/status/${this.id}?appId=${appId}` |
| 72 | + } |
| 73 | + |
| 74 | + update($axios) { |
| 75 | + return (appId, payload, ...args) => |
| 76 | + $axios.$post(`${this.uri(appId)}`, payload, ...args) |
| 77 | + } |
| 78 | +} |
| 79 | + |
| 80 | +// 基于 ExampleRepository 创建一个 API |
| 81 | +export const example = new ExampleRepository('/example/api') |
| 82 | + |
| 83 | +// 调用 |
| 84 | +this.$http.example.uri(appId) |
| 85 | +this.$http.example.detail(id) |
| 86 | +this.$http.example.list() |
| 87 | +this.$http.example.create(payload) |
| 88 | +this.$http.example.update(appId, payload) |
| 89 | +this.$http.example.delete(id) |
| 90 | +``` |
0 commit comments