• 项目实战--Spring Boot + GraphQL实现实时数据推送


    背景

    用户体验不断提升而3对实时数据的需求日益增长,传统的数据获取方式无法满足实时数据的即时性和个性化需求。
    GraphQL作为新兴的API查询语言,提供更加灵活、高效的数据获取方案。结合Spring Boot作为后端框架,利用GraphQL实现实时数据推送,满足对实时数据的需求。

    一、GraphQL简介

    GraphQL是一种用于API的查询语言,核心思想是让客户端能够根据自身需求精确地获取所需的数据,而不是像传统的RESTful API那样只能获取整个资源对象。GraphQL的特点包括:

    (1)灵活性:客户端可以精确指定所需的数据字段,而不是被限制于服务器端提供的固定数据结构。
    (2)效率:减少了不必要的数据传输和处理,提高了数据获取效率。
    (3)类型系统:GraphQL具有严格的类型系统,能够在编译阶段检测出潜在的错误,提高了开发效率。
    
    二、实现

    在Spring Boot中集成GraphQL可以通过GraphQL Java库来实现。在pom.xml文件中添加GraphQL Java库的依赖:

    <dependency>
        <groupId>org.springframework.bootgroupId>
        <artifactId>spring-boot-starter-graphqlartifactId>
        <version>2.7.9version>
    dependency>
    

    YAML配置:

    spring:
      graphql:
        graphiql:
          enabled: true
        websocket:
          path: /graphql
        schema:
          printer:
            enabled: true
          locations: classpath:schema   #test.graphql文件位置
          file-extensions: .graphql
    

    test.graphql文件:

    #测试接口
    #第一个graphql文件的type Mutation前不需要添加extend
    type Mutation {
        #新增测试
        saveTest(testDto: TestDto):Boolean
    }
     
    #第一个graphql文件的type Query前不需要添加extend
    type Query {
        #获取列表测试
        getTestList(name: String!):[TestVo]
    }
     
    #请求参数
    input TestDto{
        """
        ID
        """
        id: Int!
        """
        名称
        """
        name: String!
        """
        标题
        """
        title: String
        """
        备注
        """
        remarks: String
    }
     
    #返回参数
    type TestVo{
        """
        ID
        """
        id: Int
        """
        名称
        """
        name: String
        """
        标题
        """
        title: String
        """
        备注
        """
        remarks: String
    }
    

    测试TestController接口:

    /**
     * 测试TestController
     */
    @Slf4j
    @RestController
    public class TestController {
     
        /**
         * 新增测试
         * @return true:成功; false:失败
         */
        @MutationMapping
        public Mono<Boolean> saveTest(@Argument Test test) {
            log.info("新增测试,请求参数:{}", JSON.toJSONString(test));
            return Mono.just(true);
        }
     
        /**
         * 获取列表测试
         * @param name
         * @return
         */
        @QueryMapping
        public Mono<List<Test>> getTestList(@Argument String name) {
            log.info("获取列表测试,请求参数:{}", name);
            List<Test> tests = new ArrayList<>();
            Test test1 = new Test();
            test1.setId(1);
            test1.setName("测试1");
            test1.setTitle("标题1");
            test1.setRemarks("备注1");
            tests.add(test1);
            Test test2 = new Test();
            test2.setId(2);
            test2.setName("测试2");
            test2.setTitle("标题2");
            test2.setRemarks("备注2");
            tests.add(test2);
            return Mono.just(tests);
        }
    }
    

    结果:
    在这里插入图片描述

    第二种集成方式:
    在pom.xml文件中添加GraphQL Java库的依赖:

    <dependency>
        <groupId>com.graphql-java-kickstartgroupId>
        <artifactId>graphql-spring-boot-starterartifactId>
        <version>11.1.0version>
    dependency>
    

    然后定义GraphQL Schema,包括类型定义和查询操作。假设有一个简单的数据模型Message:

    public class Message {
        private String id;
        private String content;
        // Getters and setters
    }
    

    接下来定义GraphQL查询操作和Resolver。假设要实现一个查询,用于获取所有消息列表:

    @Component
    public class GraphQLQueryResolver implements GraphQLQueryResolver {
        private List<Message> messages = new ArrayList<>();
    
        public List<Message> getMessages() {
            return messages;
        }
    }
    

    然后需要配置GraphQL Endpoint,使客户端可发送GraphQL请求。在application.properties文件中添加以下配置:

    graphql.servlet.mapping=/graphql
    

    最后启动Spring Boot应用,GraphQL Endpoint将会监听客户端的请求并返回相应的数据。

    对于实时数据推送,可以使用GraphQL的订阅(Subscription)功能。假设实现一个订阅,用于实时推送新消息。首先,定义一个订阅类型和对应的Resolver:

    @Component
    public class GraphQLSubscriptionResolver implements GraphQLSubscriptionResolver {
        public Publisher<Message> newMessage() {
            //返回发出新消息的发布者
            return newPublisher -> {
                //可以在这里实现发出新消息的逻辑
                //简化为每秒发出一条新消息
                ScheduledExecutorService executorService = Executors.newScheduledThreadPool(1);
                executorService.scheduleAtFixedRate(() -> {
                    Message message = // 生成新消息的逻辑
                    newPublisher.onNext(message);
                }, 0, 1, TimeUnit.SECONDS);
            };
        }
    }
    

    然后,更新GraphQL Schema,添加订阅类型:

    @GraphQLSchema
    public class MyGraphQLSchema {
        @Bean
        public GraphQLSchema schema(GraphQLQueryResolver queryResolver,
                                    GraphQLSubscriptionResolver subscriptionResolver) {
            return SchemaParser.newParser()
                    .file("graphql/schema.graphqls") // 您的 GraphQL 架构文件
                    .resolvers(queryResolver, subscriptionResolver)
                    .build()
                    .makeExecutableSchema();
        }
    }
    

    在GraphQL Schema文件中,定义新的订阅类型:

    type Subscription {
        newMessage: Message!
    }
    

    现在,客户端可以通过订阅newMessage来实时接收新的消息。当有新消息时,服务器端将会自动推送给客户端。

    三、使用场景

    (1)实时监控系统:在监控系统中,可以利用GraphQL实时获取服务器、应用程序等的状态信息,并实时推送给用户。
    (2)社交网络应用:在社交网络应用中,可以利用GraphQL实时获取用户的动态、消息等信息,并实时推送给关注的用户。
    (3)在线游戏应用:在在线游戏应用中,可以利用GraphQL实时获取游戏状态、玩家位置等信息,并实时推送给玩家。
    (4)股票交易系统:在股票交易系统中,可以利用GraphQL实时获取股票价格、交易量等信息,并实时推送给交易员。

  • 相关阅读:
    三维模型3DTile格式轻量化压缩处理效率提高的技术方浅析
    Ubuntu下通过python使用MySQL
    数据标注工具 Label-Studio
    leetcode 1235
    Codeforces Round #750 (Div. 2)(A,B,C,D,F1)
    python基础(五)输入和while
    数学建模学习(91):快速非支配排序的遗传算法(NSGA-II)多目标寻优
    蚕蛹之光助残创业先锋:不忘初心勇担使命
    数字化时代的利器:数仓助力企业破局突围
    SLAM从入门到精通(从amcl到navigation软件栈)
  • 原文地址:https://blog.csdn.net/qq_40623672/article/details/140313637