|
对于最新稳定版本,请使用 Spring GraphQL 2.0.0! |
服务器传输
Spring for GraphQL 支持通过 HTTP、WebSocket 和 罗克特。
HTTP
GraphQLHttpHandler通过HTTP请求处理GraphQL,并将请求执行委托给拦截链。有两种变体,一种是
春季MVC和春季WebFlux。两者都异步处理请求,并且
等效功能,但分别依赖于分组与非分组I/O,满足
编写HTTP响应。
请求必须使用 HTTP POST 和“application/json”作为内容类型和GraphQL请求详情
在请求正体中包含了 JSON,这在拟议的 GraphQL over HTTP 规范中定义。
一旦 JSON 正体成功解码,HTTP 响应状态始终为 200(OK),
而GraphQL请求执行中的任何错误都会出现在GraphQL响应的“错误”部分。
默认且首选的媒体类型为“application/graphql-response+json”但“application/json”也支持,如规范中所述。
GraphQLHttpHandler可以通过声明路由器功能豆子和使用路由器功能从Spring MVC或WebFlux创建路线。启动Starters就是这样做的,详见 Web 端点部分
细节,或者检查GraphQlWebMvcAutoConfiguration或GraphQlWebFluxAutoConfiguration它包含了实际配置。
该仓库的 1.0.x 分支包含一个 Spring MVC HTTP 示例应用程序。
文件上传
作为一种协议,GraphQL 专注于文本数据的交换。这不包括二进制 但存在一个独立的非正式 graphql-multipart-request-spec,允许通过 HTTP 上传 GraphQL 文件。
Spring for GraphQL 不支持GraphQL-multipart-request-spec径直。
虽然规范确实提供了统一的 GraphQL API 的优势,但实际体验是
引发了许多问题,并且已经制定了最佳实践建议,详见阿波罗服务器文件上传最佳实践,以了解更多详细讨论。
如果你想使用GraphQL-multipart-request-spec在你的申请中,你可以
通过 multipart-spring-graphql 库来实现。
WebSocket
GraphQlWebSocketHandler基于 graphql-ws 库定义的协议,通过 WebSocket 处理 GraphQL 请求。使用的主要原因
基于WebSocket的GraphQL是一种订阅方式,允许发送GraphQL流
但也可以用于普通的单一回答查询。
处理器将每个请求委派给拦截链以供进一步处理
请求执行。
|
基于WebSocket的GraphQL协议
有两个这样的协议,一个在 subscriptions-transport-ws 库中,另一个在 graphql-ws 库中。前者不活跃, 后者继任。阅读这篇博客文章了解历史。 |
有两种变体GraphQlWebSocketHandler一个用于春季MVC,另一个用于
春季网络流。两者都异步处理请求,且功能等效。
WebFlux 处理器还使用非阻塞的输入输出和反压来流式消息,
这很有效,因为在GraphQL Java中,订阅响应是响应式流发行人.
这GraphQL-WS项目列出了许多供客户使用的配方。
GraphQlWebSocketHandler可以通过声明SimpleUrlHandlerMapping并用它来映射处理器到 URL 路径。默认情况下,
Boot Starter 不通过 WebSocket 暴露 GraphQL 端点,但很容易
通过添加端点路径属性来启用它。详情请参阅Web Endpoints部分,或查看GraphQlWebMvcAutoConfiguration或者GraphQlWebFluxAutoConfiguration用于实际启动启动配置。
该仓库的 1.0.x 分支包含一个 WebFlux WebSocket 示例应用。
RSocket
GraphQLRSocketHandler通过RSocket处理GraphQL请求。查询和变异为
预期并作为 RSocket 进行处理请求-响应订阅期间的互动
处理方式为请求流.
GraphQLRSocketHandler可以使用 来自@Controller映射为
GraphQL 请求的路由。例如:
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 引擎 之前和之后拦截请求 打电话处理一个请求。
WebGraphQl拦截器
HTTP和WebSocket传输调用了一条链
0 或更多WebGraphQl拦截器,后面接着一个ExecutionGraphQLService那就是打电话
GraphQL Java 引擎。WebGraphQl拦截器允许应用程序拦截
收到请求,并执行以下之一:
-
请查看HTTP请求详情
-
自定义
GraphQL。执行输入 -
添加HTTP响应头
-
自定义
GraphQL。执行结果
例如,拦截器可以将HTTP请求头传递给数据费彻:
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由一位控制者主持:
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:
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)引入,参见网页端点。
RSocketQl拦截者
似WebGraphQl拦截器一RSocketQl拦截者允许截获
GraphQL 在 RSocket 上请求,运行前后 GraphQL Java 引擎。你可以使用
这样可以自定义GraphQL。执行输入以及GraphQL。执行结果.