如何使用 graphql-spring-boot 向 GraphQL Java 添加检测?

Posted

技术标签:

【中文标题】如何使用 graphql-spring-boot 向 GraphQL Java 添加检测?【英文标题】:How to add instrumentation to GraphQL Java with graphql-spring-boot? 【发布时间】:2020-05-16 04:49:40 【问题描述】:

有人知道在使用 graphql-spring-boot (https://github.com/graphql-java-kickstart/graphql-spring-boot) 时如何将检测添加到 GraphQL 执行吗?我知道使用普通的 graphql-java 是如何实现的:https://www.graphql-java.com/documentation/v13/instrumentation/

但是,当使用 graphql-spring-boot 并控制执行时,我不知道该怎么做。由于缺乏文档,我只是这样尝试:

@Service
public class GraphQLInstrumentationProvider implements InstrumentationProvider 
    @Override
    public Instrumentation getInstrumentation() 
        return SimpleInstrumentation.INSTANCE;
    

但我的 InstrumentationProvider bean 上的 getInstrumentation 方法(如预期的那样)从未被调用过。任何帮助表示赞赏。

【问题讨论】:

【参考方案1】:

有一种更简单的方法可以通过 spring boot 添加检测:

@Configuration
public class InstrumentationConfiguration 
    @Bean
    public Instrumentation someFieldCheckingInstrumentation() 
        return new FieldValidationInstrumentation(env -> 
            // ... 
        );
    

Spring boot 将收集所有实现 Instrumentation 的 bean(参见 GraphQLWebAutoConfiguration)。

【讨论】:

【参考方案2】:

回答我自己的问题。与此同时,我设法做到了:

final class RequestLoggingInstrumentation extends SimpleInstrumentation 

    private static final Logger logger = LoggerFactory.getLogger(RequestLoggingInstrumentation.class);

    @Override
    public InstrumentationContext<ExecutionResult> beginExecution(InstrumentationExecutionParameters parameters) 
        long startMillis = System.currentTimeMillis();
        var executionId = parameters.getExecutionInput().getExecutionId();

        if (logger.isInfoEnabled()) 
            logger.info("GraphQL execution  started", executionId);

            var query = parameters.getQuery();
            logger.info("[] query: ", executionId, query);
            if (parameters.getVariables() != null && !parameters.getVariables().isEmpty()) 
                logger.info("[] variables: ", executionId, parameters.getVariables());
            
        

        return new SimpleInstrumentationContext<>() 
            @Override
            public void onCompleted(ExecutionResult executionResult, Throwable t) 
                if (logger.isInfoEnabled()) 
                    long endMillis = System.currentTimeMillis();

                    if (t != null) 
                        logger.info("GraphQL execution  failed: ", executionId, t.getMessage(), t);
                     else 
                        var resultMap = executionResult.toSpecification();
                        var resultJSON = ObjectMapper.pojoToJSON(resultMap).replace("\n", "\\n");
                        logger.info("[] completed in ms", executionId, endMillis - startMillis);
                        logger.info("[] result: ", executionId, resultJSON);
                    
                
            
        ;
    


@Service
class InstrumentationService 

    private final ContextFactory contextFactory;

    InstrumentationService(ContextFactory contextFactory) 
        this.contextFactory = contextFactory;
    

    /**
     * Return all instrumentations as a bean.
     * The result will be used in class @link com.oembedler.moon.graphql.boot.GraphQLWebAutoConfiguration.
     */
    @Bean
    List<Instrumentation> instrumentations() 
        // Note: Due to a bug in GraphQLWebAutoConfiguration, the returned list has to be modifiable (it will be sorted)
        return new ArrayList<>(
                List.of(new RequestLoggingInstrumentation()));
    


它帮助我了解了GraphQLWebAutoConfiguration 课程。在那里我发现框架需要一个 List&lt;Instrumentation&gt; 类型的 bean,其中包含将添加到 GraphQL 执行的所有工具。

【讨论】:

以上是关于如何使用 graphql-spring-boot 向 GraphQL Java 添加检测?的主要内容,如果未能解决你的问题,请参考以下文章

无法使用 graphql-spring 初始化代理

GraphQL Spring-boot 查询过滤

拦截器在 Spring Boot GraphQL 中不起作用

[精选] Mysql分表与分库如何拆分,如何设计,如何使用

如果加入条件,我该如何解决。如果使用字符串连接,我如何使用

如何使用本机反应创建登录以及如何验证会话