☰
openJiuwen ApiParamLocation 详解:REST 工具请求参数位置枚举与参数分流机制
2026/10/14 16:57:46 网站建设 项目流程
  • 人工智能
  • AI Agent
  • Agent 框架
  • 工具调用
  • Agent 工作流
  • RAG
  • MCP Clients
  • 强化学习

【免费下载链接】agent-core-java

openJiuwen agent core Java是 openJiuwen Core的 Java版本,提供AI Agent开发、运行、调优与演进相关的全套SDK能力。

项目地址:https://gitcode.com/openJiuwen/agent-core-java
点击查看免费下载

com.openjiuwen.core.foundation.tool.service_api.ApiParamLocation是 openJiuwen agent-core-java 中 RESTful 工具体系的参数位置枚举,用于标记一个参数应当落在 URL 查询串、路径占位、请求体还是请求头。它是RestfulApi与ApiParamMapper之间传递位置信息的核心纽带。读完本文,你将掌握该枚举的每个取值与对应的小写字符串、getValue()/fromString()的语义边界,并能结合源码读懂参数从输入 Schema 到最终 HTTP 请求的完整分流链路。

一、枚举定义与定位

在com.openjiuwen.core.foundation.tool.service_api包下,ApiParamLocation是描述“请求参数应该被放在 HTTP 请求的哪个位置”的枚举类型。其源码位于 ApiParamLocation.java,声明如下:

public enum ApiParamLocation { QUERY("query"), PATH("path"), BODY("body"), HEADER("header"), FORM("form"); private final String value; ApiParamLocation(String value) { this.value = value; } public String getValue() { return value; } public static ApiParamLocation fromString(String rawValue) { for (ApiParamLocation location : values()) { if (location.value.equalsIgnoreCase(rawValue)) { return location; } } throw new IllegalArgumentException("No enum constant for API parameter location: " + rawValue); } }

从源码注释可以确认,该枚举与 Python 版本openjiuwen/core/foundation/tool/service_api/api_param_mapper.py中的APIParamLocation一一对应,属于跨语言 SDK 参数映射协议的 Java 侧镜像实现。

该枚举在整个 service_api 子包中处于“位置契约”地位:

  • ApiParamMapper.java 依据输入 Schema 中的location标记调用fromString,把输入值分发到不同位置分组;
  • RestfulApi.java 在构造阶段创建ApiParamMapper,执行请求时按分组结果拼装 URL、请求头与请求体;
  • RestfulApiCard.java 在卡片构造阶段校验路径参数与 Schema 中location=path的声明是否匹配。

二、枚举值详解

按 ApiParamLocation.md 的说明,该枚举用于标记参数属于查询串、路径、请求体或请求头,其取值及对应小写字符串如下:

枚举值小写字符串说明HTTP 请求中的实际落点
QUERYqueryURL 查询参数追加到 URL 的?之后,如/search?q=openjiuwen
PATHpath路径占位参数替换 URL 模板中的{name}占位符,如/users/{id}→/users/42
BODYbody请求体参数序列化为 JSON 请求体(非 GET 请求),或并入查询串(GET/DELETE 等请求)
HEADERheaderHTTP 请求头参数写入请求头,如Authorization、X-Test

需要特别说明的是,从当前仓库源码看,该枚举实际还包含第 5 个取值FORM("form"),用于 multipart/form-data 场景(详见下文第四节)。文档表格虽未列出,但源码、RestfulApi.getParametersByLocation(...)与RestfulApiTest均确认了form位置的存在,使用时应以源码为准。

三、公开方法语义

getValue()

返回枚举对应的小写字符串值,即QUERY→"query"、PATH→"path"、BODY→"body"、HEADER→"header"、FORM→"form"。该字符串正是 Schema 中location字段采用的书写形式,例如 RestfulApiTest.java 中 Schema 就写为"location", "path"、"location", "query"。

fromString(String)

按文档描述,该方法“忽略大小写解析字符串;未知值回退到BODY”。结合源码需要补充两点精确语义:

  1. 忽略大小写:fromString内部使用equalsIgnoreCase逐一比对value,因此"Query"、"QUERY"、"query"等价;
  2. 未知值行为:从当前源码看,当字符串不匹配任何枚举值时,fromString实际抛出IllegalArgumentException("No enum constant for API parameter location: ..."),而不是回退到BODY。这一行为被 ApiParamMapperTest.java 的invalidExplicitLocationFailsFast用例锁定:Schema 中显式声明"location", "invalid"时,map(...)会直接失败并抛出IllegalArgumentException。

