2
2
3
3
import io .swagger .v3 .oas .models .Components ;
4
4
import io .swagger .v3 .oas .models .OpenAPI ;
5
+ import io .swagger .v3 .oas .models .PathItem ;
6
+ import io .swagger .v3 .oas .models .Paths ;
5
7
import io .swagger .v3 .oas .models .info .Info ;
6
8
import io .swagger .v3 .oas .models .security .SecurityRequirement ;
7
9
import io .swagger .v3 .oas .models .security .SecurityScheme ;
8
10
import io .swagger .v3 .oas .models .servers .Server ;
9
11
import io .swagger .v3 .oas .models .servers .ServerVariable ;
10
12
import io .swagger .v3 .oas .models .servers .ServerVariables ;
13
+ import io .swagger .v3 .oas .models .tags .Tag ;
11
14
import org .lowcoder .sdk .config .CommonConfig ;
15
+ import org .springdoc .api .OpenApiCustomiser ;
12
16
import org .springframework .beans .factory .annotation .Autowired ;
13
17
import org .springframework .beans .factory .annotation .Value ;
14
18
import org .springframework .context .annotation .Bean ;
15
19
import org .springframework .context .annotation .Configuration ;
16
20
17
21
import java .util .Arrays ;
22
+ import java .util .Comparator ;
23
+ import java .util .Map ;
24
+ import java .util .TreeMap ;
18
25
19
26
@ Configuration
20
27
public class OpenAPIDocsConfiguration {
28
+
21
29
@ Autowired
22
30
private CommonConfig commonConfig ;
23
31
24
32
@ Value ("${server.port:8080}" )
25
33
private int serverPort ;
26
-
34
+
27
35
@ Value ("${spring.webflux.base-path:/}" )
28
36
private String contextPath ;
29
-
30
- @ Bean
31
- OpenAPI customizeOpenAPI () {
32
37
38
+ /**
39
+ * Configures the core OpenAPI spec including servers, security and info.
40
+ */
41
+ @ Bean
42
+ public OpenAPI customizeOpenAPI () {
33
43
final String securitySchemeName = commonConfig .getCookieName ();
34
44
35
45
return new OpenAPI ()
36
- .info (new Info ()
37
- .title ("Lowcoder Open Rest API" )
38
- .version (commonConfig .getApiVersion ()))
39
- /*.addServersItem(new Server()
40
- .url(createLocalServerUrl("localhost", serverPort, contextPath))
41
- .description("Local development API service")
42
- ) */
43
- .addServersItem (createCustomServer ())
44
- .addServersItem (new Server ()
45
- .url ("https://api-service.lowcoder.cloud/" )
46
- .description ("Lowcoder Community Edition: Public Cloud API Access" )
47
- )
48
- .addSecurityItem (new SecurityRequirement ()
49
- .addList (securitySchemeName )).components (new Components ()
50
- /* .addSecuritySchemes(
51
- securitySchemeName,
52
- new SecurityScheme()
53
- .name(securitySchemeName)
54
- .type(SecurityScheme.Type.HTTP) // HTTP-based authentication
55
- .scheme("cookie") // Specify the authentication scheme as "cookie"
56
- .description("Cookie-based authentication. Please ensure the client sends cookies with each request after authentication.")
57
- ) */
58
- .addSecuritySchemes (
59
- "API Key" ,
60
- new SecurityScheme ()
61
- .name ("Authorization" )
62
- .type (SecurityScheme .Type .APIKEY )
63
- .in (SecurityScheme .In .HEADER )
64
- .scheme ("bearer" )
65
- .bearerFormat ("JWT" )
66
- .description ("API Key Authentication with a Bearer token. Copy your API Key and prefix it here with 'Bearer ' (e.g. 'Bearer eyJhbGciO...'" )
67
- )
68
- );
46
+ .info (new Info ()
47
+ .title ("Lowcoder Open Rest API" )
48
+ .version (commonConfig .getApiVersion ()))
49
+ .addServersItem (createCustomServer ())
50
+ .addServersItem (new Server ()
51
+ .url ("https://api-service.lowcoder.cloud/" )
52
+ .description ("Lowcoder Community Edition: Public Cloud API Access" ))
53
+ .addSecurityItem (new SecurityRequirement ().addList (securitySchemeName ))
54
+ .components (new Components ()
55
+ .addSecuritySchemes ("API Key" , new SecurityScheme ()
56
+ .name ("Authorization" )
57
+ .type (SecurityScheme .Type .APIKEY )
58
+ .in (SecurityScheme .In .HEADER )
59
+ .scheme ("bearer" )
60
+ .bearerFormat ("JWT" )
61
+ .description ("API Key Authentication with a Bearer token. Copy your API Key and prefix it here with 'Bearer ' (e.g. 'Bearer eyJhbGciO...')" )));
69
62
}
70
-
71
-
72
- /* private static String createLocalServerUrl(String domain, int port, String contextPath)
73
- {
74
- StringBuilder sb = new StringBuilder("http");
75
-
76
- if (port == 443)
77
- {
78
- sb.append("s");
79
- }
80
- sb.append("://").append(domain);
81
63
82
- if (port != 80 && port != 443)
83
- {
84
- sb.append(":").append(port);
85
- }
86
- sb.append(contextPath);
87
-
88
- return sb.toString();
89
- } */
90
-
91
- private Server createCustomServer ()
92
- {
93
- String url = "{scheme}://{domain}:{port}{basePath}" ;
94
-
95
- Server server = new Server ()
96
- .description ("Lowcoder Self-hosted Installation API Access" )
97
- .url (url )
98
- .variables (new ServerVariables ()
99
- .addServerVariable ("scheme" , new ServerVariable ()
100
- ._default ("http" )
101
- .description ("HTTP scheme" )
102
- ._enum (Arrays .asList ("http" , "https" )))
103
- .addServerVariable ("domain" , new ServerVariable ()
104
- .description ("Lowcoder IP address or domain" )
105
- ._default ("localhost" ))
106
- .addServerVariable ("port" , new ServerVariable ()
107
- .description ("Port" )
108
- ._default ("3000" ))
109
- .addServerVariable ("basePath" , new ServerVariable ()
110
- .description ("Base path" )
111
- ._default (contextPath ))
112
- );
113
- return server ;
64
+ /**
65
+ * Creates a dynamic server entry using server variables.
66
+ */
67
+ private Server createCustomServer () {
68
+ String url = "{scheme}://{domain}:{port}{basePath}" ;
69
+
70
+ return new Server ()
71
+ .description ("Lowcoder Self-hosted Installation API Access" )
72
+ .url (url )
73
+ .variables (new ServerVariables ()
74
+ .addServerVariable ("scheme" , new ServerVariable ()
75
+ ._default ("http" )
76
+ .description ("HTTP scheme" )
77
+ ._enum (Arrays .asList ("http" , "https" )))
78
+ .addServerVariable ("domain" , new ServerVariable ()
79
+ .description ("Lowcoder IP address or domain" )
80
+ ._default ("localhost" ))
81
+ .addServerVariable ("port" , new ServerVariable ()
82
+ .description ("Port" )
83
+ ._default ("3000" ))
84
+ .addServerVariable ("basePath" , new ServerVariable ()
85
+ .description ("Base path" )
86
+ ._default (contextPath )));
87
+ }
88
+
89
+ /**
90
+ * Customizes the OpenAPI spec at runtime to sort tags and paths.
91
+ */
92
+ @ Bean
93
+ public OpenApiCustomiser sortOpenApiSpec () {
94
+ return openApi -> {
95
+ // Sort tags alphabetically
96
+ if (openApi .getTags () != null ) {
97
+ openApi .getTags ().sort (Comparator .comparing (Tag ::getName ));
98
+ }
99
+
100
+ // Sort paths alphabetically by their URL
101
+ if (openApi .getPaths () != null ) {
102
+ Map <String , PathItem > sorted = new TreeMap <>(openApi .getPaths ());
103
+ Paths sortedPaths = new Paths ();
104
+ sorted .forEach (sortedPaths ::addPathItem );
105
+ openApi .setPaths (sortedPaths );
106
+ }
107
+ };
114
108
}
115
- }
109
+ }
0 commit comments