更自动化更稳定的前后端交互模式
JavaScript本身的类型系统完全是runtime的
js是解释性语言(“非编译语言”又是不恰当的)
虽然有JIT可以很大程度优化速度问题
但一切质量问题都要线上来检验,这谁顶得住
async askForSomething function () {
const result = await askServer()
if (_.isString(result)) {
// 可能是字符串
return
}
if (_.isNumber(result)) {
// 也可能是数字
return
}
// 具体是类型依赖运行时的判断
if (_.isObject(result) && _.isFunction(someTool.alert)) {
// 所谓防御型编程就是要在运行时把所有的准备安排明白
// 从而让调用和取值安全
someTool.alert(result.msg || '未知消息')
return
}
}因为JavaScript变量类型的不确定,所以开发者需要依赖繁琐的防御型编程,无趣的类型转化,来保证变量可以正确的被使用,从而减少runtime error
由于JavaScript本身没有帮助开发者解决这个问题,特别是外部变量,规模大,语言相关(java vs golang?),不确定性更大,一般来说解决外部变量的类型安全性问题,内部变量的安全性问题也就迎刃而解了。更好的接口,解决的其实就是外部数据在JavaScript中的类型安全性问题。
从根基上稳固类型安全。
如果将前后端当做一个整体,那么接口调用的本质即为跨平台调用。在微服务体系中,IDL作为中立桥接,让平台间的调用更容易,更可靠。我也曾在前后端交互中使用IDL。
thrift IDL
java client stub code
go client stub code
py thrift service
编写protobuf描述文件
生成api架子
#!/bin/bash
export GOOS=darwin
export GOARCH=amd64
binpath="./bin"
echo "binpath="$binpath
if [ -n "$GOPATH" ]; then
# ...
# proto编译器protoc,有一个插件体系
# 分别调用不同的插件,以生成不同的代码
# protoc-gen-go用来生成golang的stub代码
# protoc-gen-tttool用来生成自定义架子,这个是内部自研的工具
${binpath}/protoc -I ./example/proto --plugin=${binpath}/protoc-gen-go # 一些参数
${binpath}/protoc -I ./example/proto --plugin=${binpath}/protoc-gen-tttool # 一些参数
else
echo "GOPATH is needed!"
fi
看看架子
func Add(
c *context.Context,
request pb_gen.ReqOfAdd
) (resp *pb_gen.RespOfAdd, err error) {
// Developer fill here
return &pb_gen.RespOfAdd{}, nil
}解析protoc-gen-go生成的文件,生成前端调用代码,先看看生成的go数据结构
解析方式是golang ast加模板,核心是生成TypeScript的结构定义。ts帮助开发者在compile阶段提前发现错误,以减少runtime error,再加上现代ide,可提升防御型编程的体验。
declare interface ITSUserInfo {
avatar_uri: string;
child: ITSChild | null;
...
gender: ITSGender;
klass_info: (ITSKlassInfo | null)[] | null;
...
}TypeScript运行在compile阶段,runtime阶段线上跑的仍然是JavaScript,ts对runtime错误束手无策,所以可以酌情加入runtime类型检测。
在绩效系统使用了mobx-state-tree,types.model限制了runtime阶段数据的类型,从根源掐住。Instance+typeof限制了compile阶段的类型,实现两个阶段校验的对称。
mobx-state-tree + typescript
唯一的接口定义 + 稳定的工具链 =
所谓的接口定义,唯一即可,甚至一段强类型语言的有规律的代码段,也可以用ast读取结构加模板生成目标代码。
JavaScript本身的变量类型系统完全是runtime的
提升项目效率
提升项目质量
IDL + 工具链
compile phase
runtime phase