跳转到内容

HTTP RFC

本页定义 XIDL interface 到 HTTP API 的核心映射规则,包括:

  • 方法和路由映射
  • 参数来源解析
  • 请求/响应编码
  • attribute 映射

本页不讨论 OpenAPI 生成细节,也不承担教程角色。

本 RFC 主要覆盖:

  • HTTP 动词和路径注解
  • 路由模板解析
  • 参数来源优先级
  • 请求体与响应体整形
  • in / out / inout 的 HTTP 语义
  • @get(path = "...")
  • @post(path = "...")
  • @put(path = "...")
  • @patch(path = "...")
  • @delete(path = "...")
  • @head(path = "...")
  • @options(path = "...")
  • @path @rename("...")
  • @Consumes("mime/type")
  • @Produces("mime/type")
  • @cors(...)
  • @deprecated
  • @path
  • @query
  • @body
  • @header
  • @cookie
  • @flatten
  • @optional

规则:

  • 一个方法只能有一个 HTTP 动词注解
  • 没有显式动词时,默认等价于 @post
  • 路径既可以来自动词注解里的 path,也可以来自方法级 @path(...)
  • 多个路径声明会合并,规范化后去重

支持:

  • /users/{id}
  • /files/{*path}
  • /users/{id}{?lang,region}

语义:

  • {name}:普通路径变量
  • {*name}:捕获尾部多段路径
  • {?a,b}:声明查询参数名

在冲突检测和实际绑定前,所有路由都会先规范化:

  1. 去掉首尾空白
  2. 保证以 / 开头
  3. 合并重复 /
  4. 去掉末尾多余 /
  5. 保持大小写,不自动改写段内容

当方法没有显式路径时:

  1. /{method_name} 作为基础路径
  2. 按声明顺序追加所有 Path 参数
  3. Query 参数不参与路径模板生成

例如:

void findUser(@path uint32 id, @query string locale);

会得到:

POST /findUser/{id}

每个参数按以下优先级解析来源:

  1. 显式 @path
  2. 显式 @query
  3. 显式 @body
  4. 显式 @header
  5. 显式 @cookie
  6. 根据 HTTP 方法和方向做默认推断

默认推断实践:

  • GET / DELETE / HEAD / OPTIONS 的未标注请求参数通常进入 Query
  • POST / PUT / PATCH 的未标注请求参数通常进入 Body

方向规则:

  • in:只参与请求侧
  • out:只参与响应侧
  • inout:两边都参与

HTTP 映射中最常见的理解方式:

  • 请求侧参数决定路径、查询、头、Cookie、Body
  • 响应侧由返回值和 out / inout 参数共同决定

@head 有额外约束:

  • 返回类型必须是 void
  • 只能包含请求侧参数
  • 响应不包含内容体

@Consumes@Produces 分别定义:

  • 请求体解码格式
  • 响应体编码格式

序列化规则如下:

  • 默认情况下,原生类型(如 string, int32, bool 等)直接按其原始值的文本形式编码。
  • 复合类型(如 struct, union, sequence, map)默认采用 application/json 格式。

接口级注解作为默认值,方法级注解覆盖接口级配置。

@cors 用来声明跨域资源共享(CORS)策略,作用对象是接口或方法。

建议把它理解成“为这组 HTTP 路由附加一份跨域响应策略”。

建议支持两种基础写法:

  • @cors:无条件开启 CORS
  • @cors("https://app.example.com", "https://admin.example.com"):只接受这些来源

例如:

@cors
interface UserApi {
@get(path = "/users/{id}")
string getUser(@path @rename("id") string id);
@cors("https://admin.example.com", "https://console.example.com")
@post(path = "/users")
void createUser(string name);
};

其中:

  • @cors 表示该接口或方法接受任意来源的跨域访问
  • @cors("...", "...") 表示该接口或方法只接受列出的 Origin
  • 多个字符串参数表示一个来源白名单

继承和覆盖规则建议如下:

  • 接口级 @cors 作为默认策略
  • 方法级 @cors 覆盖接口级默认策略
  • 如果方法没有声明 @cors,则继承接口级配置

上面的例子里:

  • getUser 继承接口级 @cors,因此无条件开启 CORS
  • createUser 使用自己的方法级 @cors("...", "...")
  • createUser 的最终策略应以方法声明为准,只接受列出的来源

运行时语义建议如下:

  • 命中 @cors 的路由应返回对应的 Access-Control-Allow-Origin
  • 当浏览器发起 OPTIONS 预检请求时,应基于同一份策略计算响应
  • @cors@cors("...", "...") 的差别主要体现在允许的来源集合

这类规则属于 HTTP 边界行为,不改变 XIDL 方法签名,也不参与业务参数绑定。

HTTP 场景里:

  • 可选 Query 参数可以省略
  • 可选 Body 字段可以省略
  • 路径参数不能可选

这决定了 OpenAPI 和运行时校验时对字段必填性的理解。

attribute 会映射成隐含操作,再继续走 HTTP 普通映射规则。

也就是说,attribute 本身不是独立特殊通道,而是通过生成出来的访问操作进入 HTTP 语义。

如果你在实现生成器或运行时:

  • 先做严格校验,不要悄悄容忍冲突注解
  • 路由规范化、参数来源解析和响应整形要稳定可复现
  • 教程页面可以简化,但 RFC 规则不能模糊