Amazon API Gateway
开发人员指南
AWS 文档中描述的 AWS 服务或功能可能因区域而异。要查看适用于中国区域的差异,请参阅 Amazon AWS 入门

为请求和响应映射创建模型和映射模板

在 API Gateway 中,API 的方法请求采用的负载格式可能与后端所需的相应集成请求负载的格式不同。同样,后端返回的集成响应负载可能不同于前端希望的方法响应负载。API Gateway 允许您使用映射模板将负载从方法请求映射到相应的集成请求,以及从集成响应映射到相应的方法响应。

映射模板是一个用 Velocity 模板语言 (VTL) 表示的脚本,应用于使用 JSONPath 表达式的负载。负载可以拥有符合 JSON 架构草案 4 的数据模型。您必须定义该模型,以便让 API Gateway 生成开发工具包,或为您的 API 启用基本请求验证。您不必定义任何模型来创建映射模板。但是,模型可以帮助您创建模板,因为 API Gateway 将根据提供的模型生成模板蓝图。

本节介绍了如何使用模型和映射模板来映射 API 请求和响应负载。

模型

在 API Gateway 中,模型定义负载的数据结构。在 API Gateway 中,使用 JSON 架构草案 4 定义模型。

以下 JSON 对象描述了一种示例数据,该数据描述一个虚构超市的生产部门的水果或蔬菜库存:

假设我们有一个 API 用于管理超市生产部门的水果和蔬菜库存。当经理在后端查询当前库存时,服务器返回以下响应负载:

{ "department": "produce", "categories": [ "fruit", "vegetables" ], "bins": [ { "category": "fruit", "type": "apples", "price": 1.99, "unit": "pound", "quantity": 232 }, { "category": "fruit", "type": "bananas", "price": 0.19, "unit": "each", "quantity": 112 }, { "category": "vegetables", "type": "carrots", "price": 1.29, "unit": "bag", "quantity": 57 } ] }

JSON 对象有三个属性

  • department 属性有一个字符串值 (produce)。

  • categories 属性是由两个字符串 (fruitvegetables) 组成的数组。

  • bins 属性是一个对象数组,其中的每个对象都具有 categorytypepriceunitquantity 字符串值或数值属性。

我们可以使用以下 JSON 架构来定义上述数据的模型:

{ "$schema": "http://json-schema.org/draft-04/schema#", "title": "GroceryStoreInputModel", "type": "object", "properties": { "department": { "type": "string" }, "categories": { "type": "array", "items": { "type": "string" } }, "bins": { "type": "array", "items": { "type": "object", "properties": { "category": { "type": "string" }, "type": { "type": "string" }, "price": { "type": "number" }, "unit": { "type": "string" }, "quantity": { "type": "integer" } } } } } }

在上述示例模型中:

  • $schema 对象表示一个有效的 JSON 架构版本标识符。在本例中,它指的是 JSON 架构草稿版本 4。

  • title 对象是人类可读的模型标识符。在本例中,它是 GroceryStoreInputModel

  • JSON 数据的顶级或根结构是一个对象。

  • JSON 数据中的根对象包含 departmentcategoriesbins 属性。

  • department 属性是 JSON 数据中的字符串对象。

  • categories 属性是 JSON 数据中的数组。该数组包含 JSON 数据中的字符串值。

  • bins 属性是 JSON 数据中的数组。该数组包含 JSON 数据中的对象。JSON 数据中的上述每个对象均包含一个 category 字符串、一个 type 字符串、一个 price 数字、一个 unit 字符串和一个 quantity 整数 (没有分数或指数部分的数字)。

或者,您可以在同一文件的单独部分包含此架构的一部分 (例如 bins 数组的项目定义),然后使用 $ref 基元在架构的其他部分引用此可重用的定义。使用 $ref,上述模型定义文件可如下表示:

{ "$schema": "http://json-schema.org/draft-04/schema#", "title": "GroceryStoreInputModel", "type": "object", "properties": { "department": { "type": "string" }, "categories": { "type": "array", "items": { "type": "string" } }, "bins": { "type": "array", "items": { "$ref": "#/definitions/Bin" } } }, "definitions": { "Bin" : { "type": "object", "properties": { "category": { "type": "string" }, "type": { "type": "string" }, "price": { "type": "number" }, "unit": { "type": "string" }, "quantity": { "type": "integer" } } } } }

definitions 部分包含通过 "ref": "#/definitions/Bin"bins 数组中引用的 Bin 项目的架构定义。通过这种方法使用可重用定义可确保您的模型定义更易于阅读。

此外,您也可以引用外部模型文件中定义的另一个模型架构,方法是将该模型的 URL 设置为 $ref 属性的值:"$ref": "https://apigateway.amazonaws.com/restapis/{restapi_id}/models/{model_name}"。例如,假设您在标识符为 fugvjdxtri 的 API 下创建了名为 Bin2 的以下成熟模型:

{ "$schema": "http://json-schema.org/draft-04/schema#", "title": "GroceryStoreInputModel", "type": "object", "properties": { "Bin" : { "type": "object", "properties": { "category": { "type": "string" }, "type": { "type": "string" }, "price": { "type": "number" }, "unit": { "type": "string" }, "quantity": { "type": "integer" } } } } }

