Skip to content

Latest commit

 

History

History
190 lines (126 loc) · 5.67 KB

README-CN.md

File metadata and controls

190 lines (126 loc) · 5.67 KB

English Intro

Thrift2TS

Thrift作为服务间RPC通信的流行方案,其本身是一个类型定义语言(IDL),由于其语言无关性,即可以一次编写服务数据类型定义和方法接口文档,然后通过工具生成指定平台语言的可调用的RPC服务代码。

本工具将 Thrift (IDL) 文件解析并生成TypeScript文件,可以用作前端服务请求方法相关代码的类型文档,这样在编写调用RPC方法代码时可利用TypeScript强大的类型支持提高开发效率。

Thrift除了定义IDL,还有一套自己的数据传输方法和协议,以便在RPC客户端和服务端之间通信,因此本工具也添加了RPC服务客户端代码的生成支持,利用所有生成的代码文件,可以完成一整套的完全基于Thrift的RPC调用。

Thrift官方提供了JS的生成工具,那么本工具的存在主要是为了解决以下问题:

* 官方生成的JS文件,适用于浏览器端的使用了大量全局变量,没有模块导出,并不适合我们常规模块化开发时引入

* 官方生成的Node JS,适用于Node客户端,由于大量使用了浏览器端不支持的net/http/Buffer模块,无法直接在浏览器端使用

* 官方生成的JS文件,没有Call sequence支持,如果服务端响应时间不一,可能造成回调顺序错误,一个解决办法就是每次的RPC调用都重生成Service Client和Connection实例,但是我更希望特别是WebSocket的connection实例能够重用,即在一个WebSocket连接上发送多个RPC调用,避免频繁的TCP连接打开和关闭

* 官方生成的JS文件,因为没有类型支持,对开发时静态检查和提示不便,因此本工具全部生成TypeScript代码

关于Thrift

关于TypeScript

示例

Thrift2TS Demo Project

安装

npm

npm install thrift2ts -g

yarn

yarn global add thrift2ts

使用

CLI

t2t -i [thrift文件路径] -o [typescript文件输出目录] -r [request方法导入路径] -c

sample

t2t -i ./common.thrift -o ./services -r ./request -c

代码调用

var thrift2ts = require('thrift2ts').default;
var thriftCode = 'XXX';

var tsCode = thrift2ts(thriftCode, './request')

示例

Thrift

namespace java com.company.javabusz
namespace go com.company.gobusz

include "./Common.thrift"

enum EmployeeType {
	Junior = 0,
	Senior = 1,
	Manager,
	Director = 0xa
}

struct Employee {
	1:required string name;
	2:optional i32 age;
	3:required map<string, i32> tasks;
}

exception NetworkException {
	1:required i32 code;
	2:required string message;
	3:optional string url;
}

const i32 year = 2017

const list<string> languages = ['Java', 'Go', 'JavaScript']

const map<string, i32> lanAges = {'Java': 20, 'Go': 8, 'JavaScript': 16}

const bool happy = true

// This is a map definition
typedef map<string, number> EmployeesCatlog // a tail comment

service EmployeeOperator {
	list<Employee> QueryEmployee(1:i32 age)
}

service EmployeeSalaryOperator extends EmployeeOperator {
	bool OperateEmployeeSalaryByType(1:EmployeeType type, 2:i64 amount, 2:string note);
}

Convert to TypeScript

/**
 * Auto generated by Thrift2Ts.
 *
 * Mon Jun 19 2017 22:42:06 GMT+0800 (CST)
 */

import Request from "./request";

import * as Common from "./CommonService";

export const year: number = 2017; 

export const languages: string[] = ["Java", "Go", "JavaScript"]; 

export const lanAges: {[key: string]: number} = {"Java": 20, "Go": 8, "JavaScript": 16}; 

export const happy: boolean = true; 

export enum EmployeeType {
    Junior = 0,
    Senior = 1,
    Manager = 2,
    Director = 10
}

export interface NetworkException {
    code: number;
    message: string;
    url?: string;
}

export interface Employee {
    name: string;
    age?: number;
    tasks: {[key: string]: number};
}

export function QueryEmployee(age: number): Promise<Employee[]> {
    return Request<Employee[]>("EmployeeOperator.QueryEmployee", { age })
}

export function OperateEmployeeSalaryByType(type: EmployeeType, amount: number, note: string): Promise<boolean> {
    return Request<boolean>("EmployeeSalaryOperator.OperateEmployeeSalaryByType", { type, amount, note })
}


export default {
    QueryEmployee,
    OperateEmployeeSalaryByType
}

问题

要导入的Request是什么

本工具生成的文件包括一份RPC服务以及相关参数类型定义文档,这里会将Thrift的service下的所有方法转化为返回值为Promise的可直接引用的远程请求方法。为了灵活起见,代码不会实现如何去请求一个远端服务器。不论你用AJAX, Fetch抑或WebSocket网络请求方式,也不论你是用axios或者jQuery等哪一种网络请求库,或者说直接用本工具生成的Thrift Service Client搭配Thrift的数据传输协议,你直接提供实现了这些内容的模块的导入路径即可。

本代码中也提供了一些Request实现的例子

不使用Thrift数据传输协议和Thrift RPC Server
完整使用Thrift数据协议连接Thrift RPC服务端

必须

当要连接Thrift RPC服务时你必须导入 Browser Thrift 包, 它定义了 Thrift 数据传输协议。

这个包里面也有一份完整的使用本工具生成代码,并与Thrift RPC服务端通信的完整演示。