You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何为Spring GraphQL 1.0.1创建自定义Instrumentation以限制单次API调用的查询数量

自定义Instrumentation限制单次请求的查询数量

当然可以实现!你完全可以仿照现有的MaxQueryComplexityInstrumentation和MaxQueryDepthInstrumentation,自定义一个Instrumentation来限制单次请求中包含的操作(查询、变更等)数量。下面是具体的实现步骤:

1. 编写自定义Instrumentation类

我们继承SimpleInstrumentation,重写beginParse方法,在请求解析完成后统计操作数量,超过阈值就抛出错误。这里的“操作”默认包含query、mutation和subscription,如果你只想限制query类型,可以额外添加过滤条件。

import graphql.ExecutionInput;
import graphql.ParseResult;
import graphql.language.Document;
import graphql.language.OperationDefinition;
import graphql.schema.instrumentation.SimpleInstrumentation;
import graphql.schema.instrumentation.SimpleInstrumentationContext;

import java.util.List;

public class MaxQueryCountInstrumentation extends SimpleInstrumentation {

    private final int maxQueryCount;

    // 构造函数传入阈值
    public MaxQueryCountInstrumentation(int maxQueryCount) {
        this.maxQueryCount = maxQueryCount;
    }

    @Override
    public SimpleInstrumentationContext<ParseResult> beginParse(ExecutionInput executionInput, InstrumentationState state) {
        // 解析完成后触发回调逻辑
        return SimpleInstrumentationContext.whenCompleted((parseResult, throwable) -> {
            if (throwable == null && parseResult.isPresent()) {
                Document document = parseResult.get().getDocument();
                // 获取请求中的所有操作定义
                List<OperationDefinition> operations = document.getDefinitionsOfType(OperationDefinition.class);
                
                // 如果只想限制query类型,可添加过滤逻辑:
                // long queryCount = operations.stream()
                //     .filter(op -> op.getOperationType() == OperationDefinition.OperationType.QUERY)
                //     .count();
                
                int operationCount = operations.size();
                if (operationCount > maxQueryCount) {
                    // 抛出自定义GraphQL错误,返回标准错误格式给客户端
                    throw new TooManyOperationsError(String.format(
                        "单次请求最多允许%d个操作,当前提交了%d个",
                        maxQueryCount, operationCount
                    ));
                }
            }
        });
    }
}

2. 自定义GraphQL错误类(可选但推荐)

为了让客户端收到标准的GraphQL错误响应(而非通用的500错误),我们可以自定义一个实现GraphQLError的错误类:

import graphql.ErrorClassification;
import graphql.GraphQLError;
import graphql.language.SourceLocation;

import java.util.List;

public class TooManyOperationsError implements GraphQLError {

    private final String message;

    public TooManyOperationsError(String message) {
        this.message = message;
    }

    @Override
    public String getMessage() {
        return message;
    }

    @Override
    public List<SourceLocation> getLocations() {
        return null;
    }

    @Override
    public ErrorClassification getErrorType() {
        // 标记为验证错误,符合GraphQL规范
        return ErrorClassification.ValidationError;
    }
}

3. 配置Instrumentation Bean

和你现有的复杂度、深度配置保持一致,添加对应的Bean定义:

import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.beans.factory.annotation.Value;

@Configuration
public class GraphQLInstrumentationConfig {

    // 你的现有配置:maxQueryComplexity和maxQueryDepth的Bean...

    @Bean
    @ConditionalOnMissingBean
    @ConditionalOnProperty(prefix = "spring.graphql.instrumentation", name = "max-query-count")
    public MaxQueryCountInstrumentation maxQueryCountInstrumentation(
            @Value("${spring.graphql.instrumentation.max-query-count}") int maxQueryCount) {
        return new MaxQueryCountInstrumentation(maxQueryCount);
    }
}

4. 配置阈值参数

在application.properties或application.yml中添加配置:

# 限制单次请求最多5个操作
spring.graphql.instrumentation.max-query-count=5

这样配置完成后,当用户提交的请求中操作数量超过你设置的阈值时,服务器会返回标准的GraphQL错误响应,拒绝该请求,从而达到保护服务器的目的。

内容的提问来源于stack exchange,提问作者rubalvjaiswal

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.27 18:17:46