graphQL-java实战(四)-graphiql实现分页

通过前面的博文,我们可以发现graphQL功能很强大,那么如果我们将其用到生产环境,还需要考虑更多的问题?

1.graphQL支持http接口吗?GET、POST的查询如何实现?

2.graphQL支持分页吗?

上面两个问题,在实际工作中非常普遍,通过研究发现,都是可以实现的

一、HTTP请求

根据GraphQL最佳实践的建议,在GET请求中只取query参数的内容,

而在POST请求中可以在body中支持query之外的更多参数,比如variables

实现的代码如下

复制代码
@RequestMapping(method = {RequestMethod.GET, RequestMethod.POST})
    public Map<String, Object> graphql(
            @RequestParam(required = false) Map<String, Object> param,
            @RequestBody String body,
            HttpServletRequest r) {
        String method = r.getMethod();
        log.info("method="+method);
        if (method.equals("GET")) {
            Object query = param.get("query");
            log.info("query="+query);
            ExecutionInput executionInput = ExecutionInput.newExecutionInput()
                    // 需要执行的查询语言
                    .query(query.toString()).build();
            return this.graphQL.execute(executionInput).toSpecification();
        } else {
            JSONObject req = JSON.parseObject(body);
            log.info(req.toJSONString());
            ExecutionInput executionInput = ExecutionInput.newExecutionInput()
                    // 需要执行的查询语言
                    .query(req.getString("query"))
                    // 执行操作的名称,默认为null
                    .operationName(req.getString("operationName"))
                    // 获取query语句中定义的变量的值,这个必须注释掉,不然启动不起来
                    .variables(req.getJSONObject("variables"))
                    .build();
            // 执行并返回结果
            return this.graphQL.execute(executionInput).toSpecification();
        }
    }
复制代码

二、支持分页

对应列表数据,当数据量较大是,前端一般希望进行分页处理,这个需求很合理。

graphQL的分页分为两种情况:

(一)、如果原生API支持分页只需要定义query查询时传入(page,size)信息传入原生API接口,

理论上原生api结果应该包含(total,pages),

graphQL只需要构建包含这两个字段的schema即可,无需其他设置

(二)、如果原生API不支持分页

分页就需要在graphQL自己实现,首先自定义分页请求参数(page,size)以及新的结果schema,

然后对上游的返回结果在内存中进行分页

从性能角度考虑,推荐进行第一种方式,如果原生API不支持也不愿意修改,那就只能在内存进行分页。

内容分页的实现如下:

复制代码
//argument是参数,data是原始的结果
private Map<String, Object> pageProcess(Map<String, Object> arguments, Object data) {
        JSONArray jsonArray = JSONArray.parseArray(JSON.toJSONString(data));
        int total = jsonArray.size();
        Integer size = (Integer) arguments.get("size");
        Integer page = (Integer) arguments.get("page");
        int pages = (int) Math.ceil((double)total / size);
        Integer fromIndex = (page - 1) * size;
        Integer toIndex = fromIndex + size > total ? total : fromIndex + size;
        List<Object> subList = jsonArray.subList(fromIndex, toIndex);
        Map<String, Object> map = new HashMap<>();
        map.put("books", subList);
        map.put("total", total);
        map.put("pages", pages);
        return map;
    }
复制代码

 

posted @   Mars.wang  阅读(815)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 25岁的心里话
· 闲置电脑爆改个人服务器(超详细) #公网映射 #Vmware虚拟网络编辑器
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· 零经验选手,Compose 一天开发一款小游戏!
· 通过 API 将Deepseek响应流式内容输出到前端
历史上的今天:
2021-07-29 springboot配置日志输出
2021-07-29 springboot使用插件-GsonFormat(转)
点击右上角即可分享
微信分享提示