abstract
If the front-end and back-end are separated for project development, the better way for front-end and back-end interaction is to use HTTP+JSON.How can an interface return results that are more concise, elegant, and reasonable, and that can be made clear to front-end developers without increasing the workload for back-end developers?
Start of Text
Hello, everyone, long time no see.I have been planning for the personal website to be revamped in the 2020 version, so this article is also the last one in 2019. Of course, I have to put some thought into trying to say what I want to say one by one, explain it clearly and thoroughly.
If the front-end and back-end are separated for project development, the better way for front-end and back-end interaction is to use HTTP+JSON.How can an interface return results that are more concise, elegant, and reasonable, and that can be made clear to front-end developers without increasing the workload for back-end developers?
To do this, I have written a set of solutions for API interface development returning results. api-result , has been opened source and uploaded to Central warehouse You are welcome to criticize and make corrections.
API Explanation
Entity Class
Entity classes that satisfy the use of each scenario are provided as follows:
ResultModel
This class is the base entity class with the following properties:
Success: returns the result identifier, is a Boolean value, true / false (success / failure)
message: Description information, when an error occurs, you can fill in the error details here
Data: data, which is a generic type, can be an array or an object, etc., only when it is successful and requires data to be returned
ApiResultModel
The structural relationships are as follows:
ResultModel └── ApiResultModel
The code attribute is added to this class, which is also a generic type. You can customize your return code type, which can be an integer or a string.
PageResultModel
The structural relationships are as follows:
ResultModel └── PageResultModel
This class mainly returns results by paging, so the following properties have been added:
Total: total number of data bars, Long
size: number of bars per page, integer
Pages: total pages, Long
Current: current page, Long
Helper Tool Class
Help US manipulate entity classes. What helper s are there?The following:
ResultHelper
ResultHelper corresponds to ResultModel
success(String message)
Success, carry description information
success(String message, T data)
Success, with descriptive information and data
error(String message)
Error, with detailed description
ApiResultHelper
ApiResultHelper corresponds to ApiResultModel
success(S code, String message)
Success, carry return code and description information
success(S code, String message, T data)
Successfully, carry return codes, descriptions, and data
error(S code, String message)
Errors, carry error codes and detailed descriptions
PageResultHelper
PageResultHelper corresponds to PageResultModel
success(String message)
Success, carry description information
success(String message, T data)
Success, with descriptive information and data
success(String message, T data, long total, int size, long pages, long current)
Success, with description, data, total number, number of entries per page, total number of pages, current page
error(String message)
Error, with detailed description
quick get start
We provide you with three entity classes to satisfy different scenarios, ResultModel for returning results in general, ApiResultModel for interface development for returning results, and PageResultModel for returning results in paging.Each of these three entity classes has its own Helper, so you can use them directly to return.Of course, the recommended way to use it is to write a tool class for each Helper, then return through the tool class, which may make it more reasonable to customize your own return tool class.
Return with Helper
Let's start with a simple example code:
/** * Add Method Example * @return {@link ResultModel} */ @ApiOperation(value = "Add Method Example") @PostMapping public ResultModel<?> add() { return ResultHelper.success("Added Successfully"); }
Return results:
{ "success": true, "message": "Added Successfully" }
Note: This is only an example of an interface return, not that the add interface should be written like this.
Write Return Results Tool Class
For example, we could write a ResultUtils tool class to operate on ResultHelper.Examples include the following:
/** * Success examples * @return {@link ResultModel} */ public static ResultModel <?> success() { return ResultHelper.success("Success"); }
Using the Return Results tool class
We can call the methods in the ResultUtils class, as shown in the following example:
/** * Success examples * @return {@link ResultModel} */ @ApiOperation(value = "Success examples") @DeleteMapping public ResultModel<?> success() { return ResultUtils.success(); }
Impression results:
{ "success": true, "message": "Success" }
Use examples
Example Diagram
Test Interface Preview
Models
Return a successful result example
/** * Delete Method Example * @return {@link ResultModel} */ @ApiOperation(value = "Delete Method Example") @DeleteMapping public ResultModel<?> delete() { return ResultUtils.success(); }
Response results:
{ "success": true, "message": "Success" }
Return Failed Result Example
If something goes wrong, how do we get back?Let's take a look:
/** * Example Modification Method * @return {@link ResultModel} */ @ApiOperation(value = "Example Modification Method") @PutMapping public ResultModel<?> update() { return ResultUtils.error("Modification failed"); }
Return results:
{ "success": false, "message": "Modification failed" }
Return query result example
It is worth mentioning that this is the query method. Let's take a look
/** * Example query method * @return {@link ResultModel} */ @ApiOperation(value = "Example query method") @GetMapping public ResultModel<?> get() { List<Map<String, String>> list = new ArrayList<>(); Map<String, String> map1 = new HashMap<>(); map1.put("name", "Zhang Fei"); map1.put("desc", "Swallow man Zhang Fei"); list.add(map1); Map<String, String> map2 = new HashMap<>(); map2.put("name", "Zhao Yun"); map2.put("desc", "Changshan Zhao Zilong"); list.add(map2); Map<String, String> map3 = new HashMap<>(); map3.put("name", "Guan Yu"); map3.put("desc", "Chopping Huaxiong with Warm Wine"); list.add(map3); return ResultUtils.success(list); }
Take a look at the response and see if it works as you like:
{ "success": true, "message": "Success", "data": [ { "name": "Zhang Fei", "desc": "Swallow man Zhang Fei" }, { "name": "Zhao Yun", "desc": "Changshan Zhao Zilong" }, { "name": "Guan Yu", "desc": "Chopping Huaxiong with Warm Wine" } ] }
Example of interface return data
/** * Example of interface return data * @return {@link ApiResultModel} */ @ApiOperation(value = "Example of interface return data") @GetMapping("/api-data") public ApiResultModel<Integer, ?> apiData() { return ApiResultUtils.success(getData()); }
Response results:
{ "success": true, "message": "Success", "data": [ { "name": "Zhang Fei", "desc": "Swallow man Zhang Fei" }, { "name": "Zhao Yun", "desc": "Changshan Zhao Zilong" }, { "name": "Guan Yu", "desc": "Chopping Huaxiong with Warm Wine" } ], "code": 0 }
Example interface return failure result
/** * API Interface error return example * @return {@link ApiResultModel} */ @ApiOperation(value = "API Interface error return example") @GetMapping("/api-error") public ApiResultModel<Integer, ?> apiError() { return ApiResultUtils.error(1101, "API Interface error return example"); }
Response results:
{ "success": false, "message": "API Interface error return example", "code": 1101 }
Paging Return Data Example
/** * Paging Return Data Example * @return {@link ApiResultModel} */ @ApiOperation(value = "Paging Return Data Example") @GetMapping("/page") public PageResultModel<?> page() { return PageResultUtils.success(getData(), 100, 10, 10, 1); }
Response results:
{ "success": true, "message": "Success", "data": [ { "name": "Zhang Fei", "desc": "Swallow man Zhang Fei" }, { "name": "Zhao Yun", "desc": "Changshan Zhao Zilong" }, { "name": "Guan Yu", "desc": "Chopping Huaxiong with Warm Wine" } ], "total": 100, "size": 10, "pages": 10, "current": 1 }
Tool class example
Return Results Tool Class
package com.fengwenyi.api_example.util; import com.fengwenyi.api_result.helper.ResultHelper; import com.fengwenyi.api_result.model.ResultModel; /** * Return Results Encapsulation Tool Class * @author Erwin Feng[xfsy_2015@163.com] * @since 2019/11/30 13:54 */ public class ResultUtils { /** * Success * @return {@link ResultModel} */ public static ResultModel <?> success() { return ResultHelper.success("Success"); } /** * Success, carrying data * @param data data * @param <T> Type of data * @return {@link ResultModel} */ public static <T> ResultModel <T> success(T data) { return ResultHelper.success("Success", data); } /** * Errors, with detailed error description information * @param message Detailed error description information * @return {@link ResultModel} */ public static ResultModel <?> error(String message) { return ResultHelper.error(message); } }
API Interface Return Results Tool Class
package com.fengwenyi.api_example.util; import com.fengwenyi.api_result.helper.ApiResultHelper; import com.fengwenyi.api_result.model.ApiResultModel; /** * API Interface Return Results Tool Class * @author Erwin Feng[xfsy_2015@163.com] * @since 2019/12/1 20:10 */ public class ApiResultUtils { /** * Success, carry return code and description information * @return {@link ApiResultModel} */ public static ApiResultModel<Integer, ?> success() { return ApiResultHelper.success(0, "Success"); } /** * Successfully, carry return codes, descriptions, and data * @param data data * @param <T> Type of data * @return {@link ApiResultModel} */ public static <T> ApiResultModel<Integer, T> success(T data) { return ApiResultHelper.success(0, "Success", data); } /** * Error, carry error and detailed description * @param code Return code * @param message Believe Descriptive Information * @return {@link ApiResultModel} */ public static ApiResultModel<Integer, ?> error(int code, String message) { return ApiResultHelper.error(code, message); } }
Paging Return Results Tool Class
package com.fengwenyi.api_example.util; import com.fengwenyi.api_result.helper.PageResultHelper; import com.fengwenyi.api_result.model.PageResultModel; /** * Paging Return Results Tool Class * @author Erwin Feng[xfsy_2015@163.com] * @since 2019/12/1 20:32 */ public class PageResultUtils { /** * Success, carrying paging related data and information * @param data data * @param total Total number of data bars * @param size Number of bars per page * @param pages PageCount * @param current Current Page * @param <T> data type * @return {@link PageResultModel} */ public static <T> PageResultModel<T> success(T data, long total, int size, long pages, long current) { return PageResultHelper.success("Success", data, total, size, pages, current); } }
Sample Parse Return Results
To add this, let me give you my opinion on how to parse the returned JSON string.The string returned is a json-formatted string, and here I'm going to use fastjson to write an example of parsing.We usually encapsulate the request data as a generic method or tool class and simply return the data. Of course, if it fails or an exception occurs, it's all handled here.
Examples of common return result parsing
/** * Examples of parsing common return results * @return data */ public Object parseResult() { String result = ""; ResultModel<?> resultModel = JSON.parseObject(result, ResultModel.class); Boolean success = resultModel.getSuccess(); if (success != null && success) { return resultModel.getData(); } else { // Exception Information String message = resultModel.getMessage(); // exception handling throw new DataParseException(message); } }
Interface Return Result Parsing Example
/** * Sample Parse Interface Return Results * @return data */ public Object parseApiResult() { String apiResult = ""; ApiResultModel<?, ?> apiResultModel = JSON.parseObject(apiResult, ApiResultModel.class); Boolean success = apiResultModel.getSuccess(); if (success != null && success) { return apiResultModel.getData(); } else { Object code = apiResultModel.getCode(); String message = apiResultModel.getMessage(); // Processing based on interface error codes // ... return null; } }
Paging Return Result Parsing Example
This is slightly different from the above, because some fields have been added, so we can use bean s to go back.
/** * Parse Paging Return Results Example * @return {@link PageResultDataBean} */ public PageResultDataBean parsePageResult() { String pageResult = ""; PageResultModel<List<?>> pageResultModel = JSON.parseObject(pageResult, PageResultModel.class); Boolean success = pageResultModel.getSuccess(); if (success != null && success) { List<?> data = pageResultModel.getData(); Long total = pageResultModel.getTotal(); Integer size = pageResultModel.getSize(); Long pages = pageResultModel.getPages(); Long current = pageResultModel.getCurrent(); return new PageResultDataBean() .setTotal(total) .setSize(size) .setPages(pages) .setCurrent(current) .setData(data); } else { // Exception Information String message = pageResultModel.getMessage(); // exception handling throw new DataParseException(message); } }
Above all, is this what you want?Welcome to comment and let me know.
link
[1] api-result source | github
[2] api-result source | code cloud
[3] api-result central warehouse
[4] Test sample code