-
Notifications
You must be signed in to change notification settings - Fork 10
API Documentation to Console
This guide walks you through adding OpenAPI documentation for new API endpoints in the Console project.
Console uses Fuego to automatically generate OpenAPI 3.0 documentation from your Go code. The documentation is generated at runtime when running in debug mode.
API endpoints are organized as follows:
internal/
├── controller/
│ └── openapi/
│ ├── adapter.go # Main OpenAPI adapter setup
│ ├── devices.go # Device-related endpoints
│ ├── devicemanagement.go # Device management endpoints
│ ├── cira.go # CIRA endpoints
│ └── ...
├── usecase/
│ └── devices/
│ ├── info.go # Business logic for device info
│ ├── power.go # Business logic for power operations
│ └── ...
└── entity/
└── dto/
└── v1/
├── device.go # DTOs for devices
├── power.go # DTOs for power operations
└── ...
Use Go structs to define your API's request and response formats. These DTOs form the basis of your API documentation and ensure type-safe data handling.
Location: internal/entity/dto/v1/ - Choose or create a file based on your feature:
Example File: internal/entity/dto/v1/power.go
package dto
// PowerState represents the current power state of a device
type PowerState struct {
PowerState int `json:"powerstate" example:"2"`
OSPowerSavingState int `json:"osPowerSavingState" example:"0"`
}Key Points:
- Use
jsontags to define the JSON field names - Use
exampletags for OpenAPI documentation examples - Use
binding:"required"for required fields in request bodies - Export fields (capitalize first letter) to make them accessible
The use case layer contains the business logic and orchestrates data access.
Location: internal/usecase/devices/ - Choose or create a file based on functionality:
Example File: internal/usecase/devices/power.go
package devices
import (
"context"
"github.com/device-management-toolkit/console/internal/entity/dto/v1"
)
// GetPowerState retrieves the current power state of a device
func (uc *UseCase) GetPowerState(c context.Context, guid string) (dto.PowerState, error) {
item, err := uc.repo.GetByID(c, guid, "")
if err != nil {
return dto.PowerState{}, err
}
if item == nil || item.GUID == "" {
return dto.PowerState{}, ErrNotFound
}
device := uc.device.SetupWsmanClient(*item, false, true)
state, err := device.GetPowerState()
if err != nil {
return dto.PowerState{}, err
}
stateOS, err := device.GetOSPowerSavingState()
if err != nil {
// Return partial data if OS state fails
return dto.PowerState{
PowerState: int(state[0].PowerState),
OSPowerSavingState: 0, // UNKNOWN
}, err
}
return dto.PowerState{
PowerState: int(state[0].PowerState),
OSPowerSavingState: int(stateOS),
}, nil
}The controller layer handles HTTP requests and connects them to your use cases. This is where OpenAPI documentation is generated.
Location: internal/controller/openapi/ - Choose the appropriate file:
-
devicemanagement.go- Device management operations (power, logs, version, hardware info, certificates, alarms) -
devices.go- Device CRUD operations, listing, and basic device operations -
cira.go- CIRA configuration endpoints -
profiles.go- Profile management -
wireless.go- Wireless configuration -
ieee8021x.go- IEEE 802.1x configuration - Create a new file if adding a completely new feature area
Example File: internal/controller/openapi/devicemanagement.go
package openapi
import (
"github.com/go-fuego/fuego"
"github.com/device-management-toolkit/console/internal/entity/dto/v1"
)
// Add route registration in RegisterDeviceManagementRoutes()
func (f *FuegoAdapter) RegisterDeviceManagementRoutes() {
// ... existing routes ...
// Power State endpoint
fuego.Get(f.server, "/api/v1/admin/amt/power/state/{guid}", f.getPowerState,
fuego.OptionTags("Device Management"),
fuego.OptionSummary("Get Power State"),
fuego.OptionDescription("Retrieve the current power state of a device"),
fuego.OptionPath("guid", "Device GUID"),
)
}
// Handler function - calls your use case
func (f *FuegoAdapter) getPowerState(c fuego.ContextNoBody) (dto.PowerState, error) {
// Extract path parameter
guid := c.PathParam("guid")
// Call the use case to get actual data
response, err := f.devices.GetPowerState(c.Context(), guid)
if err != nil {
return dto.PowerState{}, err
}
return response, nil
}Adding a New Feature Area?:
- After creating your new
Register*Routes()function, add it to the mainRegisterRoutes()function inadapter.go - Without this registration, your new endpoints won't be wired up to the server
File: internal/controller/openapi/adapter.go
func (f *FuegoAdapter) RegisterRoutes() {
// Profiles
f.RegisterProfileRoutes()
// Wireless
f.RegisterWirelessConfigRoutes()
...
// Add your new feature area here
// f.RegisterYourNewFeatureRoutes()
}In your .env file:
GIN_MODE=debuggo run ./cmd/app/main.goYou should see output like:
DAP server listening at: 127.0.0.1:53453
2025/10/27 11:02:03 migrate: environment variable not declared: DB_URL -- using embedded database
2025/10/27 11:02:03 DB path : C:\Users\AMT\AppData\Roaming\device-management-toolkit\console.db
2025/10/27 11:02:03 OpenAPI specification generated at doc/openapi.json
View JSON Specification:
# View in browser
http://localhost:8181/api/openapi.json
# Or download with curl
curl http://localhost:8181/api/openapi.json -o openapi.json- Check existing code for examples in
internal/controller/openapi/ - Review Fuego Documentation