对于最新稳定版本,请使用 Spring GraphQL 2.0.0spring-doc.cadn.net.cn

服务器传输

Spring for GraphQL 支持通过 HTTP、WebSocket 和 罗克特。spring-doc.cadn.net.cn

HTTP

GraphQLHttpHandler通过HTTP请求处理GraphQL,并将请求执行委托给拦截链。有两种变体,一种是 春季MVC和春季WebFlux。两者都异步处理请求,并且 等效功能,但分别依赖于分组与非分组I/O,满足 编写HTTP响应。spring-doc.cadn.net.cn

请求必须使用 HTTP POST 和“application/json”作为内容类型和GraphQL请求详情 在请求正体中包含了 JSON,这在拟议的 GraphQL over HTTP 规范中定义。 一旦 JSON 正体成功解码,HTTP 响应状态始终为 200(OK), 而GraphQL请求执行中的任何错误都会出现在GraphQL响应的“错误”部分。 默认且首选的媒体类型为“application/graphql-response+json”“application/json”也支持,如规范中所述。spring-doc.cadn.net.cn

GraphQLHttpHandler可以通过声明路由器功能豆子和使用路由器功能从Spring MVC或WebFlux创建路线。启动Starters就是这样做的,详见 Web 端点部分 细节,或者检查GraphQlWebMvcAutoConfigurationGraphQlWebFluxAutoConfiguration它包含了实际配置。spring-doc.cadn.net.cn

该仓库的 1.0.x 分支包含一个 Spring MVC HTTP 示例应用程序。spring-doc.cadn.net.cn

文件上传

作为一种协议,GraphQL 专注于文本数据的交换。这不包括二进制 但存在一个独立的非正式 graphql-multipart-request-spec,允许通过 HTTP 上传 GraphQL 文件。spring-doc.cadn.net.cn

Spring for GraphQL 不支持GraphQL-multipart-request-spec径直。 虽然规范确实提供了统一的 GraphQL API 的优势,但实际体验是 引发了许多问题,并且已经制定了最佳实践建议,详见阿波罗服务器文件上传最佳实践,以了解更多详细讨论。spring-doc.cadn.net.cn

如果你想使用GraphQL-multipart-request-spec在你的申请中,你可以 通过 multipart-spring-graphql 库来实现。spring-doc.cadn.net.cn

WebSocket

GraphQlWebSocketHandler基于 graphql-ws 库定义的协议,通过 WebSocket 处理 GraphQL 请求。使用的主要原因 基于WebSocket的GraphQL是一种订阅方式,允许发送GraphQL流 但也可以用于普通的单一回答查询。 处理器将每个请求委派给拦截链以供进一步处理 请求执行。spring-doc.cadn.net.cn

基于WebSocket的GraphQL协议

有两个这样的协议,一个在 subscriptions-transport-ws 库中,另一个在 graphql-ws 库中。前者不活跃, 后者继任。阅读这篇博客文章了解历史。spring-doc.cadn.net.cn

有两种变体GraphQlWebSocketHandler一个用于春季MVC,另一个用于 春季网络流。两者都异步处理请求,且功能等效。 WebFlux 处理器还使用非阻塞的输入输出和反压来流式消息, 这很有效,因为在GraphQL Java中,订阅响应是响应式流发行人.spring-doc.cadn.net.cn

GraphQL-WS项目列出了许多供客户使用的配方spring-doc.cadn.net.cn

GraphQlWebSocketHandler可以通过声明SimpleUrlHandlerMapping并用它来映射处理器到 URL 路径。默认情况下, Boot Starter 不通过 WebSocket 暴露 GraphQL 端点,但很容易 通过添加端点路径属性来启用它。详情请参阅Web Endpoints部分,或查看GraphQlWebMvcAutoConfiguration或者GraphQlWebFluxAutoConfiguration用于实际启动启动配置。spring-doc.cadn.net.cn

该仓库的 1.0.x 分支包含一个 WebFlux WebSocket 示例应用。spring-doc.cadn.net.cn

RSocket

GraphQLRSocketHandler通过RSocket处理GraphQL请求。查询和变异为 预期并作为 RSocket 进行处理请求-响应订阅期间的互动 处理方式为请求流.spring-doc.cadn.net.cn

GraphQLRSocketHandler可以使用 来自@Controller映射为 GraphQL 请求的路由。例如:spring-doc.cadn.net.cn

import java.util.Map;

import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;

import org.springframework.graphql.server.GraphQlRSocketHandler;
import org.springframework.messaging.handler.annotation.MessageMapping;
import org.springframework.stereotype.Controller;

@Controller
public class GraphQlRSocketController {

	private final GraphQlRSocketHandler handler;

	GraphQlRSocketController(GraphQlRSocketHandler handler) {
		this.handler = handler;
	}

	@MessageMapping("graphql")
	public Mono<Map<String, Object>> handle(Map<String, Object> payload) {
		return this.handler.handle(payload);
	}

