java recursively implements the result operation method of assembling multiple api

  • 2021-11-14 05:36:56
  • OfStack

Often the api interface needs to be implemented, but each time it is the same, so I wonder if I can configure this repetitive work.

I will write a template api, and then all HTTP requests come over and return different results according to different configurations.

At first, the consideration is relatively simple. When I come to an api requirement, I will go to MySQL to check an SQL corresponding to api, and then take SQL to get the result and return.

This is not difficult.

The key point is that in actual requirements, there are many complex data returned by api, such as the interface for rendering maps, which can't be handled by one SQL.

Then I thought, can I assemble api? You can see that I only called one API, but the result I returned to you is actually assembled by several API results.

After research, it can be realized.

First, we define a model of ApiConfig


@Data
@Table(name = "api_config")
@AllArgsConstructor
public class ApiConfig implements Serializable {

    @ApiModelProperty("api Name ")
    private String apiName;

    @ApiModelProperty(" Data source name ")
    private String dsName;

    @ApiModelProperty("SQL")
    private String querySql;

    @ApiModelProperty(" Result type ")
    private String resultType;

    @ApiModelProperty(" Result description ")
    private String resultDesc;

    @ApiModelProperty(" Dependency api")
    private String dependApiName;
}

Next is our implementation class, because it shows feasibility, so we don't hierarchy, and implement all logic in one Test class

{"key1":"x/y/1",
"key2":"x/y/2"}

Next is our implementation class, because it shows feasibility, so we don't hierarchy, and implement all logic in one Test class


@Slf4j
public class Test {
    // Initialization of test data 
    public static List<ApiConfig> apiConfigList = new ArrayList<>();
    public static Map<String, String> sqlResultMap = ImmutableMap.of("sql1", "{\"a\":\"1\"}", "sql2", "{\"b\":\"2\"}", "sql3", "{\"c\":\"3\"}");

    static {
        ApiConfig api1 = new ApiConfig("p1", "d1", "sql1", "map", "", "{\"b\":\"p1/x1\"}");
        ApiConfig api2 = new ApiConfig("p1/x1", "d1", "sql2", "map", "", "{\"c\":\"p1/x2\"}");
        ApiConfig api3 = new ApiConfig("p1/x2", "d1", "sql3", "map", "", null);
        apiConfigList.add(api1);
        apiConfigList.add(api2);
        apiConfigList.add(api3);
    }

    /**
     *  I want to proceed http:ip:port/p1 Please return me the relevant data for this request 
     * @param args
     */
    public static void main(String[] args) {
        // According to api Name get result 
        String apiName = "p1";
        JSONObject json = doGetResult(apiName);
        //result Must be initialized and cannot be re-established within the method new To ensure that the updated within the recursive method is the same as the 1 Objects, otherwise you can't get the updated data result
        JSONVO result = null;
        if (json != null) {
            result = new JSONVO(json.toJSONString());
        } else {
            result = new JSONVO("{}");
        }
        // If necessary, recursively get the child api And save the results of the result
        getApiResult(apiName, null, result);
        System.out.println(result);

    }

    /**
     *  Subordinate api Query the results and update them to the main result
     * @param apiName
     * @param dataKey
     * @param result
     */
    public static void getApiResult(String apiName, String dataKey, JSONVO result) {
        //dataKey Is equal to when entering the method null Of, number 2 The second entry should definitely not be null, This place is updated result The key position of 
        if (dataKey != null) {
            JSONObject json = doGetResult(apiName);
            result.set(dataKey, json);
        }
        // Enter the recursive entrance 
        String dependApiName = getApiConfig(apiName).getDependApiName();
        if (dependApiName != null) {
            JSONObject dependApi = JSONObject.parseObject(dependApiName);
            Set<String> keySet = dependApi.keySet();
            for (String key : keySet) {
                String subApi = dependApi.getString(key);
                getApiResult(subApi, key, result);
            }

        }
    }

    public static JSONObject doGetResult(String apiName) {
        String querySql = getApiConfig(apiName).getQuerySql();
        return doQuery(querySql);
    }

    /**
     *  According to api Name acquisition apiConfig
     *
     * @param api
     * @return
     */
    public static ApiConfig getApiConfig(String api) {
        for (ApiConfig apiConfig : apiConfigList) {
            if (apiConfig.getApiName().equals(api)) {
                return apiConfig;
            }
        }
        log.error("api not exists!");
        return null;
    }

    /**
     *  According to the query SQL Get results 
     *
     * @param sql
     * @return
     */
    public static JSONObject doQuery(String sql) {
        String s = sqlResultMap.get(sql);
        JSONObject jsonObject = JSONObject.parseObject(s);
        return jsonObject;
    }


}

Output:

{"a":"1","b":{"b":"2"},"c":{"c":"3"}}

As you can see, the data of api, a child of two recursions, have been found out.

The result returned from the database may not necessarily be JsonObject, which needs to be analyzed in detail in the implementation project.


Related articles: