zoukankan      html  css  js  c++  java
  • GraphQL Java

    Instrumentation拦截器

    通过实现Instrumentation接口,可以观察一个query的执行,或修改运行期的行为。

    最常见的用途是进行性能监控,和自定义日志记录,但它也可以用于完成其他任务。

    创建GraphQL对象时,可以绑定相关的Instrumentation实现。

            GraphQL.newGraphQL(schema)
                    .instrumentation(new TracingInstrumentation())
                    .build();
    

    自定义Instrumentation拦截器

    Instrumentation实现类需要实现"begin"开头的方法。这个方法会在查询执行的过程中,在每个步骤开始之前被调用。

    每个回调方法都必须返回一个非空的InstrumentationContext对象,这个对象在本执行步骤完成时会被回调,并告知是否调用成功或是出错(可以获取Throwable对象)。

    下面的示例中,给出了一个自定义的Instrumentation拦截器。可以用来测量执行过程的整体执行时间,并将结果存入一个有状态的对象当中。

        class CustomInstrumentationState implements InstrumentationState {
            private Map<String, Object> anyStateYouLike = new HashMap<>();
    
            void recordTiming(String key, long time) {
                anyStateYouLike.put(key, time);
            }
        }
    
        class CustomInstrumentation extends SimpleInstrumentation {
            @Override
            public InstrumentationState createState() {
                //
                // instrumentation state is passed during each invocation of an Instrumentation method
                // and allows you to put stateful data away and reference it during the query execution
                //
                return new CustomInstrumentationState();
            }
    
            @Override
            public InstrumentationContext<ExecutionResult> beginExecution(InstrumentationExecutionParameters parameters) {
                long startNanos = System.nanoTime();
                return new SimpleInstrumentationContext<ExecutionResult>() {
                    @Override
                    public void onCompleted(ExecutionResult result, Throwable t) {
                        CustomInstrumentationState state = parameters.getInstrumentationState();
                        state.recordTiming(parameters.getQuery(), System.nanoTime() - startNanos);
                    }
                };
            }
    
            @Override
            public DataFetcher<?> instrumentDataFetcher(DataFetcher<?> dataFetcher, InstrumentationFieldFetchParameters parameters) {
                //
                // this allows you to intercept the data fetcher used to fetch a field and provide another one, perhaps
                // that enforces certain behaviours or has certain side effects on the data
                //
                return dataFetcher;
            }
    
            @Override
            public CompletableFuture<ExecutionResult> instrumentExecutionResult(ExecutionResult executionResult, InstrumentationExecutionParameters parameters) {
                //
                // this allows you to instrument the execution result some how.  For example the Tracing support uses this to put
                // the `extensions` map of data in place
                //
                return CompletableFuture.completedFuture(executionResult);
            }
        }
    

    链式Instrumentation拦截器

    可以使用ChainedInstrumentation类,将多个Instrumentation对象进行聚合。ChainedInstrumentation类接收一个Instrumentation对象列表参数,然后按照它们定义的顺序依次调用。

            List<Instrumentation> chainedList = new ArrayList<>();
            chainedList.add(new FooInstrumentation());
            chainedList.add(new BarInstrumentation());
            ChainedInstrumentation chainedInstrumentation = new ChainedInstrumentation(chainedList);
    
            GraphQL.newGraphQL(schema)
                    .instrumentation(chainedInstrumentation)
                    .build();
    

    字段验证Instrumentation

    FieldValidationInstrumentation拦截器,可以在执行查询前,校验字段和字段参数。如果校验失败,那么执行过程将终止,error信息添加到查询的result当中。

    可以自定义FieldValidation的实现,或直接使用SimpleFieldValidation类来为每个字段增加校验规则。

            ExecutionPath fieldPath = ExecutionPath.parse("/user");
            FieldValidation fieldValidation = new SimpleFieldValidation()
                    .addRule(fieldPath, new BiFunction<FieldAndArguments, FieldValidationEnvironment, Optional<GraphQLError>>() {
                        @Override
                        public Optional<GraphQLError> apply(FieldAndArguments fieldAndArguments, FieldValidationEnvironment environment) {
                            String nameArg = fieldAndArguments.getFieldArgument("name");
                            if (nameArg.length() > 255) {
                                return Optional.of(environment.mkError("Invalid user name", fieldAndArguments));
                            }
                            return Optional.empty();
                        }
                    });
    
            FieldValidationInstrumentation instrumentation = new FieldValidationInstrumentation(
                    fieldValidation
            );
    
            GraphQL.newGraphQL(schema)
                    .instrumentation(instrumentation)
                    .build();
    
  • 相关阅读:
    Leetcode Substring with Concatenation of All Words
    Leetcode Divide Two Integers
    Leetcode Edit Distance
    Leetcode Longest Palindromic Substring
    Leetcode Longest Substring Without Repeating Characters
    Leetcode 4Sum
    Leetcode 3Sum Closest
    Leetcode 3Sum
    Leetcode Candy
    Leetcode jump Game II
  • 原文地址:https://www.cnblogs.com/pku-liuqiang/p/11529115.html
Copyright © 2011-2022 走看看