则可以从同一 API 的 GroceryStoreInputModel 中引用它,如下所示:

{ "$schema": "http://json-schema.org/draft-04/schema#", "title": "GroceryStoreInputModel", "type": "object", "properties": { "department": { "type": "string" }, "categories": { "type": "array", "items": { "type": "string" } }, "bins": { "type": "array", "items": { "$ref": "https://apigateway.amazonaws.com/restapis/fugvjdxtri/models/Bin2" } } } }

引用模型和被引用模型必须来自同一 API。

这些示例不使用高级 JSON 架构功能,例如指定必需项;允许的最小和最大字符串长度、数值和数组项长度;正则表达式等等。有关更多信息,请参阅 JSON 简介JSON 架构草案 4

有关更复杂的 JSON 数据格式及其模型,请参阅以下示例:

要试验 API Gateway 中的模型,请按照映射响应负载中的说明操作,具体来说就是步骤 1:创建模型

映射模板

当后端返回查询结果 (在模型部分中显示) 时,生产部门的经理可能会有兴趣阅读它们,如下所示:

{ "choices": [ { "kind": "apples", "suggestedPrice": "1.99 per pound", "available": 232 }, { "kind": "bananas", "suggestedPrice": "0.19 per each", "available": 112 }, { "kind": "carrots", "suggestedPrice": "1.29 per bag", "available": 57 } ] }

要做到这一点,我们需要提供 API Gateway 映射模板来转换后端数据的格式。以下映射模板将实现这一目标。

#set($inputRoot = $input.path('$')) { "choices": [ #foreach($elem in $inputRoot.bins) { "kind": "$elem.type", "suggestedPrice": "$elem.price per $elem.unit", "available": $elem.quantity }#if($foreach.hasNext),#end #end ] }

现在,我们来看看上述输出映射模板的一些详细信息:

  • $inputRoot 变量表示上一部分的原始 JSON 数据中的根对象。输出映射模板中的变量映射到原始 JSON 数据,而不是所需的已转换的 JSON 数据架构。

  • 输出映射模板中的 choices 数组是从原始 JSON 数据根对象 ($inputRoot.bins) 的 bins 数组映射而来。

  • 在输出映射模板中,choices 数组 (由 $elem 表示) 中的每个对象均是从原始 JSON 数据根对象的 bins 数组中的相应对象映射而来。

  • 在输出映射模板中,对于 choices 对象中的每个对象,kindavailable 对象的值 (由 $elem.type$elem.quantity 表示) 分别是从原始 JSON 数据的 bins 数组中每个对象的 typevalue 对象的相应值映射而来。

  • 在输出映射模板中,对于 choices 对象中的每个对象,suggestedPrice 对象的值分别是原始 JSON 数据中每个对象的 priceunit 对象的相应值的串联,每个值均用单词 per 分隔。

有关 Velocity 模板语言的更多信息,请参阅 Apache Velocity – VTL 参考。有关 JSONPath 的更多信息,请参阅 JSONPath – 适用于 JSON 的 XPath

该映射模板假定基础数据为 JSON 对象。它不要求为数据定义模型。作为 API 开发人员,您需要知道前端和后端的数据格式。掌握这些信息可指导您定义必要的映射,而不会模棱两可。

要为 API 生成开发工具包,上述数据将作为特定于语言的对象而返回。对于强类型语言 (如 Java、Objective-C 或 Swift),对象对应于用户定义的数据类型 (UDT)。API Gateway 将创建此类 UDT (如果您为其提供数据模型)。对于上述方法响应示例,您可以在集成响应中定义以下负载模型:

{ "$schema": "http://json-schema.org/draft-04/schema#", "title": "GroceryStoreOutputModel", "type": "object", "properties": { "choices": { "type": "array", "items": { "type": "object", "properties": { "kind": { "type": "string" }, "suggestedPrice": { "type": "string" }, "available": { "type": "integer" } } } } } }

在此模型中,JSON 架构如下所示:

  • $schema 对象表示一个有效的 JSON 架构版本标识符。在本例中,它指的是 JSON 架构草稿版本 4。

  • title 对象是人类可读的模型标识符。在本例中,它是 GroceryStoreOutputModel

  • JSON 数据的顶级或根结构是一个对象。

  • JSON 数据中的根对象包含一个对象数组。

  • 对象数组中的每个对象均包含一个 kind 字符串、一个 suggestedPrice 字符串和一个 available 整数 (没有分数或指数部分的数字)。

借助此模型,您可以调用开发工具包,以便通过读取 GroceryStoreOutputModel.kindGroceryStoreOutputModel.suggestedPriceGroceryStoreOutputModel.available 属性来分别检索 kindsuggestedPriceavailable 属性值。如果未提供模型,API Gateway 将使用空模型创建默认 UDT。在这种情况下,您将无法使用强类型开发工具包来读取这些属性。

要了解更复杂的映射模板,请参阅以下示例:

要试验 API Gateway 中的映射模板,请按照映射响应负载中的说明操作,具体来说就是步骤 5:设置和测试方法

模型和映射模板的任务

有关可以使用模型和映射模板执行的其他操作,请参阅以下内容: