TSRPC 作为一个专门为 TypeScript 设计的 RPC (远程过程调用) 框架,通过它的介绍可以看出,它旨在解决前后端通信中的一系列常见问题,如沟通成本高、类型安全缺失、数据类型支持有限、安全性问题、技术框架不兼容、平台差异以及缺乏对 TypeScript 高级类型的支持等。通过提供一系列创新特性,TSRPC 旨在提升开发效率,确保类型安全,同时支持更多数据类型的传输,包括二进制数据,以及提供对 Serverless 架构的支持。
其实吧,看官网的入门比我这个文章强。至于当初为什么写,现在为什么要发出来?刚好最近又用到了,但是好多东西还要重新看文档再理解。
啊?这,不是现成的机会吗?[手动狗头]
关键特性
- 类型安全:通过 TypeScript 的类型系统,实现编译时的类型校验,减少运行时错误。
- 支持二进制传输:提高数据传输效率和安全性。
- 跨平台兼容:支持浏览器、小程序、Node.js 等多个平台,方便构建全栈应用。
- Serverless 支持:适配多种云平台的 Serverless 架构,简化部署和运维。
- 一键生成接口文档:自动化文档生成,提高开发效率和接口透明度。
- 多协议支持:同时支持 HTTP 和 WebSocket,满足不同场景的需求。
创建项目
首先,确保你有 NodeJS 12 或以上版本。你可以通过运行 node -v 来检查你的 NodeJS 版本。
写文章时候用的版本是18,小版本忘了
使用 create-tsrpc-app 脚手架工具来创建一个新的 TSRPC 项目。你可以选择使用 npx 或 yarn 来执行这个命令:
npx create-tsrpc-app@latest
# 或者
yarn create tsrpc-app
这个命令会启动一个交互式的会话,让你选择一些基本的配置选项,比如项目名称和是否包含某些特性或依赖。
前端yarn失败问题不大,进目录再看看,估计也没啥大问题
项目结构
创建完项目后,你会得到一个包含前后端的全栈项目结构,大致如下:
# 查看当面目录,指定10层深度 忽略了俩目录
/UserHub$ tree -l 10 --ignore node_modules --ignore .svcode
▅
/project/blog/UserHub
├── backend
| ├── Dockerfile
| ├── README.md
| ├── package.json
| ├── src
| | ├── api
| | | ├── ApiAddData.ts
| | | └── ApiGetData.ts
| | ├── index.ts
| | └── shared
| | └── protocols
| | ├── PtlAddData.ts
| | ├── PtlGetData.ts
| | ├── base.ts
| | └── serviceProto.ts
| ├── test
| | ├── api
| | | └── data.test.ts
| | └── tsconfig.json
| ├── tsconfig.json
| ├── tsrpc.config.ts
| └── yarn.lock
├── frontend
| ├── README.md
| ├── babel.config.js
| ├── package.json
| ├── public
| | ├── favicon.ico
| | └── index.html
| ├── src
| | ├── App.less
| | ├── App.vue
| | ├── client.ts
| | ├── env.d.ts
| | ├── main.ts
| ├── tsconfig.json
| └── vue.config.js
└── vetur.config.js
directory: 494 file: 5356 symboliclink: 1
ignored: directory (17)
简单解释一下这些目录和文件
后端(backend)
-
Dockerfile: 用于创建 Docker 容器的配置文件,可以让应用容易地在不同环境中部署和运行。 -
README.md: 通常包含项目的基本信息、安装指南、使用方法等。 -
package.json: 定义了项目的依赖库、脚本命令和其他配置信息。 -
src: 源代码目录。 -
api: 存放具体的 API 实现文件,例如ApiAddData.ts和ApiGetData.ts,这些文件通常包含处理客户端请求的逻辑。 -
index.ts: 项目的入口文件,用于启动服务。 -
shared: 存放前后端共享的代码,如协议定义。protocols: 包含 TSRPC 协议定义文件,如PtlAddData.ts和PtlGetData.ts,这些文件定义了 API 请求和响应的数据结构。
-
test: 包含测试代码,用于对 API 进行单元测试或集成测试。 -
tsconfig.json: TypeScript 的配置文件,定义了编译选项和项目设置。 -
tsrpc.config.ts: TSRPC 框架的配置文件,可以在这里配置 TSRPC 的行为,如设置协议路径、启用二进制传输等。
前端(frontend)
-
README.md: 通常包含前端项目的基本信息、安装指南、使用方法等。 -
babel.config.js: Babel 的配置文件,用于将 ES6+ 代码转换为向后兼容的 JavaScript 代码。 -
package.json: 定义了前端项目的依赖库、脚本命令和其他配置信息。 -
public: 存放静态资源文件,如favicon.ico和index.html。 -
src: 前端项目的源代码目录。App.less: 定义了 Vue 应用的样式。App.vue: Vue 应用的根组件。client.ts: TSRPC 客户端的初始化和配置,用于与后端进行通信。env.d.ts: TypeScript 的环境声明文件,用于声明全局变量类型。main.ts: 前端应用的入口文件,用于初始化 Vue 应用。
-
tsconfig.json: TypeScript 的配置文件,定义了编译选项和项目设置。 -
vue.config.js: Vue CLI 的配置文件,可以自定义 Vue 项目的构建和开发服务器等设置。 -
vetur.config.js: Vetur 插件的配置文件,用于在 Vue 项目中提供更好的开发体验,如语法高亮和代码自动完成。
刚刚自动安装依赖的时候不是报错了吗?我们再去前端项目中试一下
cd frontend
yarn
warning @vue/cli-service > @intervolga/optimize-cssnano-plugin > cssnano-preset-default > postcss-svgo > svgo > stable@0.1.8: Modern JS already guarantees Array#sort() is a stable sort, so this library is deprecated. See the compatibility table on MDN: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort#browser_compatibility
[2/4] Fetching packages...
error @achrinza/node-ipc@9.2.2: The engine "node" is incompatible with this module. Expected version "8 || 10 || 12 || 14 || 16 || 17". Got "18.17.1"
error Found incompatible module.
info Visit https://yarnpkg.com/en/docs/cli/install for documentation about this command.
plyue@/home/blog/UserHub/frontend$ npm ls @achrinza/node-ipc
UserHub-frontend@0.1.0 /media/plyue/662C8A672C8A31DB6/project/blog/UserHub/frontend
└── (empty)
本人没文化,这个包@achrinza/node-ipc不认识也不知道这个是用了做进程通信的。
这个错误大概的意思是,这个包和我本地的node18,作为一个没有安装过NVM的程序员我决定略过它
npm i
# balabala
added 1532 packages in 20s
146 packages are looking for funding
run `npm fund` for details
对,世上无难事只要肯放弃嘛,解决问题😸
运行项目
要运行项目,你需要分别在前端和后端目录下启动开发服务器:
# 启动后端服务
cd backend
npm run dev
# 启动前端服务
cd frontend
npm run dev
这会启动本地开发服务器,并且当你修改代码并保存时,服务器会自动重启,让你能实时看到变化。
构建项目
当你准备将你的应用部署到生产环境时,你需要构建你的项目。这可以通过在前端和后端项目下运行构建命令完成:
# 构建后端
cd backend
npm run build
# 构建前端
cd frontend
npm run build
构建完成后,输出的文件会放在各自项目的 dist 目录下,这些文件是准备好的生产环境代码,可以直接部署。
小贴士
- 建议总是先启动后端服务,再启动前端服务,这样可以确保前端能正确地与后端通信。
- 如果你遇到任何问题,可以查看
create-tsrpc-app的帮助信息,或者访问 TSRPC 的官方文档和社区寻求帮助。
实现API接口
使用 TSRPC 开发 API 接口前,必须先了解几个重要的概念。
- API 接口
- API 接口就相当于一个实现在远端的异步函数
- 这个函数的输入参数叫做 请求(Request),返回值叫做 响应(Response)
- 协议(Protocol)
- API 接口的类型定义,包括它的请求类型和响应类型
- 实现函数(Implementation)
- API 接口的功能实现,接收请求并返回响应
- 服务端(Server)
- API 接口的实现端,NodeJS 12 以上
- 客户端(Client)
- API 接口的调用端,支持多个平台,如浏览器、小程序前端,或是 NodeJS 后端微服务调用
实现一个 API 接口,只需要 3 个步骤: 定义协议 -> 服务端实现 -> 客户端调用。
定义协议
1 个接口对应 1 个协议文件,TSRPC 按照命名来识别,规则如下:
-
协议文件命名为
Ptl{接口名}.ts,统一放置在backend/src/shared/protocols下,允许子目录嵌套 -
协议包含请求类型
Req{接口名}及响应类型Res{接口名}- 通过 TypeScript 的
interface或type定义
- 通过 TypeScript 的
-
API 接口的实际请求路径为
{协议路径}/{接口名}- 协议路径:协议文件于协议目录的相对路径
定义协议是实现 API 接口的第一步,需要在 backend/src/shared/protocols 目录下创建对应的协议文件(例如 PtlLogin.ts)。这个文件中需要定义请求(ReqLogin)和响应(ResLogin)的类型。
在backend/src/shared/protocols/user/PtlLogin.ts新建协议文件后tsrpc会自动在新文件内给出默认内容
// backend/src/shared/protocols/user/PtlLogin.ts
// 请求
export interface ReqLogin {
username: string;
password: string;
}
// 响应
export interface ResLogin {
user: {
id: number;
nickname: string;
};
}
服务端实现
在服务端,每个 API 接口对应一个实现函数。这些函数通常位于 backend/src/api 目录下,并遵循一定的命名规则(例如 ApiLogin.ts)。
// backend/src/api/user/ApiLogin.ts
import { ApiCall } from "tsrpc";
export async function ApiLogin(call: ApiCall<ReqLogin, ResLogin>) {
if (!(call.req.username === 'admin' && call.req.password === 'admin')) {
call.error('用户名或密码错误');
return;
}
call.succ({
user: {
id: 123,
nickname: 'Test'
}
});
}
客户端调用
在客户端,使用 TSRPC 提供的客户端库(例如 tsrpc-browser)来调用远端 API,享受完整的代码提示和类型检查。
// 客户端示例代码
import { HttpClient } from 'tsrpc-browser';
import { serviceProto } from './shared/protocols/serviceProto';
const client = new HttpClient(serviceProto, {
server: 'http://127.0.0.1:3000',
json: true
});
async function login() {
let ret = await client.callApi('user/Login', {
username: 'admin',
password: 'admin'
});
if (!ret.isSucc) {
console.log('登录失败', ret.err.message);
return;
}
console.log('登录成功', ret.res.user);
}
TSRPC 通过其类型安全的设计,让前后端开发者可以更加专注于业务逻辑的实现,而不是通信细节。它提供的客户端库和服务端框架简化了 API 的调用和实现过程,同时保持了高度的灵活性和扩展性。通过使用 TypeScript 的类型系统,TSRPC 还能确保接口的输入和输出在编译时就已经得到了校验,极大地提升了开发效率和代码质量。
说人话,就是我觉得最大的好处就是让全干工程师干起活儿来更嗨皮