fly coding Api请求支持通配符“{}”调用接口

此前,已经完善了Api的功能,但是,目前暂不支持“'get/{id}”此种形式,根据通配符调用接口功能。

fly coding Api请求支持通配符“{}”调用接口

一、解析通配符接口配置

  • 需求分析,思路梳理

为使api模型支持通配符形式解析,并且后期可以方便扩展其他形式解析,我的思路大致如下:

1、定义一个“api_type”用来存储Api类型,目前仅支持“默认”,“通配符”两种类型。

2、考虑到解析性能问题,定义一个“parse_param_config”字段,用来存储解析值,数据格式大致如下;

[{"index":4,"key":"orderNum"}]

参数Key为映射请求参数对象的名称,后面的数字为以“/”分割后值的“index”位置。

  • 代码实现

1、定义Api规则对象

package com.flycoding.drivenlibrary.engine.api.entity.bo;/*** api 规则bo** @author 赵屈犇* @version 1.0* @date 创建时间: 2023/8/3 20:08* @Copyright(C): 2023 by 赵屈犇*/public class ApiMatchBO {    /*** 索引位置*/    private int index;    /*** 参数主键*/    private String key;    public int getIndex() {        return index;    }    public void setIndex(int index) {        this.index = index;    }    public String getKey() {        return key;    }    public void setKey(String key) {        this.key = key;    }}

2、声明Api ORM映射

/*** 服务类型*/@FormFieldConfig(fieldCode = "api_type", fieldName = "服务类型", elementCode = DrivenElementConstants.SELECT_ELEMENT,                 dict = @DictConfig(dictCode = ApiType.DICTIONARY_CODE), fieldParentName = BASIC_MESSAGE_NAME)@Column(columnName = "api_type", columnType = ColumnType.VARCHAR, length = SqlConstants.DICTIONARY_VALUE_SIZE, isNotNull = true)private String apiType;/*** 解析参数配置*/@Column(columnName = "parse_param_config", columnType = ColumnType.VARCHAR, length = 500)private List<ApiMatchBO> parseParamConfig;

3、声明 apiType 字典数据

/** * api 类型 */@DictionaryConfig(dictionaryCode = ApiType.DICTIONARY_CODE, dictionaryName = "api 类型")public static class ApiType {/*** 字典编码*/   public static final String DICTIONARY_CODE = "1042";    /** * 默认 */    @DictionaryConfig(dictionaryName = "默认")    public static final String DEFAULT = "104201";    /** * 通配符 */    @DictionaryConfig(dictionaryName = "通配符")    public static final String WILDCARD = "104202";}

4、解析通配符接口

String apiType = ConfigDictionaryConstants.ApiType.DEFAULT;// 分割api 全路径String[] apiFullUrls = (moduleUrl + "/" + api.getApiUrl()).split("/");StringJoiner apiFullUrl = new StringJoiner("/");if (ArrayUtils.isNotEmpty(apiFullUrls)) {    JSONObject parseParamConfig = new JSONObject();    for (int i = 0; i < apiFullUrls.length; i++) {    String fullUrl = apiFullUrls[i];        if (!fullUrl.equals("/")) {        // 解析 {} 通配符            if (RegularHelper.isMatcher(fullUrl, RegularConstants.BRACES)) {            Matcher matcher = RegularHelper.getMatcher(fullUrl, RegularConstants.BRACES);                while (matcher.find()) {                String group = matcher.group(1);                    parseParamConfig.put(group, i);                    apiType = ConfigDictionaryConstants.ApiType.WILDCARD;                }            } else {                apiFullUrl.add(fullUrl);         }}}api.setParseParamConfig(parseParamConfig);
  • 代码执行结果

二、解析支持通配符请求

  • 需求分析,思路梳理

此上,已实现结构解析并入库。接下来,我需要实现Api功能支持,通配符访问请求。要实现这种功能,我需要实现Api接口通配符形式的匹配,我有两种实现方式,一种是通过startWith直接判断,另一种是通过正则匹配。

