Hasor【部署 04】Dataway接口配置服务扩展能力实例分享

简介: Hasor【部署 04】Dataway接口配置服务扩展能力实例分享

Dataway接口配置服务扩展能力说明文档。以下是实例。

1.CompilerSpiListener

CompilerSpiListener 也叫做编译拦截器,DataQL 在真正执行查询之前调用。可以使用这个拦截器来实现数据库方言的配置,这样前台就可以只关注 SQL 了。

// 编译拦截器(统一处理SQL方言)
        apiBinder.bindSpiListener(CompilerSpiListener.class, new CompilerSpiListener() {
            @Override
            public QIL compiler(ApiInfo apiInfo, String query, DataQL dataQl) throws IOException {
                if (query.contains(DataBaseType.MySQL.value)) {
                    query = "hint FRAGMENT_SQL_PAGE_DIALECT = \"mysql\" ;" + query;
                } else {
                    query = "hint FRAGMENT_SQL_PAGE_DIALECT = \"postgresql\" ;" + query;
                }
                return dataQl.compilerQuery(query);
            }
        });

2.FxSqlCheckChainSpi

FxSqlCheckChainSpi 是 4.2.0 加入的新特性,应用可以通过这个扩展点对于执行 @@sql 时对 SQL 进行检查和改写。可以用来查看执行的 SQL 或统一修改某些规则。

// 如果存在后续 那么继续执行检查,否则使用 EXIT 常量控制退出后续的检查。
        apiBinder.bindSpiListener(FxSqlCheckChainSpi.class, infoObject -> {
            System.out.println(String.format("[%s] %s", infoObject.getSourceName(), infoObject.getQueryString().trim()));
            // 可以用来查看执行的 SQL 或统一修改某些规则。
            return FxSqlCheckChainSpi.NEXT;
        });

3.ResultProcessChainSpi

一个已经发布的接口被调用之后,一定会触发这个拦截器。而 ResultProcessChainSpi 拦截器的处理有两个方法,分别应对了两个不同的情况:

  • callAfter:结果拦截,用于处理 Query 正确执行之后的二次结果处理。
  • callError:异常拦截,当 Query 执行发生异常时(也可以用来记录错误日志)。
// 返回结果封装
        apiBinder.bindSpiListener(ResultProcessChainSpi.class, new ResultProcessChainSpi() {
            @Override
            public Object callAfter(boolean formPre, ApiInfo apiInfo, Object result) {
                return BaseResult.getInstance(result);
            }
        });
// 所有返回的结果,都把 API 的 Method 和 path 返回
        apiBinder.bindSpiListener(ResultProcessChainSpi.class, new ResultProcessChainSpi() {
            @Override
            public Object callError(boolean formPre, ApiInfo apiInfo, Throwable e) {
                return new HashMap<String, Object>() {{
                    put("method", apiInfo.getMethod());
                    put("path", apiInfo.getApiPath());
                    put("errorMessage", e.);
                }};
            }
        });

实现调用缓存

public class ApiCacheSpi implements PreExecuteChainSpi, ResultProcessChainSpi {
    private Map<String,Object> cacheMap = ... // for example
    public void preExecute(ApiInfo apiInfo, BasicFuture<Object> future) {
        String cacheKey = ...
        if (this.cacheMap.containsKey(cacheKey)) {
            Object cacheValue = cacheMap.get(cacheKey);
            future.completed(cacheValue);
            return;
        }
    }
    public Object callAfter(boolean formPre, ApiInfo apiInfo, Object result) {
        // formPre 为 true,表示 preExecute 已经处理过。
        // apiInfo.isPerform() 为 true 表示,API 调用是从 UI 界面发起的。
        if (formPre || apiInfo.isPerform()) {
            return result;
        }
        //
        String cacheKey = ...
        this.cacheMap.put(cacheKey, result);
        return result;
    }
}

4.SerializationChainSpi

