Spring中GraphQL控制器为何使用@Controller而非@RestController?
核心原因是Spring GraphQL的请求处理模型和传统REST接口完全不同,@RestController的设计并不适配它的工作机制。
@RestController的本质是@Controller + @ResponseBody
@RestController的核心作用是让方法返回值直接通过消息转换器(比如Jackson)序列化成JSON/XML写入HTTP响应体——这是为传统REST接口设计的:每个接口对应独立的URL,返回固定结构的数据。Spring GraphQL是单端点统一处理请求
所有GraphQL的查询、变更请求都通过同一个端点(默认是/graphql)发送。控制器里的@QueryMapping/@MutationMapping注解,不是用来映射HTTP路径的,而是绑定GraphQL Schema中定义的字段。请求的解析、执行、响应的序列化,全由Spring GraphQL框架统一接管:- 框架先解析收到的GraphQL请求体,确定要执行的查询/变更
- 调用对应控制器中绑定的方法获取数据
- 把所有字段的结果整合后,统一序列化成JSON响应返回
@Controller完全满足需求,@RestController反而多余
@Controller只是标记类为Spring MVC的控制器组件,Spring GraphQL已经通过自身的机制完成了响应的处理,不需要@ResponseBody的功能。如果用@RestController,反而可能引入不必要的逻辑:比如某些场景下,框架可能会把方法返回值直接当成REST响应返回,而不是交给GraphQL引擎处理,导致错误。
拿你给出的代码举例:bookById方法返回的Book对象,并不是直接写到HTTP响应体里,而是作为GraphQL查询bookById的结果,和author方法返回的Author一起,被框架整合为符合GraphQL规范的JSON响应。
另外纠正一个常见误解:@Controller不是只能返回HTML,它只是Spring MVC控制器的基础注解,配合不同的处理器可以返回任意格式的数据;@RestController只是简化了REST场景下的配置,并非返回JSON的唯一方式。
内容的提问来源于stack exchange,提问作者Spongi