以下是两种实现方式的优劣分析:

  • startWith
    • 性能高于正则,但是扩展性不好,仅支持get/{id}此种形式
  • 正则匹配
    • 性能低于startWith,但是扩展性好,可以支持各种形式匹配规则

以下是性能示例图:

可以看出,startWith远远高于正则匹配。综合考虑,我决定采用startWith方式进行匹配。

为提高检索效率,我仅准备缓存通配符类型的Api接口键值对,这样的话,也可以快速匹配索引到对应的Api地址。若未匹配到时,走之前处理逻辑即可。

  • 代码实现

1、Api匹配规则工厂

package com.flycoding.drivenlibrary.engine.api.factory;import com.alibaba.fastjson.JSONObject;import com.flycoding.dblibrary.executor.inter.ISqlExecutor;import com.flycoding.drivenlibrary.engine.config.constants.dictionary.ConfigDictionaryConstants;import com.flycoding.drivenlibrary.engine.config.entity.ModelDBConfigMessage;import com.flycoding.drivenlibrary.engine.config.factory.DBConfigFactory;import com.flycoding.drivenlibrary.engine.request.build.sql.QueryBuilder;import com.flycoding.drivenlibrary.enums.dictionary.QueryType;import com.flycoding.utillibrary.java.ArrayUtils;import com.flycoding.utillibrary.logger.LoggerFactory;import java.util.List;/** * api 匹配工厂 * * @author 赵屈犇 * @version 1.0 * @date 创建时间: 2023/8/3 20:26 * @Copyright(C): 2023 by 赵屈犇 */public class ApiMatchFactory {    private static final LoggerFactory logger = LoggerFactory.getLogger(ApiMatchFactory.class.getName());    private static ApiMatchFactory instance;    /**     * DB配置信息的工厂     */    private DBConfigFactory dbConfigFactory;    /**     * api 匹配地址集合     */    private List<String> apiMatchUrls = ArrayUtils.newArrayList();    public static ApiMatchFactory getInstance() {        if (instance == null) {            synchronized (ApiMatchFactory.class) {                if (instance == null) {                    instance = new ApiMatchFactory();                }            }        }        return instance;    }    private ApiMatchFactory() {        dbConfigFactory = DBConfigFactory.getInstance();    }    /**     * 初始化匹配规则     */    public void initMatch() {        try {            List<ModelDBConfigMessage> dbConfigs = DBConfigFactory.getInstance().getDBConfigs();            if (ArrayUtils.isNotEmpty(dbConfigs)) {                for (ModelDBConfigMessage config : dbConfigs) {                    ISqlExecutor executor = dbConfigFactory.getModelSqlExecutor(config.getDbConfigCode());                    List<JSONObject> datas = (List<JSONObject>) QueryBuilder.builder().executor(executor).table("Sy_Api").column("api_full_url", "apiFullUrl")                            .whereBuilder().and("api_type", QueryType.NOT_EQUAL, ConfigDictionaryConstants.ApiType.DEFAULT)                            .sqlBuilder().execute();                    if (ArrayUtils.isNotEmpty(datas)) {                        for (JSONObject data : datas) {                            apiMatchUrls.add(data.getString("apiFullUrl"));                        }                    }                }            }        } catch (Exception e) {            logger.error("初始化匹配规则报错了,", e);        }    }    /**     * 获取api根据规则     *     * @param apiUrl     * @return     */    public String getApiByMatch(String apiUrl) {        for (String apiMatchUrl : apiMatchUrls) {            if (apiUrl.startsWith(apiMatchUrl)) {                return apiMatchUrl;            }        }        return apiUrl;    }}

2、改造Api入口,实现请求参数入参

// 判断是否为通配符规则if (ConfigDictionaryConstants.ApiType.DEFAULT != apiInfo.getApiType()) {    List<ApiMatchBO> parseParamConfig = apiInfo.getParseParamConfig();    if (ArrayUtils.isNotEmpty(parseParamConfig)) {        String[] apiUrls = apiUrl.split("/");        for (ApiMatchBO apiMatch : parseParamConfig) {            if (apiUrls.length > apiMatch.getIndex()) {                requestParams.put(apiMatch.getKey(), apiUrls[apiMatch.getIndex()]);            }        }    }}
  • 代码执行结果