SerializationChainSpi 是 4.1.7 加入的新特性,这个接口允许开发者自定义 Dataway 结果的序列化逻辑。它的使用场景如下:

  • 修改 JSON 序列化的规则,例如:不输出为空的列。
  • 自定义输出格式。例如:使用 XML来作为响应结果,或者使用 RPC 的序列化协议。
// 不输出为空数据
        apiBinder.bindSpiListener(SerializationChainSpi.class, (apiInfo, mimeType, result) -> 
        JSON.toJSONString(result));
        // 二进制序列化
        apiBinder.bindSpiListener(SerializationChainSpi.class, (apiInfo, mimeType, result) -> {
            BufferedImage bi = new BufferedImage(150, 70, BufferedImage.TYPE_INT_RGB); //高度70,宽度150
            Graphics2D g2 = (Graphics2D) bi.getGraphics();
            // background color
            g2.fillRect(0, 0, 150, 70);
            g2.setColor(Color.WHITE);
            // text
            g2.setFont(new Font("宋体", Font.BOLD, 18));
            g2.setColor(Color.BLACK);
            g2.drawString(String.valueOf(result), 3, 50);
            // save to bytes
            ByteArrayOutputStream oat = new ByteArrayOutputStream();
            try {
                ImageIO.write(bi, "JPEG", oat);
            } catch (IOException e) {
                e.printStackTrace();
            }
            // response
            return SerializationChainSpi.SerializationInfo.ofBytes(//
                    mimeType.getMimeType("jpeg"),   // response context-type
                    oat.toByteArray()               // response body
            );
        });
目录
相关文章
|
8月前
|
运维 安全 API
统一接入API赋能开发者:自动高效、灵活编排的云产品日志采集方案
随着企业对网络安全和数据安全防护水平要求的逐步提升,企业管理对企业生产运维过程中所产生的日志数据,在留存处理、权限隔离、跨境合规、数据汇总等方面提出了更高阶的需求。为了满足大客户及一些国际化客户安全合规、简单快速地接入日志、使用日志、操作日志,我们提出了一种新的解决方案——“云产品统一接入API”。统一接入API主要针对阿里云云产品日志类型,以API的方式提供企业或组织用户快速上手,编排灵活的日志采集方案。
|
1月前
|
Kubernetes 网络性能优化 调度
Koordinator v1.4 正式发布!为用户带来更多的计算负载类型和更灵活的资源管理机制
Koordinator v1.4 正式发布!为用户带来更多的计算负载类型和更灵活的资源管理机制
|
22小时前
|
运维 Serverless API
函数计算产品使用问题之作为api网关后端服务,切到3.0有什么好处
函数计算产品作为一种事件驱动的全托管计算服务,让用户能够专注于业务逻辑的编写,而无需关心底层服务器的管理与运维。你可以有效地利用函数计算产品来支撑各类应用场景,从简单的数据处理到复杂的业务逻辑,实现快速、高效、低成本的云上部署与运维。以下是一些关于使用函数计算产品的合集和要点,帮助你更好地理解和应用这一服务。
|
1月前
|
存储 监控 负载均衡
|
6月前
|
监控 安全 JavaScript
函数计算构建弹性应用程序介绍
函数计算构建弹性应用程序介绍
84 2
|
10月前
|
容器
阿里云最新产品手册——云基础产品与基础设施——计算——弹性容器实例——应用场景之通用事件驱动
阿里云最新产品手册——云基础产品与基础设施——计算——弹性容器实例——应用场景之通用事件驱动自制脑图
167 1
|
9月前
快速生成通用接口业务配置
快速生成通用接口业务配置
|
11月前
|
SQL 消息中间件 缓存
12种接口优化的通用方案
12种接口优化的通用方案
162 0
|
11月前
|
消息中间件 XML 存储
集成的方式
系统集成-功能集成
79 0
对象的自治和行为的扩展与适配
对象的自治和行为的扩展与适配
对象的自治和行为的扩展与适配