I have a spring boot application running with a graphql endpoint that validates and executes queries and mutations, however, I need to read one header in the incoming message in order to pass its value to another endpoint. Is there a way in graphql to read these values? some sort of getHeaders or something like that?
GraphQL should be placed after all authentication middleware, so that you have access to the same session and user information you would in your HTTP endpoint handlers. HTTP is commonly associated with REST, which uses "resources" as its core concept. In contrast, GraphQL's conceptual model is an entity graph.
To read HTTP Request Header in Spring Boot REST application we use @RequestHeader annotation. For example, let’s assume we need to create a method in our Rest Controller class that accepts HTTP Get Request with two headers and returns these same headers back in a Response Body. To break it down in steps I will need to:
Your GraphQL HTTP server should handle the HTTP GET and POST methods. When receiving an HTTP GET request, the GraphQL query should be specified in the "query" query string.
Consider you use graphql-spring-boot and graphql-java-tools , and assuming that you does not customize GraphQLContext , you can try to add DataFetchingEnvironment argument to your resolver function and then get the GraphQLContext from it. You can then get HttpServletRequest from the context and access the headers :
GraphQL itself does not define any things related to how to expose it over the network , so it does not define any things related to get HTTP header.It is up to developers to use their ways.So, it depends on the underlaying technologies you use to serve GraphQL over HTTP.
Consider you use graphql-spring-boot and graphql-java-tools
, and assuming that you does not customize GraphQLContext
, you can try to add DataFetchingEnvironment
argument to your resolver function and then get the GraphQLContext
from it. You can then get HttpServletRequest
from the context and access the headers :
public Foo resolveFoo(Map<String,String> input , DataFetchingEnvironment env){
GraphQLContext context = env.getContext();
HttpServletRequest request = context.getHttpServletRequest().get();
request.getHeader("content-type");
}
The solution by @Ken Chan was not working for me. GraphQLContext
had no method named getHttpServletRequest
.
Solved it by using GraphQLServletContext
instead. You can change the code to:
public Foo resolveFoo(Map<String,String> input , DataFetchingEnvironment env){
GraphQLServletContext context = env.getContext();
String header = context.getHttpServletRequest().getHeader("content-type");
}
Apparently the type of the context is not standardized. I use SPQR, and in my case I discovered (via debug):
DefaultGlobalContext<ServletWebRequest> context = handlerParameters.getDataFetchingEnvironment().getContext();
context.getNativeRequest().getHeader("something");
Not a direct answer to your problem statement, but one can use a Filter to handle it before the request hits the resolver endpoints (if that's a requirement):
public class HeaderFilter implements Filter {
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) {
final HttpServletRequest httpServletRequest = (HttpServletRequest) servletRequest;
String headerVal= httpServletRequest.getHeader("<header string>");
try {
filterChain.doFilter(httpServletRequest, servletResponse);
} catch (IOException | ServletException e) {
//handle as you wish
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With