[AEM Forms]{class="badge positive" title="适用于AEM Forms)。"}
在规则编辑器中集成API
规则编辑器中的Integrating API位于早期采用程序程序下。 您可以通过您的官方电子邮件 ID 向 aem-forms-ea@adobe.com 发送电子邮件,以加入早期采用者计划并请求对该功能的访问权限。
自适应Forms中的可视规则编辑器支持直接API集成,而无需创建表单数据模型。 您可以通过输入API URL(以JSON格式)或通过cURL命令导入配置来连接到API端点。 集成后,调用服务操作可用于调用API。
表单字段可以直接映射到API配置中定义的输入参数。 同样,可以使用相应API响应的 事件有效负载 选项将输出参数映射到表单字段。
此外,可视规则编辑器允许您在调用服务时定义 success 和failure处理程序。 成功处理程序指定在成功API调用后要执行的操作,而失败处理程序定义表单在错误发生时应如何响应。
比较: API集成方法
API 集成配置
以下屏幕截图显示API集成配置窗口:
关键配置选项
API集成配置
- 从cURL导入:通过粘贴现成的cURL命令配置API集成,而不是手动输入详细信息,如API URL、HTTP方法、标头和参数。
- 显示名称: API服务的自定义名称。
- API URL: API服务的端点。
- 选择HTTP方法:用于调用API的HTTP请求方法。
- 内容类型:定义请求和响应格式。
- 需要加密: (可选)选定后,可以使用 function.js 中的自定义函数对请求和响应负载进行加密。 出现 公钥 字段。 在保存API集成配置之前,将公钥粘贴到此字段中。
- 在客户端执行:启用后,将从客户端(浏览器)而不是服务器执行API调用。
身份验证类型
- 选项:无、基本、API密钥。
输入参数
-
上载输入的JSON:上载示例JSON文件以自动填充输入映射。
- 名称: API所需的输入参数名称。
- 类型:输入的数据类型(字符串、数字、布尔等)。
- In:参数(查询、标头或正文)的位置。
- 默认值:如果未由用户提供,则为预填充值。
- 添加:用于添加其他输入参数的选项。
输出参数
-
上载输出的JSON:上载示例API响应以自动生成映射。
- 名称: API响应中的输出参数名称。
- 类型:输出参数的预期数据类型(字符串、数字等)。
- In:定义需要映射值的位置。
- 添加/删除:添加新映射或删除现有映射。
用例:在签证申请表中填写国家/地区字段
方案:政府机构提供包含以下字段的在线签证申请表:
- 全名(文本)
- 出生日期(日期)
- 国籍国家/地区(下拉列表)
- 护照号码(文本)
- 护照签发国家/地区(下拉列表)
- 目标国家/地区(下拉列表)
- 预定到达日期(日期)
表单不会维护静态的国家/地区列表,而是动态获取国家/地区信息(大陆、资本、ISO Alpha代码等) 使用getcountryname API:
https://secure.geonames.org/countryInfoJSON?username=aemforms
这可确保在填写表单时始终看到最新的准确国家/地区列表。
在规则编辑器中使用API集成进行实施
您可以通过单击规则编辑器中的 创建API集成 按钮,在不创建表单数据模型的情况下集成API。
在规则编辑器中的 API集成配置 下配置了名为 getcountryname 的API服务:
- API终结点URL →
https://secure.geonames.org/countryInfoJSON?username=aemforms - HTTP方法 → GET
- 内容类型→JSON
- 输入→
username作为查询参数(aemforms)传递。 - 输出 →响应字段(如
continent、capital、countrynames、isoAlpha3和languages)映射到表单字段。
在 Visa申请表 中,三个下拉字段公民国家/地区、Passport颁发国家/地区和 目的地国家/地区 将绑定到 调用服务 操作。
加载表单时,调用服务从API获取国家/地区列表。 然后,将映射响应以自动填充下拉选项。
例如,当用户打开 公民国家/地区 时,将从API响应动态显示国家/地区列表。
同样,Passport Issuance国家/地区和 目标国家/地区 使用相同的API调用,确保所有三个字段中的数据一致且最新。
编辑现有API集成
创建API集成后,您可以从规则编辑器更新它,而无需创建新集成。 当 Invoke Service 语句引用API集成时,Edit选项可用于该集成。
要编辑现有API集成,请执行以下操作:
- 在规则编辑器中打开包含 Invoke Service 语句的规则。
- 在 Invoke Service 语句中,选择要更新的API集成。
- 单击 编辑 图标以打开 API集成配置 窗口。
- 更新API URL、身份验证、输入和输出参数或其他设置,并保存更改。
加密和解密
为API集成选择 需要加密 时,请将您的公钥粘贴到API集成配置窗口的 公钥 字段中。 规则编辑器会在每个传出请求之前调用encrypt,并在成功响应之后调用decrypt。 如果不在 function.js 中添加自定义逻辑,则两个函数都将返回未更改的有效负载。
要加密和解密请求和响应数据,请将 encrypt 和 decrypt 函数添加到function.js:
- 打开自适应表单的 function.js 文件。
- 添加 encrypt 函数以在API调用之前转换请求(正文、标头和相关选项)。
- 添加 decrypt 函数以在API调用成功后转换响应。 decrypt函数接收加密的响应和originalRequest,其中包含加密期间设置的任何cryptoMetadata。
- 保存function.js,然后在规则编辑器中使用 调用服务 测试集成。
以下示例代码演示了如何在 function.js 中添加 encrypt 函数:
function encrypt(payload) {
const { body, headers, options } = payload;
const { encryptedBody, encryptedKey } = await myRsaEncrypt(body);
return {
body: encryptedBody,
headers: { ...headers, 'X-Encrypted-Key': encryptedKey },
cryptoMetadata: { keyId: 'rsa-2048-v1' },
options
};
}
encrypt(请求前有效负载挂接)
encrypt函数接收具有主体、标头以及可选的 cryptoMetadata 和 选项 的有效负荷对象。 它返回同一形状的修改版本。 options字段通过请求管道携带获取API设置(例如,credentials: 'include')。 选项中的值已应用于基础fetch()调用。 cryptoMetadata字段存储数据以便在解密时使用。 您在加密期间在 cryptoMetadata 中设置的任何内容,都将保留在 originalRequest.cryptoMetadata 中,并稍后可供 decrypt 函数使用。 不管名称如何,encrypt都是通用的预请求转换器。 您可以使用该插件修改标头或请求正文,而不仅仅用于加密加密。 默认实施会返回未更改的有效负载。
>>
以下示例代码演示了 decrypt 函数:
function decrypt(encryptedData, originalRequest) {
const { keyId } = originalRequest?.cryptoMetadata || {};
return await myRsaDecrypt(encryptedData, keyId);
}
解密(后请求响应挂接)
decrypt函数在成功响应后运行。 它接收响应正文和originalRequest。 originalRequest对象包含 encrypt 函数中的cryptoMetadata,以及url、方法和其他请求元数据。 它必须同步或异步返回解密的主体。 默认实施会返回未更改的数据。 decrypt函数仅在成功响应时运行。 错误响应不调用decrypt。
myRsaEncrypt和myRsaDecrypt替换为加密函数。实施API失败的重试机制
当API请求失败时,在向用户报告错误之前重试请求通常很有用。 通过在 function.js 文件中写入自定义代码,您可以实施轮询和重试机制。
以下示例演示了如何处理最多包含两次重试和两次重试之间的指数回退的API失败:
/**
* Handles request retries with up to 2 retry attempts
* @param {function} requestFn - The request function to execute
* @return {Promise} A promise that resolves with the response or rejects after all retries
*/
function retryHandler(requestFn) {
const MAX_RETRIES = 2;
/**
* Attempts the request with retry metadata
* @param {number} retryCount - Current retry attempt count
* @return {Promise} The request promise
*/
function attemptRequest(retryCount = 0) {
// Include retry metadata if this is a retry
const requestOptions = retryCount > 0 ? {
headers: {
'X-Retry': 'true',
'X-Retry-Count': retryCount.toString(),
'X-Retry-Time': new Date().toISOString()
},
body: {
retry: true,
retryCount: retryCount,
timestamp: Date.now()
}
} : undefined;
return requestFn(requestOptions)
.then(function(response) {
if (response && response.status >= 400) {
console.warn('Request failed with status ' + response.status);
throw new Error('Request failed with status ' + response.status);
}
return response;
})
.catch(function(error) {
console.warn('Request attempt ' + (retryCount + 1) + ' failed:', error.message);
// Retry if max attempts not reached
if (retryCount < MAX_RETRIES) {
console.log('Retrying request, attempt ' + (retryCount + 2) + ' of ' + (MAX_RETRIES + 1));
// Exponential backoff delay: 1s, 2s, 4s...
const delay = Math.pow(2, retryCount) * 1000;
return new Promise(function(resolve) {
setTimeout(resolve, delay);
}).then(function() {
return attemptRequest(retryCount + 1);
});
} else {
// All retries exhausted
console.error('All retry attempts failed. Final error:', error.message);
throw new Error('Request failed after ' + (MAX_RETRIES + 1) + ' attempts: ' + error.message);
}
});
}
// Start the first attempt
return attemptRequest(0);
}
在上述代码中,retryHandler函数通过自动重试管理API请求,以防失败。 它使用一个请求函数(requestFn),最多尝试请求两次,为每次重试添加元数据。
常见问题解答
-
我是否需要创建表单数据模型以集成Adaptive Forms中的API?
不行。 通过可视化规则编辑器,您可以使用 创建API集成 选项直接集成API,而无需创建表单数据模型。 此方法最适合轻量级或特定于表单的用例。 -
我能否保护从规则编辑器发出的API调用?
是。 API集成配置提供身份验证选项,如 基本 和API密钥。 您还可以在 function.js 中选择 需要加密 并添加自定义 加密 和 解密 逻辑。 有关配置步骤和示例,请参阅加密和解密。