前端开发实践与后端开发解耦(一)-- 接口数据mock和接口字段映射

摘要

众所周知,现在的前后端开发都是独立的,除了一些老项目。但是如果公司的开发流程不规范就可能出现前端开发的阻塞,或者出现得多做一些无用功。正确的开发流程应该是:需求评审--需求确认--后端接口设计并输出文档 -- 前/后端开发 -- 联调 -- 测试 -- 上线 。这里主要强调优先输出接口设计文档的重要性。

Mock 数据

mock数据的作用是让前端开发不依赖后端的开发进度,减少创建数据的时间,减少联调的时间。但是mock也有自己的局限,对于一些复杂的接口没法很好的兼容,对于下载文件也不太好mock等。下面用 vue3 + vite 举例

安装依赖

npm install vite-plugin-mock -D

配置

src 目录的同级上新建mock文件夹;并在 vite.config.jsplugins 中添加下面配置,联调时将选项中的 enable 设置为 false

javascript 复制代码
// mock/index.js -- 按模块导入方便管理
import user from './user'
import data from './data'

export default [...user, ...data]


// vite.config.js
viteMockServe({
	mockPath: path.resolve(__dirname, '../../mock'),
	// enable: false,
	localEnabled: viteEnv.VITE_APP_ENV === 'development',
	watchFiles: true,
})
如何Mock数据

如何使用的官方文档:
vite-plugin-mock配置中文文档
mock数据如何使用

下面写一些常用的写法,以及对于 Restful Api 该如何通过 mock 的接口拦截;其他的使用请看文档。

说明一下Restful Api 类型的接口:

删除:/api/v1/project/:id 请求方法为: Delete

修改:/api/v1/project/:id 请求方法为: Post

详情:/api/v1/project/:id 请求方法为: Get

某个项目里的其他列表:/api/v1/project/:id/other/list 请求方法为: Get

第一种:非 Restful Api
javascript 复制代码
[
	{
		url: '/dev-api/api/v1/project',
		method: 'get',
		response: () => {
			return Mock.mock({
				code: 0,
				msg: 'OK',
				'data|10': [
					{
						id: '@guid',
						name: '@string',
						desc: '@sentence',
						created_at: '@integer(1693904305000, 1725526705000)',
					},
				],
			})
		},
	},
	// 有查询参数,以下所有都是通用的
	{
		url: '/dev-api/api/v1/project/type/list',
		method: 'get',
		response: ({ query }) => {
			const { ... } = query
			let list = ['default']
			// 根据条件生成list

			return {
				code: 0,
				msg: 'OK',
				data: {
					list,
					total: 2,
				},
			}
		},
	},
]
第二种: Restful Api/api/v1/project/:id,接口参数在后面
javascript 复制代码
[
	{
		url: /\/dev-api\/api\/v1\/project\/*/,
		method: 'delete',
		response: () => {
			return {
				code: 0,
				msg: 'OK',
				data: null,
			}
		},
	},
]
第三种: Restful Api/api/v1/project/:id/other/list,接口参数在中间
javascript 复制代码
	{
		url: /\/dev-api\/api\/v1\/project\/[^/]+\/other\/list/,
		method: 'get',
		response: () => {
			return {
				code: 0,
				msg: 'OK',
				data: Mock.mock({
					id: '@guid',
					name: '@string',
				}),
			}
		},
	}

接口字段映射

在我们写表单,写表格时都会绑定一个 prop 属性的值,该值对应的就是后端接口返回的 字段名;传参数时也是后端需要什么前端传什么,如果后端需要的时下划线的参数 project_name,安装前端的代码习惯都是 驼峰命名 的参数名,这时候你可以将驼峰转下划线。这里说一下更好的实践,那就是这一节的主题:接口字段的映射。将后端接口的响应数据,传给后端的请求参数,通过字段映射转换成前端需要的字段名和后端需要的参数名。

实现

src 中新建 field-map 文件夹,按模块新增对应的文件,比如 project.js。下面是具体代码

javascript 复制代码
import { mapRequestFields, formatDate } from '@/utils/common'

export const fieldMap = {
	name: 'name',
	description: 'description',
	creator: 'creator',
	createdAt: 'created_at',
}

// Format project list
export function formatList(data) {
	return (
		data?.map(item => ({
			id: item.id,
			name: item.name,
			description: item.description,
			creator: item.creator,
			createdAt: formatDate(item.created_at),
		})) || []
	)
}

export function formatQuery(params) {
	return mapRequestFields(params, fieldMap)
}
对象类型字段转换的翻转

如果需要将后端的响应对象转换成前端需要的字段名,或者在表格排序时需要将字段转换回去,可以通过下面的方式实现。其他更多的需求可以自己拓展

javascript 复制代码
export const fieldMapReverse = Object.keys(fieldMap).reduce((acc, key) => {
	acc[fieldMap[key]] = key
	return acc
}, {})

export function formatQuery(params) {
	return mapRequestFields(params, fieldMapReverse )
}
mapRequestFields的实现,对请求参数进行转换
javascript 复制代码
// 未实现嵌套的转换
export function mapRequestFields(obj, map) {
	const isFormData = obj instanceof FormData
	const mapFields = isFormData ? new FormData() : {}

	if (isFormData) {
		for (const [key, value] of obj.entries()) {
			if (value === 'undefined' || value === null || value === '') return
			const newKey = map[key] || key
			mapFields.append(newKey, value)
		}
	} else {
		Object.keys(obj).forEach(key => {
			if (obj[key] === 'undefined' || obj[key] === null || obj[key] === '') return
			const newKey = map[key] || key
			mapFields[newKey] = obj[key]
		})
	}

	return mapFields
}
相关推荐
前端郭德纲6 分钟前
深入浅出ES6 Promise
前端·javascript·es6
就爱敲代码11 分钟前
ES6 运算符的扩展
前端·ecmascript·es6
天天进步201527 分钟前
Lodash:现代 JavaScript 开发的瑞士军刀
开发语言·javascript·ecmascript
王哲晓32 分钟前
第六章 Vue计算属性之computed
前端·javascript·vue.js
假装我不帅36 分钟前
js实现类似与jquery的find方法
开发语言·javascript·jquery
究极无敌暴龙战神X39 分钟前
CSS复习2
前端·javascript·css
风清扬_jd1 小时前
Chromium HTML5 新的 Input 类型week对应c++
前端·c++·html5
Hadoop_Liang1 小时前
Docker Compose一键部署Spring Boot + Vue项目
vue.js·spring boot·docker
Ellie陈1 小时前
Java已死,大模型才是未来?
java·开发语言·前端·后端·python
GISer_Jing2 小时前
React面试常见题目(基础-进阶)
javascript·react.js·前端框架