-
Notifications
You must be signed in to change notification settings - Fork 318
Local GraphQLContext doesn't propagate values when spring actuator is active #1142
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
Which Spring GraphQL version are you using? This looks like a duplicate of #761 |
I'm on version 1.3.3 |
Something looks wrong with your code snippet. It's assuming that a local context exists and adds to it, whereas I believe that a new local context is supposed to be returned with the data fetcher result for the next data fetchers to consider. I have created a sample application and I'm not seeing any failure. Here's a package org.example.graphqlcontext;
import graphql.GraphQLContext;
import graphql.execution.DataFetcherResult;
import graphql.schema.DataFetcher;
import graphql.schema.DataFetchingEnvironment;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.graphql.execution.RuntimeWiringConfigurer;
@Configuration
public class GraphQlConfiguration {
@Bean
public RuntimeWiringConfigurer runtimeWiringConfigurer() {
return runtimeWiring -> {
runtimeWiring.type("Query", typeBuilder ->
typeBuilder.dataFetcher("bookById", environment -> {
GraphQLContext localContext = GraphQLContext.newContext()
.put("project", "spring-graphql")
.build();
return DataFetcherResult.newResult()
.data(new Book("test book", 42L))
.localContext(localContext)
.build();
}));
};
}
} As you can see, the schema mapping handler expects and finds a value in the local context: package org.example.graphqlcontext;
import graphql.GraphQLContext;
import graphql.schema.DataFetchingEnvironment;
import org.springframework.graphql.data.method.annotation.SchemaMapping;
import org.springframework.stereotype.Controller;
import org.springframework.util.Assert;
@Controller
public class TestController {
@SchemaMapping
public Author author(Book book, DataFetchingEnvironment environment) {
GraphQLContext localContext = (GraphQLContext) environment.getLocalContext();
String project = (String) localContext.get("project");
Assert.isTrue(project == "spring-graphql", "missing value from local context");
return new Author(book.authorId(), "Test author");
}
} This is for the following schema: type Query {
bookById(id: ID!): Book
}
type Book {
title: String
author: Author
}
type Author {
name: String
} I have tested this with and without actuator on the classpath. Please share a minimal sample application that reproduces the problem. Maybe your assumptions about the GraphQL local context are wrong in the first place? |
In my setup, I create and inject a context in a filter. Maybe this is an anti-pattern? Anyways, I'll try to reproduce my issue on a smaller demo during the weekend. Thanks for the feedback. |
If you would like us to look at this issue, please provide the requested information. If the information is not provided within the next 7 days this issue will be closed. |
Closing due to lack of requested feedback. If you would like us to look at this issue, please provide the requested information and we will re-open the issue. |
Sorry for taking so long. Here is my demo that illustrates my problem. My query.
The result will be the same, but I printed out a simple line.
|
Thanks for the repro, I can see now the problem. In graphql-java, the main GraphQL context is shared for the entire lifetime of the request. On the other hand, a local context is only local to the child data fetching operations. If you would like to provide a local context to the data fetching operations under the current one, you'll need to return a @SchemaMapping(typeName = "Query", field = "svc")
public DataFetcherResult<Svc> getSvc(DataFetchingEnvironment env, @Argument("id") Integer id) {
var infra = 1;
DataFetcherResult.Builder<Svc> resultBuilder = DataFetcherResult.newResult();
Svc svcName = new Svc().setName("svcName").setId(id);
if (env.getSelectionSet().contains("images")) {
GraphQLContext context = GraphQLContext.of(Map.of("svcId", id, "infraId", infra));
resultBuilder.localContext(context);
}
return resultBuilder.data(svcName).build();
} I've opened #1167 to see how we can document this and maybe consider an improvement to make this use case easier. Note: I do see a behavior difference with actuator vs. without actuator, but I have been debugging our |
Thanks, your example works! |
Uh oh!
There was an error while loading. Please reload this page.
On my controllers my code propagates values via local context, so something like this.
Which worked fine for my use-case.
But I noticed that my code breaks when I activate spring-actuator.
To elaborate, the local context would no longer have my values, and only contain 'micrometer.observation' values.
I read the documentations regarding contexts and observability but failed to find a fix.
I was wondering if this was intentional and I need some additional configuration to make my code work.
I haven't tested with global context values.
The text was updated successfully, but these errors were encountered: