English Readme | 中文说明
Example project(spring boot 2)
Document example | Document example for Front-Back-end interaction
People who have maintained the project should have experience. If the api documentation is written separately (org-mode, markdown, rap or even word), as the project cycle progresses, the gap between the interface document and the real code will come the farther away.
This document collection application has appeared because some of the details based on swagger are not so good, For example, the map cannot be parsed, the circular reference cannot be parsed, and the entry and exit parameters are poorly sorted. view desc need to be swtich(comments should be where the examples are, not together is a very bad experience).
add maven
<dependency>
<groupId>com.github.liuanxin</groupId>
<artifactId>api-document</artifactId>
<version>0.9.8</version>
</dependency>
add config for this
@Configuration
@EnableApiInfo
public class ApiInfoConfig {
// can be set in different profile, such as:
// application.yml => online: false
// application-test.yml => online: false
// application-prod.yml => online: true
@Value("${online:false}")
private boolean online;
@Bean
public DocumentCopyright apiCopyright() {
return new DocumentCopyright("title", "team", "version", "copyright")
// not collect if true, default is false.
.setOnline(online)
// // if some api can't use @ApiIgnore, set this(url|method, method can be ignore)
// .setIgnoreUrlSet(Sets.newHashSet("/user*", "/product/info|post"))
// // if class or method has @ApiResponses, use that
// .setGlobalResponse(Arrays.asList(
// new DocumentResponse(400, "param error"),
// new DocumentResponse(500, "request error").setResponse(XXX.class) // see @ApiReturnType
// ))
// // current config will be generated in the parameters of each api, if only want to use
// // on a specific api, or set this global config but want to ignore on a specific api,
// // use @ApiTokens annotation
// .setGlobalTokens(Arrays.asList(
// DocumentParam.buildToken("x-token", "oauth info", "abc", ParamType.Header).setHasTextarea("1"),
// DocumentParam.buildToken("x-version", "api version", "1.0.0", ParamType.Query).setRequired("1")
// ))
// // field comment is output in the return example.
// // default is true. set to false will be listed separately.
// .setCommentInReturnExample(false)
// // used in multi-document collection, merged items and output, default is false
// // If true, please ensure that the global response description
// // and global token of all items are consistent.
// // Duplication and appending together (current practice) will cause documentation errors.
// // If false, multiple documents will be requested on the page,
// // please ensure that all projects have cors turned on,
// // otherwise it will be inaccessible due to cross-domain issues
// .setProjectMerge(true)
// // Collecting document for other projects
// .setProjectMap(new LinkedHashMap<String, String>() {{
// // key: name, value: project address
// put("user", "http://ip:port/user");
// put("product", "http://ip:port/product");
// }})
;
}
}
Then mark the corresponding annotations in the corresponding controller layer(only collect the documents related to
@RestController or @ResponseBody related classes and interfaces, If the result of the method is List,
Set or Map will be processed by ArrayList, HashSet and HashMap),
ResponseEntity
or Callable
or DeferredResult
or WebAsyncTask
will handle the generic type it defines
(it will not be resolved without setting).
PS: You can refer to the global processing of example project(spring boot 2). For generics, be sure to use certain types, such as <String> <User> etc. If use a type like <T> <Object> will not be able to parse
@SpringBootApplication
public class ExampleApplication {
public static void main(String[] args) {
SpringApplication.run(ExampleApplication.class, args);
}
}
@ApiGroup("example")
@RestController
public class ExampleController {
@ApiMethod("user list")
@GetMapping("/example")
public JsonResult<DemoVo> example(@ApiParam("user type") String type, Page page) {
return JsonResult.success("example api", new DemoVo());
}
}
public class Page {
@ApiParam("current page")
private Integer page;
@ApiParam("page limit")
private Integer limit;
...
setter/getter
}
public class JsonResult<T> {
@ApiReturn("return code")
private JsonCode code;
@ApiReturn("return message")
private String msg;
@ApiReturn("return data")
private T data;
...
setter/getter
}
public enum JsonCode {
SUCCESS(200, "success"),
NOT_LOGIN(401, "need login"),
FAIL(500, "internal error or service exception")
int code;
String value;
JsonCode(int code, String value) {
this.code = code;
this.value = value;
}
...
getter
}
public class DemoVo {
private Long id;
@ApiReturn("名称")
private String name;
...
setter/getter
}
@ApiGroup --> in class or method. use the method if all of that
value --> module info, required
index --> can not be set, more forward when smaller("index" first,
"module info" second -> with sort), if set multi module and different index, use the smaller
@ApiResponses --> in class or method. marked on class or method will return the specified response,
otherwise it will take the global response configuration.
value --> @ApiResponse[], required
@ApiResponse --> nested annotation
code --> required, for example: 400
msg --> required, for example: param error
type --> nested annotation: @ApiReturnType[], can not be set
for example:
@ApiResponses({
@ApiResponse(code = 400, msg = "param error", type = { @ApiReturnType(XXX.class }),
@ApiResponse(code = 500, msg = "request error")
})
@ApiReturnType --> nested annotation, use on @ApiResponse or @ApiMethod
value --> return class, required
generic --> return type of generic type, can not be set
genericParent --> returns the parent level of the generic type in the type, can not be set
genericChild --> returns the sub-level of the generic type of the type, can not be set
for example:
XXX ==> @ApiReturnType(XXX.class)
List<XXX> ==> @ApiReturnType(value = List.class, generic = XXX.class)
Set<XXX> ==> @ApiReturnType(value = Set.class, generic = XXX.class)
Map<String, XXX> ==> @ApiReturnType(value = Map.class, generic = { String.class, XXX.class })
JsonResult<XXX> ==> @ApiReturnType(value = JsonResult.class, generic = XXX.class)
JsonResult<List<XXX>> ==> @ApiReturnType(
value = JsonResult.class,
genericParent = List.class,
generic = XXX.class
)
JsonResult<Set<XXX>> ==> @ApiReturnType(
value = JsonResult.class,
genericParent = Set.class,
generic = XXX.class
)
JsonResult<Map<String, XXX>> ==> @ApiReturnType(
value = JsonResult.class,
genericParent = Map.class,
generic = { String.class, XXX.class }
)
JsonResult<YYY<XXX>> ==> @ApiReturnType(
value = JsonResult.class,
genericParent = YYY.class,
generic = XXX.class
)
JsonResult<YYY<List<XXX>>> ==> @ApiReturnType(
value = JsonResult.class,
genericParent = YYY.class,
generic = List.class,
genericChild = XXX.class
)
JsonResult<YYY<Set<XXX>>> ==> @ApiReturnType(
value = JsonResult.class,
genericParent = YYY.class,
generic = Set.class,
genericChild = XXX.class
)
JsonResult<YYY<Map<String, XXX>>> ==> @ApiReturnType(
value = JsonResult.class,
genericParent = YYY.class,
generic = Map.class,
genericChild = { String.class, XXX.class }
)
@ApiMethod --> in method
value --> method title, required
develop --> can not be set
desc --> description, can not be set
index --> more forward when smaller, can not be set("index" first,
"developer" second, "title" third -> with sort)
commentInReturnExample --> if false, comment will show with display separately,
if not set, the global setting shall prevail
returnType --> nested annotation: @ApiReturnType[]. customize return type,
if set will ignore 「the return type」 on method
@ApiIgnore --> in class or method. want to ignore some api, use it
value --> false will ignore
@ApiParam --> in param or field
value --> param comment, can not be set
name --> if set, can not be set, will ignore param name or field name
dataType --> if type was custom can use, can not be set(for example: enum,
but param type was be int). can be: int、long、float、double、date、phone、email、url、ipv4
example --> used in api examples, can not be set
paramType --> can not be set, Header or Query, default is Query
required --> can not be set, if param annotation @RequestParam(required = true) etc... will ignore this config
textarea --> can not be set, param will show with textarea(in example page), default is false
datePattern --> can not be set, is param type has Date, for example: MM/dd/yyyy HH:mm:ss
style --> can not be set. html style with param on page, for example: color:green;height:35px;
@ApiParamIgnore --> in param or field
@ApiReturn --> in field
value --> can not be set
name --> return name, can not be set, if set will ignore field name(when use @JsonProperty)
type --> if type was custom can use, can not be set(for example: enum, but return type was be int)
example --> return example, can not be set, only if the field is a string or
underlying data type(including BigInteger and BigDecimal)
@ApiReturnIgnore --> in field, use with @JsonIgnore is also
@ApiTokens --> in class or method
useGlobal --> whether to use global token, cant not be set, default is false
value --> @ApiToken[]
@ApiToken --> nested annotation
name --> required
desc --> can not be set
example --> can not be set
dataType --> data type. for example: int、long、float、double、date、phone、email、url、ipv4
paramType --> can not be set, Header or Query, default is Header
required --> default false
textarea --> default false
datePattern --> parameter type is date format of the date, can not be set. for example: MM/dd/yyyy HH:mm:ss
style --> can not be set. html style with param on page, for example: color:green;height:35px;
for example:
@ApiTokens // marked on class or method will not generate global token information.
@ApiTokens(token = {
@ApiToken(name = "x-token", desc = "oauth info", example = "abc-xyz", textarea = true),
@ApiToken(name = "x-version", desc = "api version", example = "1.0", paramType = ParamType.Query, required = true)
})
@ApiModel --> Combined with the annotations of the @ApiParam and @ApiReturn,
Please do not abuse. You should try to use the first two.
value --> (return type or param name)'s comment, can not be set
name --> (return type or param name)'s name, can not be set
dataType --> (return type or param name)'s type, can not be set,
use with customize: int、long、float、double、date、phone、email、url、ipv4
example --> (return type or param name)'s example, can not be set
// The above attributes apply to both the request parameter and the return field.
// The following attributes are only used on the request parameters.
paramType --> param type, can not be set. Header or Query, default is Query
required --> param required, can not be set,
if has @RequestParam(required = true) etc... will ignore this setting
textarea --> can not be set, param will show with textarea(in example page), default is false
datePattern --> can not be set, is param type has Date, for example: MM/dd/yyyy HH:mm:ss
style --> can not be set. html style with param on page, for example: color:green;height:35px;
if not spring boot project, add this config
<mvc:resources mapping="/static/**" location="classpath:/static/" />
Run and request http://ip:port/static/api.html
(spring boot don’t need /static second directory)
test backend url, request http://ip:port/static/api-example.html
Final document collect for this: https://liuanxin.github.io/api-info-en.html