头图

常见 API

创建新的学生资料的接口如下:

Request

POST /students HTTP/1.1
Host www.school.com
Content-Type application/json

{
    "name": "tom",
    "age": 12,
    "ethnicity": "HAN"
}

Response

HTTP/1.1 200 OK
Content-Type: application/json;charset=UTF-8

{
    "code": 0,
    "message": "success",
    "data": {
        "id": 1,
        "name": "tom",
        "age": 12,
        "ethnicity": "HAN"
    }
}

包含 name \ age \ ethnicity 三个参数,其中 ethnicity 民族,需要做检查以避免输入系统无法处理的内容。

例如,前端需要将民族本地化为中文,系统不支持的民族就无法本地化为中文。

如果只有中国的 56 个民族,使用常量或者枚举都可以,实践中一般会选着使用枚举:

public enum Ethnicitiy {
    //汉族
    HAN,
    //蒙古族
    MONGOL, 
    // ... 
    //基诺族
    JINO;
}
枚举中没有设置字段存储中文含义,是为了将编码和本地化解耦。如果只有单一语言需求,请随意

Spring Web 模块默认支持枚举反序列化,错误的数据将导致反序列化失败,这样就达到了检查参数的目的

数据耦合

这样的方式能实现功能,但是会使得数据和代码耦合。例如,需要新增一个 其他 other 选项,就需要更新代码并发布新版本

很多时候还会在前端存在类似的问题。例如,后端定义了枚举之后,APP 为了本地化显示会在代码中耦合类似枚举的数据。增加新的 其他 other 选项之后,后端和 APP 都需要发布新版本,但是 APP 是否升级是由用户选择的,如果选择强制升级会严重影响用户体验。

数据和代码的耦合,最明显的缺点就是修改数据需要修改代码。更通用的解释: 数据本身的含义不完整,必须依靠代码才能理解数据的含义

数据和代码耦合会造成数据通用性低,更换后端实现更复杂,数据分析依赖于业务代码。以及,前端对接工作量增加

使用数据字典解耦

将服务器代码中的枚举转换成数据字典存入数据库,新增数据时只需要在数据库中添加记录即可

字典表 t_dict 存储民族数据如下:

idancestorscodecomment
1nullethnicitiesGB3304-91, 民族
21han汉族
31mongol蒙古族
............
571jino基诺族
注意,comment 是每行数据的注释,不能用于序列化或者本地化

01 \ 1 \ han \ HA 都可以作为编码,他们是等价的,在使用上没有区别。
例如,自定饮酒量标准如下:

idancestorsletter_codenumber_codecomment
11nullfreq_of_drinking11自定义标准,饮酒频率
1211few1少量
1311several2中等
1411many3大量
一部分情况下,如果使用字符编码,英文母语开发者可以省略备注,非英文母语开发者需要备注说明编码含义

编码 Encode

客户端遵循协议获取字典数据,将用户输入参数编码之后传给服务端

sequenceDiagram
participant c as Client 
participant s as Server
autonumber

c ->> s: Request dicts
s -->> c: Response dicts
c ->> c: Encode input parameters according to dicts
c ->> s: Submit data
s ->> s: Check if dicts is valid
s -->> c: Response OK

本地化 Localization

也叫解码 Decode,支持解码为多种语言就可以称之为本地化(与国际化同义)

服务端本地化

sequenceDiagram
participant c as Client 
participant s as Server
autonumber

c ->> s: Request data
s ->> s: Localize when decoding dicts
s -->> c: Response data

Request

请求时指定接受的语言

GET /students/1 HTTP/1.1
Host www.school.com
Accept: application/json
Accept-Language: zh-CN

Response

HTTP/1.1 200 OK
Content-Type: application/json;charset=UTF-8

{
    "id": 1,
    "name": "tom",
    "age": 12,
    "ethnicity": "汉族"
}

客户端端本地化

sequenceDiagram
participant c as Client 
participant s as Server
autonumber

c ->> s: Request data 
s -->> c: Response data
c ->> s: Request localization resoruces
s -->> c: Response localization resoruces
c ->> c: Localize when decoding dicts
请求数据

请求时指定接受的语言

GET /students/1 HTTP/1.1
Host www.school.com
Accept: application/json
HTTP/1.1 200 OK
Content-Type: application/json;charset=UTF-8

{
    "id": 1,
    "name": "tom",
    "age": 12,
    "ethnicity": "han",
    "link_ethnicity_resources": "https://www.school.com/resources/localzations/ethnicities"
}
获取本地化资源
GET /resources/localzations/ethnicities HTTP/1.1
Host www.school.com
Accept: application/json
Accept-Language: zh-CN

根据请求的语言返回对应的本地化资源

HTTP/1.1 200 OK
Content-Type: application/json;charset=UTF-8

{
    "han": "汉族",
    "mongol": "蒙古族",
    // ...
    "jino": "基诺族"
}

结尾

将数据和代码解耦,将本地化和编解码解耦,可以更好的支持变化的数据和需求。


等灯的邓
19 声望0 粉丝