版权声明

1 本文地址:https://www.sunlonger.com/jijin/1230239.html 转载请注明出处。
2 本站内容除隼龙儿财经签约编辑原创以外,部分来源网络由互联网用户自发投稿及AIGC生成仅供学习参考。
3 文章观点仅代表原作者本人不代表本站立场,并不完全代表本站赞同其观点和对其真实性负责。
4 文章版权归原作者所有,部分转载文章仅为传播更多信息服务用户,如信息标记有误请联系管理员。
5 本站禁止以任何方式发布转载违法违规相关信息,如发现本站有涉嫌侵权/违规及任何不妥内容,请第一时间联系我们申诉反馈,经核实立即修正或删除。


本站仅提供信息存储空间服务,部分内容不拥有所有权,不承担相关法律责任。
上一篇 2024年06月17日
下一篇 2024年06月17日

相关推荐

  • 以下是几种构建指数基金组合的常用方法: 一、核心

    以下是几种构建指数基金组合的常用方法:一、核心 - 卫星策略1.核心资产配置●选择宽基指数基金作为核心资产,如沪深300指数基金。沪深300涵盖了沪深两市规模大、流动性好的300只股票,能代表A股市场的整体表现。这部分资产通常占组合的较大比例,比如60% - 70%。其作用是获取

    2024-10-28 22:02:12
    0 0
  • A500投资锦囊,来了

    风险提示:基金有风险,投资须谨慎。本观点仅代表当时观点,今后可能发生改变,仅供参考,不构成投资建议或保证,亦不作为任何法律文件。基金过往业绩并不预示其未来表现,基金管理人管理的其他基金的业绩并不构成基金业绩表现的保证。我国基金运作时间较短,不能反映股市发展

    2024-10-28 22:02:07
    0 0
  • 李稻葵谈理财:假如有10万元,会先买1万元保险,再买8万元基金

    近日,清化大学中国经济思想与实践研究院院长李稻葵做客央视财经频道《对话》栏目,对当前宏观经济运行情况发表最新见解。现场,李稻葵被问假如有10万元,该如何分配。李稻葵表示:“首先有个小前提,就是这10万元钱我5年之内不需要急用。首先,我想至少拿出1万元钱买保险,我

    2024-10-28 22:01:57
    0 0
  • 指数基金的三种配置方法

    1976年6月,先锋领航发行了旗下第一款指数基金产品,甚至其名称都叫做First Index Investment Trust(现已改名为Vanguard 500 Index Fund ETF——标普500ETF先锋领航)。这只产品的“第一”,不仅预示着先锋领航指数基金业务的开端,同时也标志着全球指数基金产品0的突破。投

    2024-10-28 21:23:17
    0 0
  • 基金投资:稳健获利的策略选择

    在当今的金融市场中,基金投资已成为众多投资者的热门选择。然而,如何进行有效的基金投资却是一门需要深入研究的学问。基金投资的风险、流动性和收益性一直是投资者关注的焦点。过高的风险可能导致本金的大幅损失,而缺乏流动性则可能在急需资金时陷入困境,当然,追求高收益

    2024-10-28 21:23:13
    0 0
  • 权益理财三季度跑输主流指数和权益型基金,施罗德交银理财欲推新品布局红利策略丨机警理财日报

    南财理财通课题组 黄桂煊榜单排名来自理财通AI全自动化实时排名,如您对数据有疑问,请在文末联系助理进一步核实。权益类理财三季度涨8.98%,跑输主流指数和权益型基金2024年三季度,A股出现V型反转,上证指数在第二季度末跌破3000点之后持续下行,9月20日最低至2700点,9月底

    2024-10-28 21:23:09
    0 0

发表回复

8206

评论列表(0条)

    暂无评论