Skip to content

Commit c829f3a

Browse files
author
FalkWolsky
committed
Updating API Auto-Docs
1 parent 849452d commit c829f3a

File tree

6 files changed

+108
-87
lines changed

6 files changed

+108
-87
lines changed

server/api-service/lowcoder-server/pom.xml

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -56,10 +56,10 @@
5656
<artifactId>lowcoder-plugin-api</artifactId>
5757
</dependency>
5858

59-
<dependency>
60-
<groupId>ch.qos.logback</groupId>
61-
<artifactId>logback-classic</artifactId>
62-
</dependency>
59+
<dependency>
60+
<groupId>ch.qos.logback</groupId>
61+
<artifactId>logback-classic</artifactId>
62+
</dependency>
6363
<dependency>
6464
<groupId>org.springframework.boot</groupId>
6565
<artifactId>spring-boot-starter-security</artifactId>
@@ -77,6 +77,11 @@
7777
<groupId>org.springdoc</groupId>
7878
<artifactId>springdoc-openapi-starter-webflux-ui</artifactId>
7979
</dependency>
80+
<dependency>
81+
<groupId>org.springdoc</groupId>
82+
<artifactId>springdoc-openapi-core</artifactId>
83+
<version>1.1.49</version>
84+
</dependency>
8085
<dependency>
8186
<groupId>io.projectreactor.tools</groupId>
8287
<artifactId>blockhound</artifactId>

server/api-service/lowcoder-server/src/main/java/org/lowcoder/api/OpenAPIDocsConfiguration.java

Lines changed: 75 additions & 81 deletions
Original file line numberDiff line numberDiff line change
@@ -2,114 +2,108 @@
22

33
import io.swagger.v3.oas.models.Components;
44
import io.swagger.v3.oas.models.OpenAPI;
5+
import io.swagger.v3.oas.models.PathItem;
6+
import io.swagger.v3.oas.models.Paths;
57
import io.swagger.v3.oas.models.info.Info;
68
import io.swagger.v3.oas.models.security.SecurityRequirement;
79
import io.swagger.v3.oas.models.security.SecurityScheme;
810
import io.swagger.v3.oas.models.servers.Server;
911
import io.swagger.v3.oas.models.servers.ServerVariable;
1012
import io.swagger.v3.oas.models.servers.ServerVariables;
13+
import io.swagger.v3.oas.models.tags.Tag;
1114
import org.lowcoder.sdk.config.CommonConfig;
15+
import org.springdoc.api.OpenApiCustomiser;
1216
import org.springframework.beans.factory.annotation.Autowired;
1317
import org.springframework.beans.factory.annotation.Value;
1418
import org.springframework.context.annotation.Bean;
1519
import org.springframework.context.annotation.Configuration;
1620

1721
import java.util.Arrays;
22+
import java.util.Comparator;
23+
import java.util.Map;
24+
import java.util.TreeMap;
1825

1926
@Configuration
2027
public class OpenAPIDocsConfiguration {
28+
2129
@Autowired
2230
private CommonConfig commonConfig;
2331

2432
@Value("${server.port:8080}")
2533
private int serverPort;
26-
34+
2735
@Value("${spring.webflux.base-path:/}")
2836
private String contextPath;
29-
30-
@Bean
31-
OpenAPI customizeOpenAPI() {
3237

38+
/**
39+
* Configures the core OpenAPI spec including servers, security and info.
40+
*/
41+
@Bean
42+
public OpenAPI customizeOpenAPI() {
3343
final String securitySchemeName = commonConfig.getCookieName();
3444

3545
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...')")));
6962
}
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);
8163

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+
};
114108
}
115-
}
109+
}

server/api-service/lowcoder-server/src/main/java/org/lowcoder/api/application/ApplicationEndpoints.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -149,6 +149,12 @@ public Mono<ResponseView<ApplicationView>> publish(@PathVariable String applicat
149149
public Mono<ResponseView<Boolean>> updateEditState(@PathVariable String applicationId,
150150
@RequestBody UpdateEditStateRequest updateEditStateRequest);
151151

152+
@Operation(
153+
tags = TAG_APPLICATION_MANAGEMENT,
154+
operationId = "updateApplicationSlug",
155+
summary = "Update Application URL Path Slug",
156+
description = "The slug is used to build a friendly reader URL for Apps instead of the ID"
157+
)
152158
@PutMapping("/{applicationId}/slug")
153159
public Mono<ResponseView<Application>> updateSlug(@PathVariable String applicationId, @RequestBody String slug);
154160

server/api-service/lowcoder-server/src/main/java/org/lowcoder/api/framework/IndexController.java

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,22 @@
55
import org.springframework.http.MediaType;
66
import org.springframework.web.bind.annotation.GetMapping;
77
import org.springframework.web.bind.annotation.RestController;
8+
9+
import io.swagger.v3.oas.annotations.Operation;
810
import reactor.core.publisher.Mono;
911

1012
@RequiredArgsConstructor
1113
@RestController
1214
public class IndexController {
1315

16+
public static final String TAG_ROOT = "API Root Endpoint";
17+
18+
@Operation(
19+
tags = TAG_ROOT,
20+
operationId = "getHelloWorld",
21+
summary = "Get the hello world Message from Lowcoder API",
22+
description = "Retrieve the Hello World Message. If the API Service operates normal, the response is: {\"code\":1,\"message\":\"Lowcoder API is up and runnig\",\"success\":true}"
23+
)
1424
@GetMapping(value = "/", consumes = {MediaType.ALL_VALUE})
1525
public Mono<ResponseView<Void>> index() {
1626
return Mono.just(ResponseView.error(ResponseView.SUCCESS, "Lowcoder API is up and runnig"));

server/api-service/lowcoder-server/src/main/java/org/lowcoder/api/usermanagement/OrganizationEndpoints.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -181,6 +181,12 @@ public Mono<ResponseView<Boolean>> removeUserFromOrg(@PathVariable String orgId,
181181
@GetMapping("/{orgId}/api-usage")
182182
public Mono<ResponseView<Long>> getOrgApiUsageCount(@PathVariable String orgId, @RequestParam(required = false) Boolean lastMonthOnly);
183183

184+
@Operation(
185+
tags = TAG_ORGANIZATION_MANAGEMENT,
186+
operationId = "updateOrganizationSlug",
187+
summary = "Update Organization URL Path Slug",
188+
description = "The slug is used to build a friendly reader URL for Apps. The Organization (workspace) get a part of this URL with an own slug."
189+
)
184190
@PutMapping("/{orgId}/slug")
185191
Mono<ResponseView<Organization>> updateSlug(@PathVariable String orgId, @RequestBody String slug);
186192

server/api-service/lowcoder-server/src/main/resources/application.yaml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -64,8 +64,8 @@ common:
6464
domain:
6565
default-value: lowcoder.org
6666
cloud: false
67-
version: 2.1.4
68-
apiVersion: 1.1
67+
version: 2.7.0
68+
apiVersion: 1.2
6969
block-hound-enable: false
7070
encrypt:
7171
password: ${LOWCODER_DB_ENCRYPTION_PASSWORD:lowcoder.org}

0 commit comments

Comments
 (0)