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日

相关推荐

  • 新手选好基金的关键与投资技巧 |基金宝典

    对于新手来说,选择基金是一个需要谨慎考虑的过程,首先,要明确自己的投资目标,是追求短期收益还是长期增值,或者是为了特定的财务目标(如子女教育、退休养老等)。同时,评估自己对投资风险的承受能力,风险承受能力较低的投资者可以选择低风险的货币市场基金或债券型基金

    2024-09-14 21:32:10
    0 0
  • 基金基础篇:一文讲透指数基金,干货满满

    投资千万条,风险第一条。前言:对于基金投资而言,绕不开的一个话题就是指数基金,那么到底什么是指数基金呢?它有哪些魅力呢?指数基金的优缺点是啥呢?等一系列问题,本篇就来展开详解,一起往下!对于基金老手而言,可以选择性阅读!01一、什么是指数?在说指数基金之前,

    2024-09-14 21:32:07
    0 0
  • 基金在什么平台上买比较合理?

    购买基金的平台,各有特点和优势,你可以根据自己的需求进行选择,以下是一些基金购买平台:1. 基金公司官方网站或APP:- 优点:直接从基金公司购买,能获取最准确的产品信息和相关服务,有时还可能享受费率优惠,比如申购费折扣等;对自家基金产品的研究和理解更深入,能提供

    2024-09-14 21:32:02
    0 0
  • 购买货币基金有哪些技巧?

    来源:龙老解股以下是购买货币基金的一些技巧: **一、选择规模适中的基金** 一般来说,规模适中的货币基金在市场上的议价能力较强,同时也能在操作上保持灵活性。如果规模过小,可能在应对大额赎回时面临流动性风险,并且在与银行等机构谈判获取更高利率时处于劣势;而规模过

    2024-09-14 21:31:59
    0 0
  • 【理财狮talk秀】债市也波动?别急,先看看这五要素

    据wind数据显示,今年开年以来债券市场吸引了大量资金的关注,走出了非常亮眼的行情,不过也引发了市场和监管对于持续上涨背后潜在风险的担忧。自8月5日以来,债券市场出现了明显的波动,债券价格持续下跌。走势相对较稳的债券为什么出现了较大的波动呢?今天,就让我们来聊一

    2024-09-14 21:31:58
    0 0
  • 几种止损的方式

    XX股票跌了好多,需要止损吗?关于这个问题,相信炒股的朋友都遇到过。买入被套后,不少人会选择原地躺下,等待股价回归。但事实上,随着A股越来越成熟,国际化进程越来越快,以往很多老股民的这个解套“经验”可能不那么灵了。运气不好的,甚至可能被套到退市!众所周知,投

    2024-09-14 21:31:56
    0 0

发表回复

8206

评论列表(0条)

    暂无评论