java - Automatically enforcing GraphQL directives with Spring GraphQL - Stack Overflow

I wondering if it is possible to automatically enforce GraphQL directive in Spring GraphQL.My schema i

I wondering if it is possible to automatically enforce GraphQL directive in Spring GraphQL.

My schema is

directive @validateUserId on ARGUMENT_DEFINITION
type Mutation {
  addBook(userId: ID! @validateUserId , name:String, pageCount:Int, author:NewAuthorInput): Book
}

Mutation handler in my controller:

@MutationMapping
  public Book addBook(@Argument UUID userId, @Argument String name, @Argument Integer pageCount, @NotNull @Argument NewAuthorInput author, DataFetchingEnvironment environment) {
    ValidateUserIdDirective.validateUserId(environment);

    Author newAuthor = bookService.addAuthor(author.getFirstName(), author.getLastName());
    return bookService.addBook(name, pageCount, newAuthor);
  }

and my directive wiring:

@Component
public class ValidateUserIdDirective implements SchemaDirectiveWiring {

  @Override
  public GraphQLArgument onArgument(SchemaDirectiveWiringEnvironment<GraphQLArgument> environment) {
    return environment.getElement();
  }

  public static void validateUserId(DataFetchingEnvironment environment) {
    UUID providedUserId = UUID.fromString(Objects.requireNonNull(environment.getArgument("userId")));
   // do something with user id
  
  }
}

In this code I explicitly calling ValidateUserIdDirective.validateUserId(environment); in my mutation handler. I am wondering if there is a way to automatically validate user directive without making any explicit calls?

I wondering if it is possible to automatically enforce GraphQL directive in Spring GraphQL.

My schema is

directive @validateUserId on ARGUMENT_DEFINITION
type Mutation {
  addBook(userId: ID! @validateUserId , name:String, pageCount:Int, author:NewAuthorInput): Book
}

Mutation handler in my controller:

@MutationMapping
  public Book addBook(@Argument UUID userId, @Argument String name, @Argument Integer pageCount, @NotNull @Argument NewAuthorInput author, DataFetchingEnvironment environment) {
    ValidateUserIdDirective.validateUserId(environment);

    Author newAuthor = bookService.addAuthor(author.getFirstName(), author.getLastName());
    return bookService.addBook(name, pageCount, newAuthor);
  }

and my directive wiring:

@Component
public class ValidateUserIdDirective implements SchemaDirectiveWiring {

  @Override
  public GraphQLArgument onArgument(SchemaDirectiveWiringEnvironment<GraphQLArgument> environment) {
    return environment.getElement();
  }

  public static void validateUserId(DataFetchingEnvironment environment) {
    UUID providedUserId = UUID.fromString(Objects.requireNonNull(environment.getArgument("userId")));
   // do something with user id
  
  }
}

In this code I explicitly calling ValidateUserIdDirective.validateUserId(environment); in my mutation handler. I am wondering if there is a way to automatically validate user directive without making any explicit calls?

Share Improve this question asked Mar 25 at 19:45 MrkKMrkK 9033 gold badges12 silver badges25 bronze badges
Add a comment  | 

2 Answers 2

Reset to default 0

Instead of manually calling ValidateUserIdDirective.validateUserId(environment) in your @MutationMapping method, you can modify your ValidateUserIdDirective to intercept the DataFetcher for the field and apply the validation logic automatically.

This is done by wiring the directive at the schema level and modifying the DataFetcher behavior.

import graphql.schema.*;
import .springframework.graphql.execution.SchemaDirectiveWiring;
import .springframework.stereotype.Component;
import graphql.schema.idl.SchemaDirectiveWiringEnvironment;

import java.util.Objects;
import java.util.UUID;

@Component
public class ValidateUserIdDirective implements SchemaDirectiveWiring {

    @Override
    public GraphQLArgument onArgument(SchemaDirectiveWiringEnvironment<GraphQLArgument> environment) {
        GraphQLArgument argument = environment.getElement();
        GraphQLFieldDefinition field = environment.getFieldDefinition();

        DataFetcher<?> originalDataFetcher = environment.getCodeRegistry().getDataFetcher(
            (GraphQLObjectType) field.getParentType(), field);

        DataFetcher<?> wrappedDataFetcher = dataFetchingEnvironment -> {
            String userIdArg = dataFetchingEnvironment.getArgument("userId");
            validateUserId(userIdArg);
            return originalDataFetcher.get(dataFetchingEnvironment);
        };

        // Register the wrapped DataFetcher in the CodeRegistry
        environment.getCodeRegistry().dataFetcher(
            (GraphQLObjectType) field.getParentType(), field, wrappedDataFetcher);

        return argument; 
    }

    private void validateUserId(String userId) {
        UUID providedUserId = UUID.fromString(Objects.requireNonNull(userId));
        // Add your validation logic here
        System.out.println("Validated userId: " + providedUserId);
    }
}

I solved the problem by correct registration of my wiring directive:

@Bean
public RuntimeWiringConfigurer runtimeWiringConfigurer(ValidateUserIdDirective validateUserIdDirective) {
  return wiringBuilder -> wiringBuilder
          .directive("validateUserId", validateUserIdDirective);
}

发布者:admin,转转请注明出处:http://www.yc00.com/questions/1744172846a4561618.html

相关推荐

发表回复

评论列表(0条)

  • 暂无评论

联系我们

400-800-8888

在线咨询: QQ交谈

邮件:admin@example.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信