某前后端分离项目,如何传递参数?

1. 只有一个简单业务实体

假设有一个编辑简历的功能,页面元素很简单,只有:姓名、年龄。数据格式为:application/json。

1.1 初次提交

请求参数

{
  "age": 29,
  "name": "张三"
}

响应参数

{
  "id": 386
}

1.2 编辑后提交

请求参数
前端需要传递id或uuid这类唯一标识到后端。如果不传递:

  1. 如果业务上规定,一个用户只能有一个简历,那就简单了。
  2. 如果业务上规定,一个用户可以有多个简历,例如面试政府部门的简历,面试互联网公司的简历等,那后端就无从下手,不知道该更新哪个了。

所以,再次编辑后提交,需要携带id。

{
  "id": 386
  "age": 30,
  "name": "张三"
}

响应参数

{
  "id": 386
}

2. 一个业务实体,并且同时1对多关联其他业务实体

在编辑简历的同时,也编辑教育信息。

2.1 初次提交

请求参数

{
  "name": "张三",
  "age": 29,
  "eduList": [
    {
      "colleague": "高校1",
      "major": "专业1"
    },
    {
      "colleague": "高校2",
      "major": "专业2"
    },
    {
      "colleague": "高校3",
      "major": "专业3"
    }
  ]
}

响应参数
问题来了,如何表征多个教育信息在数据库表里的id值呢?这个id很重要,删除或更新教育信息时需要用到。

  1. 最简单的方式,重新加载整个页面信息,显然,加载后所有实体都有id。但是,比较浪费带宽。
  2. 可以考虑前端为每个教育信息生成一个临时唯一标识,响应时携带这个临时唯一标识,这样前端就可以对号入座,根据frontEndUuid的值,设置后端生成的真正的id值了,之后抛弃frontEndUuid。
    改进后请求参数
{
  "name": "张三",
  "age": 29,
  "eduList": [
    {
      "frontEndUuid": "xxxx",
      "colleague": "高校1",
      "major": "专业1"
    },
    {
      "frontEndUuid": "xxxx",    
      "colleague": "高校2",
      "major": "专业2"
    },
    {
      "frontEndUuid": "xxxx",    
      "colleague": "高校3",
      "major": "专业3"
    }
  ]
}

改进后响应参数

{
  "id": xxx,
  "eduList": [
    {
      "frontEndUuid": "xxxx",
       "id": xxx
    },
    {
      "frontEndUuid": "xxxx",    
       "id": xxx
    },
    {
      "frontEndUuid": "xxxx",    
       "id": xxx
    }
  ]
}

2.2 查询并编辑后提交

查询的响应参数

{
  "id": xxx,
  "name": "张三",
  "age": 29,
  "eduList": [
    {
      "id": "xxxx",
      "colleague": "高校1",
      "major": "专业1"
    },
    {
      "id": "xxxx",    
      "colleague": "高校2",
      "major": "专业2"
    },
    {
      "id": "xxxx",    
      "colleague": "高校3",
      "major": "专业3"
    }
  ]
}

问题来了,编辑后如何表征哪些教育信息是新增的,哪些是被修改的,哪些是被删除的?可以考虑:
【方法1】

  • 新增的,为新增的教育信息新增一个变量:newEduList
  • 修改的,为修改的(无变化的视为修改的)教育信息新增一个变量:modifiedEduList
  • 删除的,为删除的教育信息新增一个变量:delEduList

【方法2】
不新增变量,只使用eduList这一个变量:

  • 无论用户作何操作,全都把页面上呈现的教育信息封装到eduList,并传递到后端。
  • 将传入eduList记为A,数据库中的eduList集合(例如select id from t_edu_info where userId = ?)记为B。
  • 新增的教育信息:A中edu的id为空的。
  • 无变化的及修改的教育信息:A与B的交集。
  • 删除的:B-A。

【方法3】
不新增变量,只使用eduList这一个变量:

  • 如果eduList为null,表示教育信息无变化,后端可以忽视之。
  • 如果eduList的大小为0,则表示客户端已删除了所有实体,无新增和修改。以下内容仅针对eduList大小大于0的情况:
  • 将传入eduList记为A,数据库中的eduList集合(例如select id from t_edu_info where userId = ?)记为B。
  • 新增的教育信息:A中edu的id为空的。
  • 无变化的及修改的教育信息:A与B的交集。
  • 删除的:B-A。
方法1方法2方法3
优点数据模型很清晰,后端代码整洁。变量少,前端工作量少些。对方法2的改进
缺点变量较多,前端工作量大些。后端对前端的操作不甚明了,计算新增的、修改的和删除的,一个也不能少,即使用户没有任何编辑行为。

方法1请求参数举例(方法2和方法3略)

{
  "id": xxx,
  "name": "张三",
  "age": 30,
  "newEduList": [
    {
      "frontEndUuid": "xxxx",
      "colleague": "高校4",
      "major": "专业4"
    }
  ],
  "modifiedEduList": [
    {
      "id": "xxxx",    
      "colleague": "高校2-更新",    <====== 这是修改的
      "major": "专业2-更新"
    },
    {
      "id": "xxxx",                <====== 这里并没有修改,但后端仍可以按此数据进行更新
      "colleague": "高校3",
      "major": "专业3"
    }
  ],
  "delEduList": [
    {
      "id": "xxxx"
    },
    {
      "id": "xxxx"
    }    
  ]  
}

2.3 粗暴的处理方法

无论新增还是编辑,对教育信息每次都先删除数据库中的数据,再按全新数据插入。弊端是无效的垃圾数据较多。

2.4 关于“多”的那个实体数据的删除问题

上例中,显然需要新增一个表来保存教育信息。编辑简历时,如果前端删除了某条教育信息,对应数据库里也删除就可以了。考虑这种场景:

  • 新增“照片”业务实体,一个简历里可以关联1或多个照片。
  • 为了节省存储空间,N张照片在数据库里最多保存N行记录(列名可能包括:照片名称、照片格式、照片二进制数据信息)。
  • 某一张照片可能被多个简历关联了,但不能重复保存该照片信息。当然了,关联表可以有多条记录(列名可能包括:简历ID、照片ID)。

修改简历或删除简历时,不能像删除教育信息一样,删除照片数据,只能删除简历与照片的关联表数据。应该在照片管理功能里上传新照片或删除照片。删除照片时,如果照片被引用了,要提示用户:一旦删除照片,那些引用该照片的简历里,也将一并被删除。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值