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

如何在Spring-GraphQL项目中添加第二个GraphQL端点?

在Spring-GraphQL中配置多个GraphQL端点

完全可以实现!核心思路是手动注册多个GraphQlServlet实例,分别对应内部和公众端点,并通过访问控制规则隔离两者的权限范围。以下是具体实现步骤:

1. 禁用自动注册的默认端点

首先在配置文件中关闭Spring Boot自动生成的默认GraphQL端点,避免冲突:

# application.properties
spring.graphql.servlet.enabled=false

2. 注册两个独立的GraphQL端点

创建配置类,手动注册两个Servlet实例,分别指定不同的访问路径:

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.graphql.server.webmvc.GraphQlHttpHandler;
import org.springframework.graphql.server.webmvc.GraphQlServlet;
import org.springframework.boot.web.servlet.ServletRegistrationBean;

@Configuration
public class MultipleGraphQlEndpointsConfig {

    // 内部端点:供数据中心内部访问
    @Bean
    public ServletRegistrationBean<GraphQlServlet> internalGraphQlServlet(GraphQlHttpHandler graphQlHttpHandler) {
        GraphQlServlet servlet = new GraphQlServlet(graphQlHttpHandler);
        ServletRegistrationBean<GraphQlServlet> registration = new ServletRegistrationBean<>(servlet, "/internal/graphql");
        registration.setName("internalGraphQlServlet");
        return registration;
    }

    // 公众端点:对外开放访问
    @Bean
    public ServletRegistrationBean<GraphQlServlet> publicGraphQlServlet(GraphQlHttpHandler graphQlHttpHandler) {
        GraphQlServlet servlet = new GraphQlServlet(graphQlHttpHandler);
        ServletRegistrationBean<GraphQlServlet> registration = new ServletRegistrationBean<>(servlet, "/public/graphql");
        registration.setName("publicGraphQlServlet");
        return registration;
    }
}

3. 配置访问控制(隔离内部/公众端点)

结合Spring Security,给内部端点添加IP白名单限制,只允许数据中心的IP段访问:

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.security.web.servlet.util.matcher.MvcRequestMatcher;
import org.springframework.security.web.util.matcher.IpAddressMatcher;
import org.springframework.web.servlet.handler.HandlerMappingIntrospector;

@Configuration
public class SecurityConfig {

    // 定义内部端点的IP匹配规则(替换为你的数据中心IP段)
    @Bean
    public MvcRequestMatcher internalEndpointMatcher(HandlerMappingIntrospector introspector) {
        MvcRequestMatcher matcher = new MvcRequestMatcher(introspector, "/internal/graphql/**");
        matcher.setIpAddressMatcher(new IpAddressMatcher("192.168.0.0/16"));
        return matcher;
    }

    // 配置权限规则
    @Bean
    public SecurityFilterChain securityFilterChain(HttpSecurity http, MvcRequestMatcher internalEndpointMatcher) throws Exception {
        http
            .authorizeHttpRequests(auth -> auth
                .requestMatchers(internalEndpointMatcher).permitAll() // 允许内部IP访问
                .requestMatchers("/public/graphql").permitAll() // 公众端点开放访问,可根据需求调整为角色限制
                .anyRequest().authenticated()
            );
        return http.build();
    }
}

4. 可选:为不同端点配置独立的GraphQL逻辑

如果需要内部和公众端点使用不同的schema、数据获取器,可以创建独立的GraphQlSource实例:

// 在MultipleGraphQlEndpointsConfig中添加以下Bean
@Bean
public GraphQlSource internalGraphQlSource() {
    return GraphQlSource.builder()
        .schemaResourceLoader(new DefaultResourceLoader())
        .schemaLocations("classpath:internal-schema.graphqls") // 内部专属schema
        .runtimeWiring(runtimeWiring -> runtimeWiring
            .type("Query", typeWiring -> typeWiring
                .dataFetcher("internalData", internalDataFetcher())
            )
        )
        .build();
}

@Bean
public GraphQlSource publicGraphQlSource() {
    return GraphQlSource.builder()
        .schemaResourceLoader(new DefaultResourceLoader())
        .schemaLocations("classpath:public-schema.graphqls") // 公众专属schema
        .runtimeWiring(runtimeWiring -> runtimeWiring
            .type("Query", typeWiring -> typeWiring
                .dataFetcher("publicData", publicDataFetcher())
            )
        )
        .build();
}

// 为每个端点绑定独立的GraphQlHttpHandler
@Bean
public GraphQlHttpHandler internalGraphQlHttpHandler(GraphQlSource internalGraphQlSource) {
    return GraphQlHttpHandler.builder(internalGraphQlSource).build();
}

@Bean
public GraphQlHttpHandler publicGraphQlHttpHandler(GraphQlSource publicGraphQlSource) {
    return GraphQlHttpHandler.builder(publicGraphQlSource).build();
}

这种方式可以灵活满足你的需求:既可以让两个端点共用同一套GraphQL逻辑,也可以完全隔离各自的schema和数据处理流程,同时通过IP或权限控制确保内部端点的安全性。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.01 01:20:19