• graphQLjava实战(四)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;
        }
  • 相关阅读:
    IP和MAC
    ASCII,Unicode 和 UTF-8
    php(PHP Hypertext Preprocessor)随笔1
    css层叠样式表 (Cascading Style Sheets)初识
    ansible部署
    mysql三种备份方式
    nginx反向代理,负载均衡,动静分离,rewrite地址重写介绍
    Maven安装和配置
    jenkins之Tomcat7+jdk1.7+jenkins
    CentOS 7.0如何安装配置iptables和seLinux以及firewalld
  • 原文地址:https://www.cnblogs.com/wangbin2188/p/16532796.html
Copyright © 2020-2023  润新知