GraphQL 接口实验(U50)
独立新增工程:Liberica JDK21.0.11+11、Boot4.0.9 / Framework7.0.10、Spring for GraphQL 2.0.6、graphql-java 25.1、Spring Security 7.0.8、H2 2.4.240(全部由 Boot 4.0.9 parent/BOM 管理)。本机 macOS27.2 arm64。全部测试在进程内真实 HTTP(随机端口)与真实 spring-graphql 执行引擎上运行;H2 内存库按测试重置,数据全部合成;无外部服务依赖。
从仓库根运行完整公开入口:
JAVA_HOME=$(/usr/libexec/java_home -v21) python3 labs/graphql-interface/run.py入口记录 JDK/Maven、执行 clean test、核对 Surefire 计数(7 测试)、8 条 U50 观察行(每条恰好一次)、解析依赖版本并强制与 BOM 一致(spring-graphql 2.0.6、graphql-java 25.1、spring-boot-graphql 4.0.9、security-core 7.0.8、h2 2.4.240),写入 evidence。
教材:GraphQL 接口与 N+1。
公开工程:根 POM、runner、schema、控制器、SQL 仓库、BatchLoader 配置、安全与错误、租户拦截器、执行测试、运行证据。
| 组 | 真实运行入口 | 实际观察 |
|---|---|---|
| schema/resolver/租户 | 真实 HTTP POST /graphql + HttpGraphQlTester | books 查询返回 3 本(tenant-a);X-Tenant=tenant-b 只返回 1 本 SECRET——租户过滤在 SQL where,不在 GraphQL 参数 |
| 校验与错误 | 同一端点 | @Valid 空 title → errors 含「输入不合法」且 HTTP 仍 200;未知字段 bogusField → 校验错误;未处理 NumberFormatException → 不透明 INTERNAL_ERROR(不泄漏细节) |
| 鉴权两层 | 真实 Security 链 | 匿名 → 401(未进 GraphQL);alice(READER) 调 addBook → FORBIDDEN error(HTTP 200);admin → 成功写入 |
| N+1 | 自建 SqlCounter | books+author 每书一查 = 1+3 = 4 条 SQL;authorBatch(@BatchMapping) = 1+1 = 2 条;BatchLoaderRegistry 显式 DataLoader 批函数 1 次调用、收到 2 个去重 key(5 次 load) |
7 个测试全部通过真实 HTTP 与真实执行引擎观察行为:没有 mock GraphQlSource,没有 stub Security 链,没有假数据库。H2 是真实 JDBC 驱动与真实 SQL,每个测试重置表。
本机环境(一次运行的实际值)
BellSoft Liberica JDK 21.0.11、Maven 3.9.9、macOS 27.2.0 arm64;Boot 4.0.9、spring-graphql 2.0.6、graphql-java 25.1、Spring Security 7.0.8、H2 2.4.240。实际解析版本、退出码、观察行与文件 SHA-256 见入口生成的 evidence/u50-*.json。
边界
- 只跑 HTTP POST transport;WebSocket 订阅、SSE、multipart、RSocket transport 未运行。
- GraphiQL 与 schema printer 关闭(生产默认);未运行浏览器 GraphiQL 交互。
- 未运行 federation、Connection 分页适配、maxBatchSize 分批、query 深度/复杂度限制、instrumentation 与指标导出。
- N+1 观察基于自建 SqlCounter(每 SQL 一次计数),不是数据库 profile;未做吞吐/延迟压测。
- 租户上下文同时写 GraphQLContext 与 ThreadLocal 以演示陷阱;生产级异步 resolver 应只依赖 GraphQLContext。
- 只使用合成数据与进程内资源;不写用户数据,不触碰本机其他服务。
已知未运行
WebSocket 订阅与取消、上传(multipart)、RSocket、federation、分页 Connection、查询复杂度预算、AOT/native、多实例与外部认证服务器,均未在本实验运行;对应结论按教材标注为源码/配置推演或待验证。