Add API Documentation Service and enhance existing services with OpenAPI support

This commit is contained in:
glenn schrooyen
2025-09-11 22:24:56 +02:00
parent 21e4972ab1
commit 63b4bb487d
14 changed files with 800 additions and 69 deletions

View File

@@ -0,0 +1,49 @@
package com.labfusion.config;
import io.swagger.v3.oas.models.OpenAPI;
import io.swagger.v3.oas.models.info.Info;
import io.swagger.v3.oas.models.info.Contact;
import io.swagger.v3.oas.models.info.License;
import io.swagger.v3.oas.models.servers.Server;
import io.swagger.v3.oas.models.security.SecurityRequirement;
import io.swagger.v3.oas.models.security.SecurityScheme;
import io.swagger.v3.oas.models.Components;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import java.util.List;
@Configuration
public class OpenApiConfig {
@Bean
public OpenAPI customOpenAPI() {
return new OpenAPI()
.info(new Info()
.title("LabFusion API Gateway")
.description("Core API gateway for LabFusion homelab dashboard. Provides authentication, dashboard management, and data storage.")
.version("1.0.0")
.contact(new Contact()
.name("LabFusion Team")
.url("https://github.com/labfusion/labfusion")
.email("team@labfusion.dev"))
.license(new License()
.name("MIT License")
.url("https://opensource.org/licenses/MIT")))
.servers(List.of(
new Server()
.url("http://localhost:8080")
.description("Development Server"),
new Server()
.url("https://api.labfusion.dev")
.description("Production Server")
))
.addSecurityItem(new SecurityRequirement().addList("bearerAuth"))
.components(new Components()
.addSecuritySchemes("bearerAuth", new SecurityScheme()
.type(SecurityScheme.Type.HTTP)
.scheme("bearer")
.bearerFormat("JWT")
.description("JWT token authentication")));
}
}

View File

@@ -3,6 +3,14 @@ package com.labfusion.controller;
import com.labfusion.model.Dashboard;
import com.labfusion.model.User;
import com.labfusion.service.DashboardService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.media.Content;
import io.swagger.v3.oas.annotations.media.Schema;
import io.swagger.v3.oas.annotations.responses.ApiResponse;
import io.swagger.v3.oas.annotations.responses.ApiResponses;
import io.swagger.v3.oas.annotations.security.SecurityRequirement;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.security.core.annotation.AuthenticationPrincipal;
@@ -14,19 +22,37 @@ import java.util.Optional;
@RestController
@RequestMapping("/api/dashboards")
@CrossOrigin(origins = "*")
@Tag(name = "Dashboard Management", description = "APIs for managing user dashboards and widgets")
@SecurityRequirement(name = "bearerAuth")
public class DashboardController {
@Autowired
private DashboardService dashboardService;
@GetMapping
@Operation(summary = "Get user dashboards", description = "Retrieve all dashboards for the authenticated user")
@ApiResponses(value = {
@ApiResponse(responseCode = "200", description = "Successfully retrieved dashboards",
content = @Content(mediaType = "application/json", schema = @Schema(implementation = Dashboard.class))),
@ApiResponse(responseCode = "401", description = "Unauthorized")
})
public ResponseEntity<List<Dashboard>> getDashboards(@AuthenticationPrincipal User user) {
List<Dashboard> dashboards = dashboardService.getDashboardsByUser(user);
return ResponseEntity.ok(dashboards);
}
@GetMapping("/{id}")
public ResponseEntity<Dashboard> getDashboard(@PathVariable Long id, @AuthenticationPrincipal User user) {
@Operation(summary = "Get dashboard by ID", description = "Retrieve a specific dashboard by its ID")
@ApiResponses(value = {
@ApiResponse(responseCode = "200", description = "Successfully retrieved dashboard",
content = @Content(mediaType = "application/json", schema = @Schema(implementation = Dashboard.class))),
@ApiResponse(responseCode = "403", description = "Forbidden - User doesn't own this dashboard"),
@ApiResponse(responseCode = "404", description = "Dashboard not found"),
@ApiResponse(responseCode = "401", description = "Unauthorized")
})
public ResponseEntity<Dashboard> getDashboard(
@Parameter(description = "Dashboard ID") @PathVariable Long id,
@AuthenticationPrincipal User user) {
Optional<Dashboard> dashboard = dashboardService.getDashboardById(id);
if (dashboard.isPresent()) {
// Check if user owns the dashboard

View File

@@ -4,6 +4,13 @@ import com.labfusion.model.DeviceState;
import com.labfusion.model.Event;
import com.labfusion.repository.DeviceStateRepository;
import com.labfusion.repository.EventRepository;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.media.Content;
import io.swagger.v3.oas.annotations.media.Schema;
import io.swagger.v3.oas.annotations.responses.ApiResponse;
import io.swagger.v3.oas.annotations.responses.ApiResponses;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
@@ -14,6 +21,7 @@ import java.util.List;
@RestController
@RequestMapping("/api/system")
@CrossOrigin(origins = "*")
@Tag(name = "System Data", description = "APIs for system events, device states, and metrics")
public class SystemController {
@Autowired

View File

@@ -44,3 +44,14 @@ management:
endpoint:
health:
show-details: always
# OpenAPI/Swagger Configuration
springdoc:
api-docs:
path: /v3/api-docs
swagger-ui:
path: /swagger-ui.html
operationsSorter: method
tagsSorter: alpha
display-request-duration: true
show-actuator: true