Reputation: 43
I have a project running with Spring Boot and have implemented a GraphQL API with com.graphql-java.graphql-java:12.0.
I want to set the field visibility for some Mutators and maybe some fields now, but unfortunately I find no tutorial, doc or example where I find a working explanation how to to this.
For explanation, I have following example entries in schema:
type Query {
login(username: String!, password: String!): String
organization(id: Int!): ApiOrganization
}
type Mutation {
updateProfile(profileData: ProfileInputDto): ID
updateAdminStuff(adminData: AdminStuffDto): ID
}
The Query entries shall now be visible in the schema for all users who use the api and also the Mutation to updateProfile shall be visible. But the Mutation updateAdminStuff shall only be visible if the user is logged in as Admin Role, so that a normal user doesn't even know that this mutation exists. Additionally it can happen that only some fields of some schema types shall be made visible for some roles only.
I found out that there is a chance to set something like that by GraphqlFieldVisibility (https://www.graphql-java.com/documentation/v12/fieldvisibility/). First versions I found said to set it in GraphQLSchema, but there it seems deprecated and I should use GraphQLCodeRegistry to set the visibility. For GraphQLCodeRegistry I found out on https://www.graphql-java.com/documentation/v12/execution/
GraphQLCodeRegistry codeRegistry = newCodeRegistry()
.dataFetcher(
coordinates("CreateReviewForEpisodeMutation", "createReview"),
mutationDataFetcher()
)
.build();
GraphQLSchema schema = GraphQLSchema.newSchema()
.query(queryType)
.mutation(createReviewForEpisodeMutation)
.codeRegistry(codeRegistry)
.build();
But unfortunately I find no way to set this method for the schema generation I use.
Can someone please give me a hint (example, tutorial, documentation) where I can find a tipp for soulution? (if something is possible at all in GraphQL)
Here some additional infos about the project: I have a schmea definition saved as schema.graphqls. I have a GraphQLProvider and it prepares the Scehma and a GraphQL the following way:
private GraphQL graphQL;
@Bean
public GraphQL graphQL() {
return graphQL;
}
@PostConstruct
public void init() throws IOException {
URL url = Resources.getResource("graphql/schema.graphqls");
String sdl = Resources.toString(url, Charsets.UTF_8);
GraphQLSchema graphQLSchema = buildSchema(sdl);
this.graphQL = GraphQL.newGraphQL(graphQLSchema).build();
}
private GraphQLSchema buildSchema(String sdl) {
TypeDefinitionRegistry typeRegistry = new SchemaParser().parse(sdl);
RuntimeWiring runtimeWiring = buildWiring();
SchemaGenerator schemaGenerator = new SchemaGenerator();
return schemaGenerator.makeExecutableSchema(typeRegistry, runtimeWiring);
}
In my controller I fetch the data by
ExecutionInput executionInput = ExecutionInput.newExecutionInput().context(request).query(body.getQuery())
.build();
ExecutionResult executionResult = graphQL.execute(executionInput);
where body is a GraphQLQuery and graphQL is the bean of the code before.
Thanks for your help and best regards.
Upvotes: 1
Views: 1418
Reputation: 43
Ok got the answer in the GraphQL-Java chat.
I used this tutorial https://www.graphql-java.com/tutorials/getting-started-with-spring-boot/ to build the graphQl API and using this I build the runtime wiring by myself and there I can set the visibility.
I now implemented it this way:
GraphqlFieldVisibility blockedFields = BlockedFields.newBlock()
.addPattern("ApiField.secretfield")
.addPattern(".*\\.secretAdminMutation")
.build();
private RuntimeWiring buildWiring() {
return RuntimeWiring.newRuntimeWiring().fieldVisibility(blockedFields)....
and it works great!
Upvotes: 1