thrift接口描述语言 (基于thrift 0.13.0版本)

thrift接口描述语言(IDL)用来定义thrift类型. 一个Thrift IDL文件用来生成各种语言使用的结构体和服务.

 

IDL中包含如下部分:

1. Document

Document中包含0或者多条如下的声明:

(1) include Literal

Thrift Include: 用来导入其他thrift中的符号, 在这个thrift中使用导入的thrift中的符号时, 需要带一个前缀.这个thrift编译时, 被导入thrift的对应头文件会被插入到这个thrift编译的相应文件中.

说明: Literal表示字符串常量, 写法要求有可选值(其中*表示0或者多个字符):

1) “[^”]*” (其中[^”]表示不为双引号的字符)

2) ‘[^’]*’ (其中[^’]表示不为单引号的字符)

示例: include "xxx.thrift"

(2) cpp_include Literal

C++ Include: 用来在这个thrift编译生成的文件中添加Literal头文件.

示例: cpp_include "xxx.h"

(3) namespace NamespaceScope Identifier

Namespace: 一个namespace表示一个命名空间//模块等, 含义基于编译成的目标语言, 其中C++中表示命名空间名, golang中表示包名. NamespaceScope表示对应的编程语言, 如果使用*, 则表示对所有的语言都使用同样的Namespace.

说明:

(1) NamespaceScope可以使用如下值取代: *, c_glib, cpp, csharp, delphi, go, java, js, lua, netcore, perl, php, py, py.twisted, rb, st, xsd.

(2) Identifier允许的写法(其中|表示或的关系, *表示出现0次或者多次): (Letter|_)(Letter | Digit | . | _ | -)*.

(3) Letter表示A-Z或者a-z中的一个字符.

(4) Digit表示0-9中的一个数字.

示例: namespace cpp tutorial

 

2. Definition

 Definition包含如下的多条定义:

(1) const FieldType Identifier = ConstValue ListSeparator?

说明: ?表示可选, 其中ListSeparator包括两个可选值: (1) ,(逗号) (2);(分号)

用来定义一个常量, 可以参考如下示例:

const i32 INT32CONSTANT = 9853
const map<string,string> MAPCONSTANT = {'hello':'world', 'goodnight':'moon'}

(2) typedef DefinitionType Identifier

用来定义一个类型的别名, 其中DefinitionType包括可选值: (1) BaseType (2) ContainerType, BaseTypeContainerType的说明见后文, 关于定义别名, 可以参考如下示例:

typedef i32 MyInteger

(3) enum Identifier { (Identifier (= IntConstant)? ListSeparator?)* }

说明: 其中的*表示多条

用来定义一个枚举类型. 如果枚举结构体内的标识符没有提供常量, 那么第一个元素取0, 对于后续元素会比前一个元素大1. 所有提供的常量都必须是非负的. 可以参考如下示例:

enum Operation {
  ADD = 1,
  SUBTRACT = 2,
  MULTIPLY = 3,
  DIVIDE = 4
}
/**
 * Common status reporting mechanism across all services
 */
enum fb_status {
  DEAD = 0,
  STARTING = 1,
  ALIVE = 2,
  STOPPING = 3,
  STOPPED = 4,
  WARNING = 5,
}

(4) senum Identifier { (Literal ListSeparator?)* }

: 和slist都是deprecated, 都使用string来代替.

(5) struct Identifier { Field* }

用来定义复合类型, struct中的每个成员名都需要是唯一的, 可以参考如下示例:

 struct Work {
  1: i32 num1 = 0,
  2: i32 num2,
  3: Operation op,
  4: optional string comment,
}

(6) union Identifier { Field* }

用来定义union类型, union类型中的所有成员只有一个成员有值, 当设置另一个成员时, 就只会有那个成员有值, 这个类型类似于C++中的union. 所以, union中的成员都默认为可选的(查看requiredness). 可以参考如下示例:

union Dessert  {
  1: string port
  2: string iceWine
}

(7) exception Identifier { Field* }

用来定义一个异常. exception中的每一个成员都需要是唯一的.

/**
 * Structs can also be exceptions, if they are nasty.
 */
exception InvalidOperation {
  1: i32 whatOp,
  2: string why 
}

(8) service Identifier (extends Identifier)? { Function* }

用来定义使用thrift的服务器的函数接口. 一个服务可以扩展(extend)其他的服务, 那么这个服务就可以提供被扩展服务的函数接口. 关于服务的一个简单示例:

/**
 * Standard base service
 */
service FacebookService {

  /**
   * Returns a descriptive name of the service
   */
  string getName(),

  /**
   * Returns the version of the service
   */
  string getVersion(),

  /**
   * Gets the status of this service
   */
  fb_status getStatus(),

  /**
   * User friendly description of status, such as why the service is in
   * the dead or warning state, or what is being started or stopped.
   */
  string getStatusDetails(),

  /**
   * Gets the counters for this service
   */
  map<string, i64> getCounters(),

  /**
   * Gets the value of a single counter
   */
  i64 getCounter(1: string key),

  /**
   * Sets an option
   */
  void setOption(1: string key, 2: string value),

  /**
   * Gets an option
   */
  string getOption(1: string key),

  /**
   * Gets all options
   */
  map<string, string> getOptions(),

  /**
   * Returns a CPU profile over the given time interval (client and server
   * must agree on the profile format).
   */
  string getCpuProfile(1: i32 profileDurationInSec),

  /**
   * Returns the unix time that the server has been running since
   */
  i64 aliveSince(),

  /**
   * Tell the server to reload its configuration, reopen log files, etc
   */
  oneway void reinitialize(),

  /**
   * Suggest a shutdown to the server
   */
  oneway void shutdown(),

}

下面解释一下上面出现的FieldFunction.

Field

Field的定义如下:

IntConstant : FieldReq? FieldType Identifier (= ConstValue)? ListSeparator?

其中FieldReq可选值包括: (1) required (2) optional (3) 如果没有指定, 则为default.

(1) required表示这个字段是必需的.

(2)  optional 表示这个字段是可选的.

大多数语言使用推荐的”isset”标志来标示optional的成员有没有被设置值.

(3) default

defaultoptionalrequired的混合,因此内部名为”opt-in,req-out”. 虽然理论上这些字段都会被写入(“req-out”), 实际上未被设置的字段总是不会写入. 尤其是, 结构体中的某个字段根据定义包含不能通过thrift发送的值. 这种情况下,唯一能够采取的方式,就是根本不写入这个值.

关于默认值特定要注意的是, 任何没有显示写入的默认值, 会随着接口定义而改变, 而将默认值写入到output, IDL改变默认值,不会对这个产生影响.

FieldType说明:

  1. FieldType包括可选值: (1) Identifier (thrift中定义的struct, union) (2) BaseType (3) ContainerType

  2. BaseType包括可选值: bool, byte, i8, i16, i32, i64, double, string, binary, slist

  3. ContainerType包括可选值:

    (1) map (cpp_type Literal)? <FieldType, FieldType>

    (2) set (cpp_type Literal)? <FieldType>

    (3) list<FieldType> (cpp_type literal)?

ConstValue包括如下可选值(其中+号表示1个或者多个, |表示或的关系):

(1) IntConstant: (+ | -)? Digit+

(2) DoubleConstant: (+ | -)? Digit* (.Digit+)? ( (E | e) IntConstant)?

(3) ConstList: [ (ConstValue ListSeparator?)*]

(4) ConstMap: { (ConstValue : ConstValue ListSeparator?)* }

 

Function:

Function的定义格式: oneway? (FieldType | void) Identifier (Field*) (throws (Field*))?  ListSeparator?

其中涉及的FieldType, Identifier, Field等的定义, 参考上面的说明.

 

posted on 2019-05-10 10:33  月落无影  阅读(2492)  评论(0编辑  收藏  举报