尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

ShowDoc 依赖剖析:Guzzle Services 服务描述机制实战指南

ShowDoc 依赖剖析:Guzzle Services 服务描述机制实战指南 ShowDoc 依赖剖析Guzzle Services 服务描述机制实战指南【免费下载链接】showdocShowDoc is a tool greatly applicable for an IT team to share documents online一个非常适合IT团队的在线API文档、技术文档工具项目地址: https://gitcode.com/gh_mirrors/sh/showdoc本指南围绕 ShowDoc 仓库中内置的第三方依赖 guzzlehttp/guzzle-services 展开讲解它如何借助“服务描述Service Description”来声明 Web 服务接口、自动序列化 HTTP 请求并把响应解析为易用的模型结构。读完本文你将掌握服务描述文件的完整配置语法operations、models、parameters、location 等、GuzzleClient 的请求/响应流转原理以及如何通过自定义 Query 序列化器解决真实 API 的兼容问题。一、Guzzle Services 是什么Guzzle Services 提供了 Guzzle Command 库的一套基于 Guzzle 的实现它使用 Guzzle 服务描述service descriptions来描述 Web 服务序列化请求serialize requests并把响应解析parse responses成易于使用的模型结构model structures。其核心思想是把“调哪个接口、传什么参数、响应长什么样”声明式地写在一份数组PHP 数组或 JSON 文件里运行时由库自动完成请求构建与响应解析从而减少手写 HTTP 客户端样板代码。在 ShowDoc 项目中该库以依赖形式被放置在 server/vendor/guzzlehttp/guzzle-services 目录下版本为 1.1.3见 composer.lock。它建立在 Guzzle Command 体系之上源码中同时包含src/核心实现与tests/配套测试是理解“声明式 HTTP 客户端”设计模式的绝佳样本。二、快速上手一段完整的服务描述示例README 给出了一段最小可运行的示例。结合源码稍作注释use GuzzleHttp\Client; use GuzzleHttp\Command\Guzzle\GuzzleClient; use GuzzleHttp\Command\Guzzle\Description; $client new Client(); $description new Description([ baseUri http://httpbin.org/, operations [ testing [ httpMethod GET, uri /get{?foo}, responseModel getResponse, parameters [ foo [ type string, location uri // 作为 URI 模板变量 ], bar [ type string, location query // 作为查询字符串参数 ] ] ] ], models [ getResponse [ type object, additionalProperties [ location json // 响应体按 JSON 解析 ] ] ] ]); $guzzleClient new GuzzleClient($client, $description); $result $guzzleClient-testing([foo bar]); echo $result[args][foo]; // bar运行流程可以拆解为三步Description将声明式数组解析为内部结构operations / models 等见后文第三节GuzzleClient调用testing([foo bar])时Serializer根据uri模板/get{?foo}展开出/get?foobar并应用query位置的参数响应返回后Deserializer依据getResponse模型把 JSON 响应体解析成Result对象因此$result[args][foo]能直接取到回显的bar。值得注意的是GuzzleClient在查找命令时会先按原名查找失败后会自动尝试首字母大写ucfirst再查找一次未找到才抛出InvalidArgumentException这为驼峰与首字母大写的调用方式提供了容错见 GuzzleClient.php。三、安装与版本选择使用 Composer 安装composer require guzzlehttp/guzzle-services针对Guzzle 5的旧项目需要锁定旧版本composer require guzzlehttp/guzzle-services:0.6注意如果 Composer 未全局安装需要把上述命令改为php composer.phar require ...其中composer.phar指向你本地的 Composer 可执行文件。在 ShowDoc 的 composer.lock 中锁定的是 1.1.3 版本对应 Guzzle 6 时代的新接口GuzzleHttp\Command\Guzzle\GuzzleClient、Description等命名空间与 README 中的示例代码一致。四、服务描述Service Description结构深入Description类是整份声明的入口构造参数$config支持如下顶级键见 Description.php键说明nameAPI 名称apiVersionAPI 版本descriptionAPI 用途摘要baseUri基础地址兼容旧写法baseUrl构造时会自动转换operations操作集合操作名 操作配置数组models模型集合模型名 模型 schema 数组其他任意键存入extraData可通过getData($key)取回用于扩展信息两个关键实现细节懒加载operations与models在构造时只保存原始数组直到首次通过getOperation($name)/getModel($id)访问时才实例化为Operation/Parameter对象见 Description.php可定制格式化器第二参$options[formatter]可注入自定义的SchemaFormatter默认使用共享的单例SchemaFormatter负责format属性的解析。DescriptionInterface定义了对外的查询能力getBaseUri、getOperations、getOperation、hasOperation、getModel、hasModel、getApiVersion、getName、getDescription、format、getData是GuzzleClient与序列化/反序列化器协作的统一契约。五、Operation声明一个接口操作每个 operation 由 Operation.php 描述支持的配置键含默认值如下键类型/默认值说明namestring命令名httpMethodstringHTTP 方法GET/POST/PUT/DELETE 等uristringURI 模板可生成相对或绝对 URL如/get{?foo}parametersarray[]参数 schema 集合每项会创建为Parameter对象summarystring操作的短摘要notesstring更详细的说明documentationUrlstringnull参考文档链接responseModelstringnull用于解析响应的模型名兼容旧键responseClassdeprecatedboolfalse标记为已废弃errorResponsesarray[]错误响应声明每项含codeHTTP 状态码、phrase原因短语、class自定义异常类dataarray[]任意附加数据additionalParametersnull|array未在 schema 中声明的额外参数所用的 schemaextendsstring继承另一个 operation见下方说明extends机制值得一提若配置了extends构造时会先解析被继承操作的完整配置再以“当前配置覆盖父配置、参数数组按键合并”的方式合并resolveExtends逻辑见 Operation.php便于复用公共参数。六、Parameter参数的完整约束体系Parameter是服务描述中最核心、约束能力最强的构件Parameter.php支持近乎 JSON Schema 子集的能力typestring/number/integer/boolean/object/array/numeric/null/any也支持传数组表示联合类型required/default/static是否必填、默认值、是否静态statictrue时值不可被调用方修改始终使用默认值见getValue()location参数在请求中的位置默认内置uri、query、header、body、json、xml、formParam、multipartsentAs指定“线上传输名”当参数名与真实键名不一致时使用例如模型内叫FooBar实际 header 是x-foo-bargetWireName()优先返回sentAsfilters值过滤函数列表支持ClassName::staticMethod形式也支持带args的复杂过滤器占位符value表示被过滤的值、api表示当前 Parameter 对象format预定义格式化器与filters二选一支持date-time、date、time、timestamp、date-time-http、boolean-string实现见 SchemaFormatter.php例如date-time会输出 UTC 时区的Y-m-d\TH:i:s\Z格式properties/additionalProperties对象类型的嵌套属性与附加属性 schemaobject类型默认additionalPropertiestrueitems数组类型的元素 schemapattern/enum/minLength/maxLength/minimum/maximum/minItems/maxItems字符串正则、枚举与数值/长度边界约束$ref引用服务描述中已定义的模型构造时自动展开替换见 Parameter.phpextends参数级继承父模型数据被合并进当前参数。七、请求序列化与响应解析的“Location 访问者”机制7.1 Serializer命令 → HTTP 请求Serializer.php 负责把Command变成 PSR-7Request核心是 Location 访问者visitor模式依据 operation 的uri与所有locationuri的参数调用GuzzleHttp\uri_template()展开 URI 模板参数值会先经过filter()处理遍历 operation 的所有参数跳过uri位置和未设置的参数按location分派给对应的 Location 访问者执行visit()最后对所有访问过的 location 调用after()用于处理additionalParameters等收尾逻辑。默认注册的请求位置与实现类一一对应location实现类bodyBodyLocation.phpqueryQueryLocation.phpheaderHeaderLocation.phpjsonJsonLocation.phpxmlXmlLocation.phpformParamFormParamLocation.phpmultipartMultiPartLocation.php7.2 DeserializerHTTP 响应 → 模型结果Deserializer.php 负责把响应按responseModel解析为Result对象若客户端配置processfalse直接返回原始ResponseInterface不做解析若 operation 未声明responseModel返回空的Result响应模型类型必须是object或array否则抛出InvalidArgumentException解析同样走“before → visit → after”访问者流程默认响应位置包括body、header、reasonPhrase、statusCode、xml、json。错误响应errorResponses匹配规则遍历 operation 声明的错误列表若声明中同时包含code与phrase则要求状态码与原因短语同时精确匹配若只声明code则匹配状态码即可命中。命中后抛出对应class的异常若未命中任何声明则由 Guzzle 的http_errors选项默认开启接管抛出标准异常见 Deserializer.php。7.3 输入校验ValidatedDescriptionHandlerValidatedDescriptionHandler.php 是一个命令处理器当客户端validate配置未关闭时默认开启它会在发送前对命令参数逐项执行SchemaValidator校验校验通过且值被过滤改变时会回写命令值存在错误时抛出CommandException并附上全部校验错误信息。GuzzleClient构造时还支持defaults给每个命令注入的默认参数、process是否解析响应、response_locations自定义响应位置等配置见 GuzzleClient.php。八、从 Guzzle 5 迁移到 6postField / postFile 的变更在 Guzzle 5 时代请求位置postField和postFile分别表示表单字段与文件上传它们已被移除取而代之的是formParam与multipart。如果你的旧描述长这样[ baseUri http://httpbin.org/, operations [ testing [ httpMethod GET, uri /get{?foo}, responseModel getResponse, parameters [ foo [ type string, location postField ], bar [ type string, location postFile ] ] ] ], ]需要把postField改为formParam把postFile改为multipartfoo [ type string, location formParam // 原 postField ], bar [ type string, location multipart // 原 postFile ]迁移后formParam由 FormParamLocation.php 处理URL 编码表单体multipart由 MultiPartLocation.php 处理multipart/form-data支持文件。九、Cookbook自定义查询参数序列化方式9.1 问题背景默认情况下查询参数按严格的 RFC3986 规则、通过http_build_query序列化。数组参数会被序列化成带数字下标的形式$client-myMethod([foo [bar, baz]]); // Query params will be foo[0]barfoo[1]baz但很多真实的 API 要求去除数字下标得到foo[]barfoo[]baz。9.2 解决方案自定义 Query 序列化器通过创建自己的序列化器并覆盖query请求位置即可use GuzzleHttp\Command\Guzzle\GuzzleClient; use GuzzleHttp\Command\Guzzle\RequestLocation\QueryLocation; use GuzzleHttp\Command\Guzzle\QuerySerializer\Rfc3986Serializer; use GuzzleHttp\Command\Guzzle\Serializer; $queryLocation new QueryLocation(query, new Rfc3986Serializer(true)); $serializer new Serializer($description, [query $queryLocation]); $guzzleClient new GuzzleClient($client, $description, $serializer);这里的核心是 Rfc3986Serializer.php它用http_build_query($params, null, , PHP_QUERY_RFC3986)生成查询串当构造参数$removeNumericIndices为true时再通过正则/%5B[0-9]%5D/即[0-9]的 URL 编码把数字下标统一替换成空的[]从而输出foo[]barfoo[]baz。对应的行为验证可参考 Rfc3986SerializerTest.php。9.3 更进一步的定制如果内置序列化器仍不满足需求可以实现 QuerySerializerInterface.php 定义自己的聚合逻辑并在构造QueryLocation时传入。QueryLocation的after()还会把所有未在 operation 中声明的额外参数受additionalParametersschema 约束一并序列化进查询串见 QueryLocation.php自定义实现时需要注意这一行为的一致性。十、扩展阅读完整服务描述定义Description.php、DescriptionInterface.php操作与参数Operation.php、Parameter.php请求/响应管线Serializer.php、Deserializer.php、GuzzleClient.php配套测试SerializerTest.php、DeserializerTest.php、GuzzleClientTest.php、ParameterTest.php依赖版本与变更记录composer.lock、CHANGELOG.md如果你需要从文件中加载服务描述而不是在代码中硬编码数组可关注社区提供的guzzle-description-loader插件README 的 Plugins 一节有提及可在 Packagist 检索安装。总而言之Guzzle Services 通过“服务描述 Location 访问者”的组合把 Web 客户端中大量可重复的请求构建与响应解析工作收敛为一份声明式配置这正是它在 Guzzle Command 生态中的核心价值。【免费下载链接】showdocShowDoc is a tool greatly applicable for an IT team to share documents online一个非常适合IT团队的在线API文档、技术文档工具项目地址: https://gitcode.com/gh_mirrors/sh/showdoc创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表