Apache Thrift - 接口定义语言



Apache Thrift 的接口定义语言 (IDL) 是一种声明式语言,用于定义数据和服务的结构,而与任何特定编程语言无关。

它使您能够以简单易读的格式描述数据类型、服务方法及其交互。然后,Thrift 编译器使用此 IDL 生成多种语言的代码,这些代码可用于实现和交互定义的服务。

Thrift IDL 结构

Thrift IDL 文件使用 .thrift 文件扩展名并遵循简单的语法。Thrift IDL 文件的基本结构包括数据类型、常量、枚举、结构体和服务的定义。

以下是 Thrift IDL 结构的简单分解

命名空间

命名空间有助于组织您的 IDL 定义并防止命名冲突。您可以使用 namespace 关键字为不同的编程语言定义命名空间。每个命名空间指令指定目标语言和相应的命名空间

namespace java com.example.thrift
namespace py example.thrift

在此示例中

  • namespace java com.example.thrift 定义了从 IDL 文件生成的 Java 代码的命名空间。
  • namespace py example.thrift 定义了从 IDL 文件生成的 Python 代码的命名空间。

数据类型

Thrift 支持多种基本数据类型,您可以使用它们来定义数据的结构。一些基本类型包括

  • bool: 布尔值(true 或 false)。
  • byte: 8 位整数。
  • i16: 16 位整数。
  • i32: 32 位整数。
  • i64: 64 位整数。
  • double: 双精度浮点数。
  • string: 字符串。
  • binary: 字节序列(用于原始数据)。

结构体

结构体用于定义具有命名字段的复杂数据类型。结构体中的每个字段都分配一个唯一的标识符 (ID) 并具有特定的数据类型。字段可以标记为 可选必需。以下是一个示例

struct User {
  1: i32 id
  2: string name
  3: bool is_active
}

在此 User 结构体中

  • 1、2 和 3 是用于序列化的字段 ID(唯一整数)。
  • i32、string 和 bool 是字段的数据类型。
  • id、name 和 is_active 是字段名称。

枚举

枚举(枚举的简称)用于定义一组命名常量。枚举中的每个常量都分配一个整数数值,默认从 0 开始。如果需要,您可以为常量指定自定义值。以下是一个示例

enum Status {
  ACTIVE = 1
  INACTIVE = 2
  PENDING = 3
}

在此 "Status" 枚举中

  • ACTIVE、INACTIVE 和 PENDING 是可能的值。
  • 每个值都与一个整数相关联。

联合体

在 Apache Thrift IDL 中,联合体是一种特殊类型的数据结构,它可以一次容纳多个可能的字段中的一个。

与可以同时容纳多个字段的结构体不同,联合体一次只能容纳一个字段。以下是一个示例

union Result {
  1: string message
  2: i32 errorCode
}

在此示例中

  • "Result" 是联合体的名称。
  • 它可以具有名为 "message" 的 "string" 字段或名为 "errorCode" 的 "i32" 字段,但不能同时具有两者。

定义服务

服务定义可以执行的操作以及公开的方法。每个服务都包含一个方法列表,每个方法都指定参数和返回类型。以下是一个示例

语法

以下是 Apache Thrift 中定义服务的基本语法

service ServiceName {
  <returnType> <methodName>(<parameterList>) throws (<exceptionList>)
}

这里,service 关键字后跟服务的名称。在花括号内,每个方法都定义了其返回类型、方法名称、参数列表以及可能引发的任何异常。

示例

在以下示例中,"UserService" 是一个具有两种方法的服务。 "getUserById" 采用 i32 ID 并返回 "User" 结构体。它可能引发 "UserNotFoundException"。 "updateUser" 采用 "User" 结构体并返回空值 (void)。

  • getUserById 接受一个 i32 ID 并返回一个 User 结构体。
  • updateUser 接受一个 User 结构体并返回空值 (void)。
service UserService {
  User getUserById(1: i32 id) throws (1: UserNotFoundException e)
  void updateUser(1: User user)
}

定义异常

异常用于处理在服务方法调用期间发生的错误。您可以像结构体一样定义它们,但使用 exception 关键字

语法

以下是 Apache Thrift 中定义异常的基本语法

exception ExceptionName {
  1: <type> <fieldName>
}

这里,exception 关键字后跟异常的名称。在花括号内,异常的每个字段都定义了唯一的整数 ID、数据类型和字段名称。

示例

在以下示例中,"UserNotFoundException" 是一个具有一个字段的异常,"message" 是一个带有 ID 1 的字符串,它保存错误消息

exception UserNotFoundException {
  1: string message
}

Apache Thrift 中的容器

在 Apache Thrift IDL 中,容器用于将多个值组合在一起。它们有三种类型:列表、集合和映射。每种类型都有不同的用途,并且具有其自身的特性

  • 列表: 元素的有序集合,允许重复。以下为语法示例 -
  • list<string> names
    

    这定义了一个名为 "names" 的列表,其中每个元素都是一个 "string"。

  • 集合: 元素的无序集合,不允许重复。以下为语法示例 -
  • set<i32> numbers
    

    这定义了一个名为 "numbers" 的集合,其中每个元素都是一个 32 位整数 (i32)。

  • 映射: 键值对的集合,每个键都是唯一的。键和值可以是不同的类型。以下为语法示例 -
  • map<string, i32> ageMap
    

    这定义了一个名为 "ageMap" 的映射,其中每个键都是一个 "string"(例如,人的姓名),每个值都是一个 "i32"(例如,他们的年龄)。

广告