换句话说,“回退到 BODY”的真实发生位置在ApiParamMapper.resolveLocation(...),即当参数 Schema 中根本没有声明location键时才启用默认位置逻辑(默认 BODY)。显式声明了非法位置则会快速失败(fail-fast),避免配置错误拖到运行时才暴露。

四、在 ApiParamMapper 中的消费链路

ApiParamMapper是枚举最主要的消费者,其map(inputs, defaultLocation)方法把输入按位置分组成Map<ApiParamLocation, Map<String, Object>>。核心流程见 ApiParamMapper.java:

  1. Schema 为空:全部输入直接放入defaultLocation分组;
  2. 按 Schema 分流:遍历schema.properties,只对输入中存在的键做分流;每个属性的location值经resolveLocation解析为枚举实例;
  3. FORM 特例:location == FORM时,只有“真值”(非 null、非空字符串、非 0 数字、非空集合/Map)的参数才会被放入 FORM 分组,并包装为{"form_handler_type": ..., "value": ...};form_handler_type未显式声明时默认"default";
  4. 默认值合并:PATH、QUERY、HEADER三类位置在分流后会与构造时传入的默认参数合并,且输入值覆盖默认值;空字符串与 null 输入不会覆盖默认值(见测试mapMergesDefaultsButKeepsDefaultsWhenInputIsNullOrEmptyString)。

resolveLocation的解析规则(源码 L126-L134):

  • location值为字符串时,转小写后调用fromString(非法值抛异常);
  • location值为ApiParamLocation实例时直接采用;
  • 未声明location时:若默认位置是BODY则回退到BODY,否则回退到QUERY。

由测试 ApiParamMapperTest.java 可见典型分流结果:q→QUERY、id→PATH、payload→BODY、token→HEADER各归其位;多个 FORM 参数与 BODY 参数混用时(L81-L102),FORM 与 BODY 可同时存在。

五、在 RestfulApi 中的最终落地

卡片定义与构造期校验

RestfulApiCard声明 URL、HTTP 方法、默认请求头、默认参数与执行约束,默认方法为POST、默认超时 60 秒、默认最大响应体 10MB(见 RestfulApiCard.md 与源码 RestfulApiCard.java)。构造阶段即完成三类校验:

  • method必须属于SUPPORTED_METHODS(GET/POST/PUT/PATCH/DELETE/HEAD/OPTIONS),非法方法直接抛错;
  • url必须是带 host 的 http/https 地址;
  • 路径参数一致性:URL 中每个{name}占位符都必须在input_paramsSchema 中以"location": "path"声明,否则抛TOOL_RESTFUL_API_CARD_CONFIG_INVALID;反之 Schema 中声明了 URL 未用到的 path 参数只记 warning(源码 L166-L210)。

执行时的位置拼装

RestfulApi.invoke(...)先对输入做 Schema 格式化,再交给apiParamMapper.map(formattedInputs, ApiParamLocation.BODY)分流,随后在buildPayload(RestfulApi.java L327-L368)中按位置拼装请求:

  • PATH:applyPathParams用{name}占位符替换为参数值;
  • QUERY:appendQueryParams追加?k=v(数组/集合值会展开为多个键值对),参数经 UTF-8 URL 编码;
  • HEADER:写入请求头,并与request_args.headers合并;
  • BODY:非 GET 请求序列化为 JSON 请求体并自动补充Content-Type: application/json;GET/DELETE/HEAD/OPTIONS这类PARAM_METHODS请求则把 body 参数追加到查询串(对应 service_api.README.md 中的关键行为说明);
  • FORM:走FormHandlerManager的处理器后组装为multipart/form-data请求体,自动移除调用方传入的Content-Type并重新生成 boundary。

这些行为在 RestfulApiTest.java 中均有对应的本地 HttpServer 验证,例如:

  • testInvokeGetWithParams:id=42落入路径/users/42,format/ids/keyword与默认limit=10落入查询串,X-Test落入请求头;
  • testInvokePutWithBodyAndPathParams:PUT 请求发送 JSON body,路径占位被替换;
  • testDeleteUsesParamsForBodyLocation:DELETE 的 body 参数并入查询串;
  • testFormSubmissionFlow:location=form的参数发送 multipart body。

响应标准化

响应先经 ParserRegistry 按Content-Type解析,再封装为统一六字段结构:code、data、url、headers、reason、message。响应字节数超过max_response_byte_size、HTTP 状态码 ≥ 400(且未关闭raise_for_status)或响应解析失败时,分别转换为对应StatusCode错误。

