
后端API网关数据库GraphQL【免费下载链接】graphql-engineBlazing fast, instant realtime GraphQL APIs on all your data with fine grained access control, also trigger webhooks on database events.项目地址https://gitcode.com/gh_mirrors/gr/graphql-engine点击查看免费下载导读本文围绕 GraphQL Engine 仓库中的 REST/OpenAPI 集成 RFC完整梳理了 Hasura 如何将 RESTified GraphQL Endpoints 自动生成 OpenAPI 3 规范OAS 3.0的演进路线、生成原理与最终落地形态。文章既给出了可直接复用的调用方式GET /api/swagger/json、Swagger UI 渲染方案与 OAS 响应示例也深入到了 OpenAPI.hs 的源码实现讲解参数、请求体、响应体与标量类型是如何从 schema cache 动态推导出来的。读完本文你将掌握 Hasura REST 端点的 OAS 生成机制、字段映射规则及其在实际项目中的调试与消费方法。背景为什么要把 REST 端点接入 OpenAPIREST 端点即 Hasura 的 RESTified GraphQL Endpoints虽然带来了以 GraphQL 查询定义 REST API的便利但缺少一套标准化的机器可读描述。OpenAPI 恰好提供了这一层抽象其价值在 RFC 中被归纳为四点协作式 API 开发REST 团队、前端与后端可以基于同一份规范并行工作代码生成借助 swagger-codegen 等工具OpenAPI 定义可被转换为多种语言的客户端/服务端代码机器可读规范本身是结构化的 JSON/YAML易于做自动化测试与静态校验交互式文档可以直接渲染成带Try it out能力的 Swagger UI把文档与测试客户端合二为一。因此在 Hasura 中RESTified Endpoints 的每个端点都可以被翻译成标准的 OpenAPI 操作Operation从而复用整个 OAS 生态。从 RFC 到交付五个版本的演进路线RFC 给出了清晰的 MVP 式分阶段路线图表格如下VersionMVPFunctionalityNotes / CommentsV1Bare minimum useful functionalityList of endpoints with methods and commentsCompletedV2Bare minimum useful functionalityAll request types / arguments documentedCompletedV3User will get the Swagger JSON blob that can be used at Swagger editor to get the swagger UIAll response types documentedCompletedV4The Swagger UI will support authorization via headerSupport role based authorization systemCompletedV5The swagger UI can be accessed using the Hasura consoleUI in console(We may not implement this)可以看到V1 到 V4 均已标注为 Completed先是端点与方法清单再逐步补齐请求参数、响应类型和基于请求头的鉴权支持V5在 Console 内嵌 Swagger UI则被标记为可能不实现。当前仓库的实际交付物与 V1–V4 完全吻合服务端通过 App.hs 暴露/api/swagger/json并限制为 admin 角色访问而导出入口同时存在于 API 参考文档与 Console 的REST endpoints页签。生成 Swagger 规范需要哪些输入RFC 明确列出了生成一条 Swagger 规范所必需的五个要素这些要素恰好都能从已有的 RESTified Endpoint 元数据中获得API endpointURL来自 REST 端点的url字段MethodPOST/GET 等来自端点的methods列表Parameters即 GraphQL 查询中的 query variablesRequest body即 GQL variables 的 JSON 对象Response body在已知查询与字段类型的前提下可以由 GraphQL 类型系统推导生成。RESTified Endpoint 在 schema cache 中以 Trie前缀树结构组织每个路径对应一张方法 → 端点元数据的映射表。RFC 给出了一个典型的端点存储示例[ { tag: PathLiteral, contents: myAPIpost }, { _trieData: { POST: [ { definition: { query: mutation MyMutation($col_1: String \\, $col_2: String \\, $id: Int 10) {\n insert_table_1(objects: {col_1: $col_1, col_2: $col_2, id: $id}) {\n affected_rows\n }\n} }, url: myAPIpost, methods: [ POST ], name: newAPI, comment: null } ] }, _trieMap: [] } ]其中url字段直接给出端点路径methods给出允许的 HTTP 方法GraphQL 查询文本则同时蕴含了参数与响应结构。RFC 提出的核心思路是以 schema cache 为数据源动态生成 OpenAPI JSON而不是在查询时临时解析元数据——这样在依赖变化时可以预计算问题能更早暴露。用户如何访问 OpenAPI 文档RFC 规划的用户路径是用户访问api/swagger/json获得符合 OpenAPI 标准的 Swagger 规范JSON/YAML可渲染为 Swagger UI在 Swagger UI 中提供鉴权 tokenx-hasura-admin-secret或 JWT以访问端点。这一路径在当前仓库中已经落地官方文档 OpenAPI 3 Specification 明确说明REST 端点的 OpenAPI 3 规范暴露在/api/swagger/json仅对 admin 角色开放GET /api/swagger/json HTTP/1.1 X-Hasura-Role: admin返回的响应是完整的 OAS 3.0 JSON。一个最小化的真实响应示例字段截取如下{ openapi: 3.0.0, info: { version: , title: Rest Endpoints, description: These OpenAPI specifications are automatically generated by Hasura. }, paths: { /api/rest/users: { get: { summary: Fetch user data, description: This API fetches user data (first name and last name) from the users table.\n***\nThe GraphQl query for this endpoint is:\ngraphql\nquery MyQuery{\n users {\n first_name\n last_name\n }\n}\n, responses: {} }, parameters: [ { schema: { type: string }, in: header, name: x-hasura-admin-secret, description: Your x-hasura-admin-secret will be used for authentication of the API request. } ] } }, components: {} }注意其中的两个细节每个 operation 的description中自动嵌入了原始 GraphQL 查询文本方便消费者对照理解每个端点都会自动注入x-hasura-admin-secret的 header 参数对应 RFC V4 的通过 header 支持授权。除直接调用 API 外用户还可以在 Console 的REST endpoints页签点击Export OpenAPI Spec按钮下载全部 RESTified Endpoints 的 OAS 3.0 JSON详见 Export OpenAPI Specification。服务端如何生成 OpenAPI/api/swagger/json的调用链RFC 描述在 HGE 内部发生的事在源码中有精确对应。路由定义位于 App.hsSpock.get api/swagger/json $ mkSpockAction appStateRef encodeQErr id $ mkGetHandler $ do onlyAdmin sc - liftIO $ getSchemaCache appStateRef json - buildOpenAPI sc return (emptyHttpLogGraphQLInfo, JSONResp $ HttpResponse (encJFromJValue json) [])关键链路可以拆解为三步onlyAdmin强制 admin 角色校验这与文档中仅 admin 角色可访问的说明一致getSchemaCache从应用状态中取出 schema cache其中包含 REST 端点的 TriebuildOpenAPI sc调用 Hasura.Server.OpenAPI 模块的核心函数动态构建整个OpenApi文档对象。buildOpenAPI的入口实现OpenAPI.hs如下buildOpenAPI :: (MonadError QErr m, MonadFix m) SchemaCache - m OpenApi buildOpenAPI schemaCache do (defs, spec) - flip runDeclareT mempty do endpoints - buildAllEndpoints schemaCache (scAdminIntrospection schemaCache) pure $ mempty paths .~ fmap fst endpoints info . title .~ Rest Endpoints info . description ?~ This OpenAPI specification is automatically generated by Hasura. foldMap snd endpoints pure $ spec components . schemas .~ defs从中可以看到响应的info.titleRest Endpoints与info.descriptionThese OpenAPI specifications are automatically generated by Hasura.正是在此生成与上文 API 参考文档中的响应示例一一对应。在buildAllEndpointsOpenAPI.hs中生成逻辑按三层遍历 schema cache通过Trie.elems $ scEndpoints schemaCache取出 Trie 中的全部端点对每个端点按 HTTP 方法EndpointMethod展开对每个方法关联的元数据调用buildEndpoint构造对应的PathItem。每个 operation 由buildEndpointOpenAPI.hs组装核心步骤包括从GQLQueryWithText中解析出 GraphQL 查询文档调用getSingleOperation提取唯一操作通过analyzeGraphQLQuery schemaTypes singleOperation静态分析每个字段的类型这正是 RFC 中基于 introspection schema 对查询中的每个字段做静态类型分析的落地实现其返回的Structure包含变量信息与选择集字段将端点 URL 规范化为/api/rest/path形式路径中的变量段用{varName}占位符表示为 operation 挂上描述endpointDescription、summary端点名、参数列表与响应定义。参数、请求体与响应体是如何生成的RFC 提出参数可从查询解析、响应体可从查询生成源码给出了精确的规则。参数ParameterscollectParamsOpenAPI.hs为查询中的每个标量变量生成一个可选参数规则如下允许进入参数列表的变量仅限已知标量类型InputFieldObjectInfo输入对象、InputFieldEnumInfo枚举与数组类型G.TypeList一律排除位置推断若变量名出现在端点 URL 的路径变量中REST 端点 URL 中以:前缀声明的变量则该参数位置为ParamPath路径参数否则为ParamQuery查询参数必填性路径参数始终必填非路径参数在无默认值且非可空时必填默认值GraphQL 变量默认值会被转换为 JSON 值并写入参数的default字段标量映射已知标量还附带正则 pattern例如uuid对应 UUID 格式校验。此外每个端点都会被注入xHasuraAdminSecret参数OpenAPI.hs它是一个 header 参数xHasuraAdminSecret :: Param xHasuraAdminSecret mempty name .~ x-hasura-admin-secret description ?~ Your x-hasura-admin-secret will be used for authentication of the API request. in_ .~ ParamHeader schema ?~ Inline (mempty type_ ?~ OpenApiString)这与 API 参考文档响应中的x-hasura-admin-secretheader 参数完全一致即 RFC V4 中通过 header 支持授权的具体实现。请求体Request BodybuildRequestBodyOpenAPI.hs的规则是只有当查询至少有一个变量且方法为POST/PUT/PATCH时才生成requestBodyGET 等方法的请求体在 OAS 中非法会被省略——尽管这类请求在服务端仍然被支持请求体是application/json内容类型的对象每个查询变量对应一个属性变量的 schema 由buildVariableSchemaOpenAPI.hs构建变量在有默认值、可空或为已知标量三者满足其一即为可选否则为必填有默认值时 schema 会被内联并附上default。输入对象input object与枚举变量虽然不进入参数列表但会作为请求体属性被声明并通过$ref引用到components.schemas。响应体ResponsebuildResponse与buildSelectionSchemaOpenAPI.hs根据查询的选择集selection set构建application/json响应 schema每个输出字段对应一个属性对象类型会被递归展开并标记nullable。这样响应体可以由查询与类型系统推导生成在代码层面得到完整印证。GraphQL 类型到 OpenAPI 类型的映射规则RFC 只给出了方向性的设想从查询和数据类型生成响应体而 OpenAPI.hs 给出了精确的映射表GraphQL 标量OpenAPI 类型Pattern正则是否内联Intinteger—内联Float/Doublenumber—内联Bool/Booleanboolean—内联String/IDstring—内联uuidstring[a-f0-9]{8}-[a-f0-9]{4}-4[a-f0-9]{3}-[89aAbB][a-f0-9]{3}-[a-f0-9]{12}引用声明其他自定义标量string带描述—引用声明实现细节getReferenceScalarInfoOpenAPI.hs值得注意标准标量Int/Float/String/Bool/ID 等直接内联为 OAS 内建类型uuid虽然映射为string但附带 UUID 格式的正则 pattern且以组件声明components.schemas引用而非内联任何未知的 GraphQL 标量都会在components.schemas中声明成一个带描述的string类型并返回引用。类型修饰符由applyModifiersOpenAPI.hs递归处理列表类型[T]被转换为type: arrayitems可空性统一映射为 OAS 的nullable。对象与枚举类型通过declareTypeOpenAPI.hs声明并利用GraphQL 类型名不允许!而 JSON 引用允许的特性用TypeName!形式区分非空类型与非空类型参见源码中的Note [Nullable types in OpenAPI]。如何服务 Swagger UI三种方案的权衡RFC 详细对比了三种 Swagger UI 服务方案并给出了选型矩阵OptionProsCons1. 直接暴露 Swagger JSON用户对 UI 有完全控制权不够友好2. 在/api/swagger用 CDN 托管 Swagger UI用户获得熟悉的 Swagger UI外部 CDN 带来安全暴露面3. 基于 OpenAPI JSON 自研 Swagger UI完全掌控 UI、可扩展、可复用遥测系统甚至可复用 GraphiQL 本地保存的 header需自建 UIbundle 体积可能增大可用代码分割缓解RFC 同时还提出了两个补充思路将 Swagger UIeditor.swagger.io嵌入iFrame或不经 CDN 直接托管静态 Swagger 文件来渲染 OpenAPI JSON。RFC 给出的 CDN 方案Option 2示例 HTML 如下!DOCTYPE html html langen head meta charsetUTF-8 meta nameviewport contentwidthdevice-width, initial-scale1.0 meta http-equivX-UA-Compatible contentieedge script srchttps://cdnjs.cloudflare.com/ajax/libs/swagger-ui/3.22.1/swagger-ui-standalone-preset.js/script script srchttps://cdnjs.cloudflare.com/ajax/libs/swagger-ui/3.22.1/swagger-ui-bundle.js/script link relstylesheet hrefhttps://cdnjs.cloudflare.com/ajax/libs/swagger-ui/3.22.1/swagger-ui.css / titleSwagger/title /head body div idswagger-ui/div script window.onload function() { SwaggerUIBundle({ url: /api/swagger/json, dom_id: #swagger-ui, presets: [ SwaggerUIBundle.presets.apis, SwaggerUIStandalonePreset ], layout: StandaloneLayout }) } /script /body /html其中url: /api/swagger/json直接指向 Hasura 暴露的 OAS 端点这意味着只要页面与 Hasura 同源或通过代理这份 HTML 即可开箱即用地渲染出带鉴权输入能力的 Swagger UI。RFC 的结论是当前阶段采用 Option 1——直接暴露 JSON。这与仓库现状一致服务端只提供GET /api/swagger/json一个端点用户既可以在 Swagger Editor 等外部工具中导入该 JSON也可以在 Console 中一键导出。基于角色的信息暴露与鉴权RFC V4RFC 的 V4 里程碑与Future Work中的两个开放问题——如何在交互式 UI 中处理鉴权、是否应基于用户角色暴露不同信息——在仓库中的答案可以概括为端点由onlyAdmin守卫即/api/swagger/json仅对 admin 角色可见App.hs 与 API 参考 双重确认每个 operation 自动携带x-hasura-admin-secretheader 参数供 Swagger UI 的鉴权输入使用OpenAPI.hs从源码结构看buildAllEndpoints使用的是scAdminIntrospection schemaCache即基于 admin 角色的 introspection 结果来静态分析字段类型因此当前生成的规范面向 admin 视角基于其他角色动态裁剪规范的能力尚未在生成链路中体现属于 RFC 中遗留的开放问题。从类型生成响应静态分析机制RFC 的如何从查询表示生成类型一节提到查询解析器解析查询后会借助 introspection schema 对查询中的每个字段做静态类型分析。对应到源码这一步由Hasura.GraphQL.Analyse模块的analyzeGraphQLQuery完成在 OpenAPI.hs 被调用其产物Structure同时服务于三条生成路径参数生成Structure中的变量信息_stVariables驱动collectParams与buildRequestBody响应生成Structure中的选择集字段fields驱动buildSelectionSchema默认值传播变量的 GraphQL 默认值经gqlToJsonValueOpenAPI.hs转换为 JSON 值写入参数的default与请求体属性的default保证参数可选性判断与真实 GraphQL 执行语义一致。也就是说整份 OAS 文档是查询文本 introspection schema的确定性推导结果不依赖任何运行时抽样或示例数据这正是该方案可测试、可预计算的根本原因。实战快速获取并消费 REST 端点的 OpenAPI 规范以下流程基于当前仓库的已交付能力确保已配置 RESTified Endpoint通过 Console 的REST页签或create_rest_endpoint元数据 API 创建端点例如将query MyQuery { users { first_name last_name } }保存为名为Fetch user data、URL 为users的 GET 端点。导出 OAS JSON二选一API 方式curl -H X-Hasura-Admin-Secret: secret http://hasura-host/api/swagger/jsonConsole 方式API→REST endpoints→Export OpenAPI Spec按钮export-oas.mdx。渲染与调试将导出的 JSON 粘贴到 Swagger Editor或在本地托管 RFC 提供的 Swagger UI HTML将url指向/api/swagger/json然后在 UI 的鉴权输入中填入x-hasura-admin-secret或 JWT即可直接Try it out。对接代码生成把 OAS JSON 交给 swagger-codegen 等工具可自动生成 REST 客户端代码实现GraphQL 查询定义一次、多语言客户端无限生成的协作流程。局限性与遗留问题RFC 末尾的开放问题在当前实现中仍有部分保留引用时需注意角色裁剪OAS 生成目前仅面向 admin 角色尚未实现按调用者角色动态裁剪端点与字段的规范输出UI 内置V5Console 内嵌 Swagger UI标注为可能不实现当前官方交付为 JSON 导出 外部工具渲染的组合自定义标量的表达力未知 GraphQL 标量统一降级为带描述的string若需要更精确的格式约束如日期、十进制精度需要在自定义标量层面补充描述或另行扩展映射表。关键源码索引RFC 原文rfcs/rest-openapi-integration.md核心生成实现server/src-lib/Hasura/Server/OpenAPI.hs路由与 admin 校验server/src-lib/Hasura/Server/App.hsAPI 参考响应示例docs/docs/api-reference/restified.mdxConsole 导出说明docs/docs/restified/export-oas.mdx赞分享后端API网关数据库GraphQL【免费下载链接】graphql-engineBlazing fast, instant realtime GraphQL APIs on all your data with fine grained access control, also trigger webhooks on database events.项目地址https://gitcode.com/gh_mirrors/gr/graphql-engine点击查看免费下载相关推荐Hasura graphql-engine replace_metadata API 警告机制从 RFC 设计到 MonadWarnings 落地实现Hasura graphql engine replace_metadata API 警告机制从 RFC 设计到 MonadWarnings 落地实现 本篇技后端API网关数据库GraphQLHasura GraphQL Engine 的 Apollo Federation v1 支持从 RFC 设计到源码实现Hasura GraphQL Engine 的 Apollo Federation v1 支持从 RFC 设计到源码实现 导读 本文以 rfcs/apollo后端API网关数据库GraphQLHasura GraphQL Engine 的 MSSQL 后端变更操作Mutations实现解析从 RFC 到源码落地Hasura GraphQL Engine 的 MSSQL 后端变更操作Mutations实现解析从 RFC 到源码落地 本篇文章围绕开源仓库 graph后端API网关数据库GraphQL创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考