	@MessageMapping("graphql")
	public Flux<Map<String, Object>> handleSubscription(Map<String, Object> payload) {
		return this.handler.handleSubscription(payload);
	}
}

拦截

服务器传输允许在 GraphQL Java 引擎 之前和之后拦截请求 打电话处理一个请求。spring-doc.cadn.net.cn

WebGraphQl拦截器

HTTPWebSocket传输调用了一条链 0 或更多WebGraphQl拦截器,后面接着一个ExecutionGraphQLService那就是打电话 GraphQL Java 引擎。WebGraphQl拦截器允许应用程序拦截 收到请求,并执行以下之一:spring-doc.cadn.net.cn

例如,拦截器可以将HTTP请求头传递给数据费彻:spring-doc.cadn.net.cn

import java.util.Collections;

import reactor.core.publisher.Mono;

import org.springframework.graphql.data.method.annotation.ContextValue;
import org.springframework.graphql.data.method.annotation.QueryMapping;
import org.springframework.graphql.server.WebGraphQlInterceptor;
import org.springframework.graphql.server.WebGraphQlRequest;
import org.springframework.graphql.server.WebGraphQlResponse;
import org.springframework.stereotype.Controller;

class RequestHeaderInterceptor implements WebGraphQlInterceptor { (1)

	@Override
	public Mono<WebGraphQlResponse> intercept(WebGraphQlRequest request, Chain chain) {
		String value = request.getHeaders().getFirst("myHeader");
		request.configureExecutionInput((executionInput, builder) ->
				builder.graphQLContext(Collections.singletonMap("myHeader", value)).build());
		return chain.next(request);
	}
}

@Controller
class MyContextValueController { (2)

	@QueryMapping
	Person person(@ContextValue String myHeader) {
		...
	}
}
1 拦截器将HTTP请求头值添加到GraphQLContext中
2 数据控制器方法访问该值

反之,拦截器也可以访问添加到GraphQLContext由一位控制者主持:spring-doc.cadn.net.cn

import graphql.GraphQLContext;
import reactor.core.publisher.Mono;

import org.springframework.graphql.data.method.annotation.QueryMapping;
import org.springframework.graphql.server.WebGraphQlInterceptor;
import org.springframework.graphql.server.WebGraphQlRequest;
import org.springframework.graphql.server.WebGraphQlResponse;
import org.springframework.http.HttpHeaders;
import org.springframework.http.ResponseCookie;
import org.springframework.stereotype.Controller;

// Subsequent access from a WebGraphQlInterceptor

class ResponseHeaderInterceptor implements WebGraphQlInterceptor {

	@Override
	public Mono<WebGraphQlResponse> intercept(WebGraphQlRequest request, Chain chain) { (2)
		return chain.next(request).doOnNext((response) -> {
			String value = response.getExecutionInput().getGraphQLContext().get("cookieName");
			ResponseCookie cookie = ResponseCookie.from("cookieName", value).build();
			response.getResponseHeaders().add(HttpHeaders.SET_COOKIE, cookie.toString());
		});
	}
}

@Controller
class MyCookieController {

	@QueryMapping
	Person person(GraphQLContext context) { (1)
		context.put("cookieName", "123");
		...
	}
}
1 Controller为GraphQLContext
2 拦截者使用该值添加HTTP响应头部

WebGraphQLHandler可以修改执行结果例如,用于检查和修改 请求验证错误,这些错误在执行开始前引发,且无法 处理方式为DataFetcherExceptionResolver:spring-doc.cadn.net.cn

import java.util.List;

import graphql.GraphQLError;
import graphql.GraphqlErrorBuilder;
import reactor.core.publisher.Mono;

import org.springframework.graphql.server.WebGraphQlInterceptor;
import org.springframework.graphql.server.WebGraphQlRequest;
import org.springframework.graphql.server.WebGraphQlResponse;

class RequestErrorInterceptor implements WebGraphQlInterceptor {

	@Override
	public Mono<WebGraphQlResponse> intercept(WebGraphQlRequest request, Chain chain) {
		return chain.next(request).map((response) -> {
			if (response.isValid()) {
				return response; (1)
			}

			List<GraphQLError> errors = response.getErrors().stream() (2)
					.map((error) -> {
						GraphqlErrorBuilder<?> builder = GraphqlErrorBuilder.newError();
						// ...
						return builder.build();
					})
					.toList();

			return response.transform((builder) -> builder.errors(errors).build()); (3)
		});
	}
}
1 如果,则返回相同结果执行结果具有一个非空值的“data”键
2 检查并转换GraphQL错误
3 更新执行结果带有修正错误

WebGraphQLHandler配置WebGraphQl拦截器链。这是有支持的 由启动Starters(Boot Starter)引入,参见网页端点spring-doc.cadn.net.cn

RSocketQl拦截者

WebGraphQl拦截器RSocketQl拦截者允许截获 GraphQL 在 RSocket 上请求,运行前后 GraphQL Java 引擎。你可以使用 这样可以自定义GraphQL。执行输入以及GraphQL。执行结果.spring-doc.cadn.net.cn