六、完整实战示例

把以上机制串起来,一个典型的天气查询 REST 工具定义如下(改写自仓库示例 ReActWeatherAgentExample.java):

import com.openjiuwen.core.foundation.tool.Tool; import com.openjiuwen.core.foundation.tool.service_api.RestfulApi; import com.openjiuwen.core.foundation.tool.service_api.RestfulApiCard; import java.util.Map; RestfulApiCard card = RestfulApiCard.builder() .id("weather_tool") .name("WeatherReporter") .description("天气查询插件,输入 city 获取实时天气和未来几天预报") .url("https://uapis.cn/api/v1/misc/weather") .method("GET") .timeout(10.0) .queries(Map.of("lang", "zh", "forecast", true)) .inputParams(Map.of( "type", "object", "properties", Map.of( "city", Map.of( "type", "string", "description", "城市名称,支持中文(北京)和英文(Tokyo)", "location", "query" ) ) )) .build(); Tool tool = new RestfulApi(card);

示例中city通过"location", "query"声明为查询参数,lang、forecast作为卡片级默认查询参数在每次请求时自动携带。注册进 ReActAgent 后,模型调用WeatherReporter(city="北京")时会自动拼出?lang=zh&forecast=true&city=北京。

若 URL 含路径占位符,则必须配套声明:

// URL: https://api.example.com/api/v1/Activities/{id} "properties", Map.of( "id", Map.of("type", "integer", "description", "Activity ID", "location", "path"), "name", Map.of("type", "string", "description", "Activity name", "location", "body"), "api_key", Map.of("type", "string", "description", "API Key", "location", "header") )

上述 Schema 中id会替换 URL 占位符、name进入请求体、api_key进入请求头。类似的混合位置定义与 GUI 辅助方法RestfulApi.getParametersByLocation(...)(按path/query/header/body/form分组输出参数元数据)都能在 RestfulApiTest.java 中找到验证。

七、行为边界与注意事项

综合文档与源码,使用ApiParamLocation时需要留意以下边界:

  1. 位置值大小写不敏感:Schema 中写"query"、"Query"、"QUERY"均可被fromString接受;
  2. 非法显式位置快速失败:显式声明了"location"但值非法时,构造/调用阶段即抛IllegalArgumentException,不会静默回退;
  3. 未声明位置才回退 BODY:参数未写location键时默认进入BODY(map默认defaultLocation为BODY),这也是 REST 工具最常见的默认行为;
  4. 路径占位符强校验:URL 中的{name}必须能在 Schema 中按location=path找到对应声明,否则卡片构造直接失败;
  5. GET 与 DELETE 的 body 会变成查询参数,因此“body 参数”的落点取决于 HTTP 方法;
  6. FORM 是文档表格之外的扩展位置:实际源码支持location=form配合form_handler_type组装 multipart 请求,测试覆盖可参考TestProcessFormDataMethod与TestCompleteFormSubmissionFlow系列用例;
  7. 响应限流与状态检查:kwargs.timeout、kwargs.max_response_byte_size、kwargs.raise_for_status可在调用时覆盖卡片默认值。

八、相关文档与测试清单

  • 枚举 API 文档:ApiParamLocation.md
  • 参数映射器文档:ApiParamMapper.md
  • REST 工具文档:RestfulApi.md
  • 工具卡片文档:RestfulApiCard.md
  • 子包总览:service_api.README.md
  • 开发者指南:自定义工具.md(含RestfulApi使用要点与注意事项)
  • 核心测试:ApiParamMapperTest.java、RestfulApiTest.java
  • 可运行示例:ReActWeatherAgentExample.java

通过ApiParamLocation这一层轻量枚举契约,openJiuwen agent-core-java 把“参数放在哪”的声明与“请求怎么拼”的实现彻底解耦:上层 Schema 只需写一行location,底层ApiParamMapper与RestfulApi就能稳定地把它翻译成正确的路径、查询串、请求头、请求体或 multipart 表单,这也是整个 RESTful 工具体系在模型函数调用与实际 HTTP 执行之间保持一致的根基。

  • 人工智能
  • AI Agent
  • Agent 框架
  • 工具调用
  • Agent 工作流
  • RAG
  • MCP Clients
  • 强化学习

【免费下载链接】agent-core-java

openJiuwen agent core Java是 openJiuwen Core的 Java版本,提供AI Agent开发、运行、调优与演进相关的全套SDK能力。

项目地址:https://gitcode.com/openJiuwen/agent-core-java
点击查看免费下载

相关推荐

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询