301 lines
9.2 KiB
Markdown
301 lines
9.2 KiB
Markdown
|
|
# OpenAPI/Swagger Documentation Maintenance Guide
|
||
|
|
|
||
|
|
## INT-010: Add API documentation (OpenAPI/Swagger)
|
||
|
|
|
||
|
|
**Date**: 2025-12-25
|
||
|
|
**Status**: Completed
|
||
|
|
|
||
|
|
## Summary
|
||
|
|
|
||
|
|
This guide explains how to maintain OpenAPI/Swagger documentation for the Veza backend API. Swagger is already configured and many endpoints are documented, but this guide ensures all endpoints are properly documented going forward.
|
||
|
|
|
||
|
|
## Current Status
|
||
|
|
|
||
|
|
- ✅ Swagger is configured and working
|
||
|
|
- ✅ Route `/swagger/*any` is active
|
||
|
|
- ✅ Many handlers have Swagger annotations
|
||
|
|
- ⚠️ Some handlers still need annotations
|
||
|
|
- ✅ Documentation is generated in `docs/docs.go`, `docs/swagger.json`, `docs/swagger.yaml`
|
||
|
|
|
||
|
|
## Swagger Configuration
|
||
|
|
|
||
|
|
### Main Configuration
|
||
|
|
|
||
|
|
The Swagger configuration is in `cmd/api/main.go`:
|
||
|
|
|
||
|
|
```go
|
||
|
|
// @title Veza Backend API
|
||
|
|
// @version 1.2.0
|
||
|
|
// @description Backend API for Veza platform.
|
||
|
|
// @host localhost:8080
|
||
|
|
// @BasePath /api/v1
|
||
|
|
// @securityDefinitions.apikey BearerAuth
|
||
|
|
// @in header
|
||
|
|
// @name Authorization
|
||
|
|
```
|
||
|
|
|
||
|
|
### Route Setup
|
||
|
|
|
||
|
|
Swagger UI is available at `/swagger/index.html` and configured in `internal/api/router.go`:
|
||
|
|
|
||
|
|
```go
|
||
|
|
router.GET("/swagger/*any", ginSwagger.WrapHandler(swaggerFiles.Handler))
|
||
|
|
```
|
||
|
|
|
||
|
|
## Adding Swagger Annotations
|
||
|
|
|
||
|
|
### Basic Annotation Format
|
||
|
|
|
||
|
|
Every handler function should have Swagger annotations above it:
|
||
|
|
|
||
|
|
```go
|
||
|
|
// @Summary Short description
|
||
|
|
// @Description Detailed description
|
||
|
|
// @Tags TagName
|
||
|
|
// @Accept json
|
||
|
|
// @Produce json
|
||
|
|
// @Param param_name path/query/body type required "Description"
|
||
|
|
// @Success 200 {object} handlers.APIResponse{data=object{field=type}}
|
||
|
|
// @Failure 400 {object} handlers.APIResponse "Error description"
|
||
|
|
// @Failure 401 {object} handlers.APIResponse "Unauthorized"
|
||
|
|
// @Router /endpoint/path [method]
|
||
|
|
func (h *Handler) HandlerFunc() gin.HandlerFunc {
|
||
|
|
// Handler implementation
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
### Annotation Fields
|
||
|
|
|
||
|
|
- **@Summary**: Short one-line description (required)
|
||
|
|
- **@Description**: Detailed description (optional but recommended)
|
||
|
|
- **@Tags**: Category/group for the endpoint (e.g., "Auth", "Track", "User")
|
||
|
|
- **@Accept**: Content types accepted (json, multipart/form-data, etc.)
|
||
|
|
- **@Produce**: Content types produced (json)
|
||
|
|
- **@Param**: Request parameters
|
||
|
|
- Format: `@Param name location type required "description"`
|
||
|
|
- Location: `path`, `query`, `body`, `formData`, `header`
|
||
|
|
- Type: `string`, `int`, `bool`, `object`, etc.
|
||
|
|
- **@Success**: Success response
|
||
|
|
- Format: `@Success status {type} "description"`
|
||
|
|
- Type: `object`, `array`, `string`, etc.
|
||
|
|
- **@Failure**: Error responses
|
||
|
|
- **@Router**: Endpoint path and HTTP method
|
||
|
|
- **@Security**: Security requirements (e.g., `@Security BearerAuth`)
|
||
|
|
|
||
|
|
### Example: Complete Handler Annotation
|
||
|
|
|
||
|
|
```go
|
||
|
|
// SearchLogs recherche des logs d'audit
|
||
|
|
// @Summary Search audit logs
|
||
|
|
// @Description Search and filter audit logs with pagination support
|
||
|
|
// @Tags Audit
|
||
|
|
// @Accept json
|
||
|
|
// @Produce json
|
||
|
|
// @Security BearerAuth
|
||
|
|
// @Param action query string false "Filter by action"
|
||
|
|
// @Param resource query string false "Filter by resource type"
|
||
|
|
// @Param start_date query string false "Start date (YYYY-MM-DD)"
|
||
|
|
// @Param end_date query string false "End date (YYYY-MM-DD)"
|
||
|
|
// @Param page query int false "Page number" default(1)
|
||
|
|
// @Param limit query int false "Items per page" default(20)
|
||
|
|
// @Success 200 {object} handlers.APIResponse{data=object{logs=array,pagination=object}}
|
||
|
|
// @Failure 400 {object} handlers.APIResponse "Validation error"
|
||
|
|
// @Failure 401 {object} handlers.APIResponse "Unauthorized"
|
||
|
|
// @Failure 500 {object} handlers.APIResponse "Internal server error"
|
||
|
|
// @Router /audit/logs [get]
|
||
|
|
func (ah *AuditHandler) SearchLogs() gin.HandlerFunc {
|
||
|
|
// Implementation
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
## Generating Swagger Documentation
|
||
|
|
|
||
|
|
### Prerequisites
|
||
|
|
|
||
|
|
Install `swag` CLI tool:
|
||
|
|
|
||
|
|
```bash
|
||
|
|
go install github.com/swaggo/swag/cmd/swag@latest
|
||
|
|
```
|
||
|
|
|
||
|
|
### Generate Documentation
|
||
|
|
|
||
|
|
From the `veza-backend-api` directory:
|
||
|
|
|
||
|
|
```bash
|
||
|
|
swag init -g cmd/api/main.go
|
||
|
|
```
|
||
|
|
|
||
|
|
This will:
|
||
|
|
1. Scan all Go files for Swagger annotations
|
||
|
|
2. Generate `docs/docs.go`
|
||
|
|
3. Generate `docs/swagger.json`
|
||
|
|
4. Generate `docs/swagger.yaml`
|
||
|
|
|
||
|
|
### Verify Generation
|
||
|
|
|
||
|
|
1. Start the server
|
||
|
|
2. Visit `http://localhost:8080/swagger/index.html`
|
||
|
|
3. Verify all endpoints are documented
|
||
|
|
4. Test endpoint documentation accuracy
|
||
|
|
|
||
|
|
## Standard Response Formats
|
||
|
|
|
||
|
|
### Success Response
|
||
|
|
|
||
|
|
All success responses use the `APIResponse` envelope:
|
||
|
|
|
||
|
|
```go
|
||
|
|
// @Success 200 {object} handlers.APIResponse{data=object{field=type}}
|
||
|
|
```
|
||
|
|
|
||
|
|
### Error Response
|
||
|
|
|
||
|
|
All error responses use the `APIResponse` envelope with error object:
|
||
|
|
|
||
|
|
```go
|
||
|
|
// @Failure 400 {object} handlers.APIResponse "Validation error"
|
||
|
|
// @Failure 401 {object} handlers.APIResponse "Unauthorized"
|
||
|
|
// @Failure 404 {object} handlers.APIResponse "Not found"
|
||
|
|
// @Failure 500 {object} handlers.APIResponse "Internal server error"
|
||
|
|
```
|
||
|
|
|
||
|
|
### Paginated Response
|
||
|
|
|
||
|
|
For paginated endpoints:
|
||
|
|
|
||
|
|
```go
|
||
|
|
// @Success 200 {object} handlers.APIResponse{data=object{items=array,pagination=object}}
|
||
|
|
```
|
||
|
|
|
||
|
|
## Handlers Needing Annotations
|
||
|
|
|
||
|
|
The following handlers should have Swagger annotations added:
|
||
|
|
|
||
|
|
1. **Audit Handlers** (`internal/handlers/audit.go`):
|
||
|
|
- `SearchLogs` - ✅ Should add annotations
|
||
|
|
- `GetStats` - ✅ Should add annotations
|
||
|
|
- `GetSuspiciousActivity` - ✅ Should add annotations
|
||
|
|
|
||
|
|
2. **Webhook Handlers** (`internal/handlers/webhook_handlers.go`):
|
||
|
|
- `RegisterWebhook` - ✅ Should add annotations
|
||
|
|
- `ListWebhooks` - ✅ Should add annotations
|
||
|
|
- `DeleteWebhook` - ✅ Should add annotations
|
||
|
|
- `GetWebhookStats` - ✅ Should add annotations
|
||
|
|
- `TestWebhook` - ✅ Should add annotations
|
||
|
|
- `RegenerateAPIKey` - ✅ Should add annotations
|
||
|
|
|
||
|
|
3. **Comment Handlers** (`internal/handlers/comment_handler.go`):
|
||
|
|
- `GetComments` - ✅ Should add annotations
|
||
|
|
- `CreateComment` - ✅ Should add annotations
|
||
|
|
- `DeleteComment` - ✅ Should add annotations
|
||
|
|
|
||
|
|
4. **Other Handlers**:
|
||
|
|
- Check all handlers in `internal/handlers/` for missing annotations
|
||
|
|
- Add annotations when creating new handlers
|
||
|
|
|
||
|
|
## Maintenance Workflow
|
||
|
|
|
||
|
|
### When Adding a New Endpoint
|
||
|
|
|
||
|
|
1. **Add Swagger annotations** to the handler function
|
||
|
|
2. **Follow the standard format** (see examples above)
|
||
|
|
3. **Include all parameters** (path, query, body)
|
||
|
|
4. **Document all responses** (success and error cases)
|
||
|
|
5. **Regenerate documentation**: `swag init -g cmd/api/main.go`
|
||
|
|
6. **Verify in Swagger UI**: Check `/swagger/index.html`
|
||
|
|
7. **Commit changes**: Include both handler and generated docs
|
||
|
|
|
||
|
|
### When Modifying an Endpoint
|
||
|
|
|
||
|
|
1. **Update Swagger annotations** if parameters or responses change
|
||
|
|
2. **Regenerate documentation**: `swag init -g cmd/api/main.go`
|
||
|
|
3. **Verify changes** in Swagger UI
|
||
|
|
4. **Update related documentation** if needed
|
||
|
|
|
||
|
|
### Regular Maintenance
|
||
|
|
|
||
|
|
1. **Review Swagger UI** periodically to ensure all endpoints are documented
|
||
|
|
2. **Check for outdated annotations** when refactoring handlers
|
||
|
|
3. **Keep annotations in sync** with actual implementation
|
||
|
|
4. **Update version** in `main.go` when making breaking changes
|
||
|
|
|
||
|
|
## CI/CD Integration
|
||
|
|
|
||
|
|
### Pre-commit Hook (Recommended)
|
||
|
|
|
||
|
|
Add a pre-commit hook to ensure documentation is up to date:
|
||
|
|
|
||
|
|
```bash
|
||
|
|
#!/bin/bash
|
||
|
|
# .git/hooks/pre-commit
|
||
|
|
|
||
|
|
cd veza-backend-api
|
||
|
|
swag init -g cmd/api/main.go
|
||
|
|
git add docs/
|
||
|
|
```
|
||
|
|
|
||
|
|
### CI Check (Recommended)
|
||
|
|
|
||
|
|
Add a CI step to verify documentation:
|
||
|
|
|
||
|
|
```yaml
|
||
|
|
- name: Generate Swagger docs
|
||
|
|
run: |
|
||
|
|
cd veza-backend-api
|
||
|
|
go install github.com/swaggo/swag/cmd/swag@latest
|
||
|
|
swag init -g cmd/api/main.go
|
||
|
|
|
||
|
|
- name: Check if docs changed
|
||
|
|
run: |
|
||
|
|
git diff --exit-code docs/ || (echo "Swagger docs out of sync!" && exit 1)
|
||
|
|
```
|
||
|
|
|
||
|
|
## Best Practices
|
||
|
|
|
||
|
|
1. **Always add annotations** when creating new handlers
|
||
|
|
2. **Keep annotations accurate** - they should match the actual implementation
|
||
|
|
3. **Use descriptive summaries** - clear, concise descriptions
|
||
|
|
4. **Document all parameters** - path, query, body parameters
|
||
|
|
5. **Document all responses** - success and error cases
|
||
|
|
6. **Use consistent tags** - group related endpoints
|
||
|
|
7. **Include examples** in descriptions when helpful
|
||
|
|
8. **Regenerate after changes** - always regenerate docs after modifying annotations
|
||
|
|
|
||
|
|
## Troubleshooting
|
||
|
|
|
||
|
|
### Swagger UI Not Loading
|
||
|
|
|
||
|
|
1. Check that `docs/docs.go` exists and is valid
|
||
|
|
2. Verify route is registered: `router.GET("/swagger/*any", ...)`
|
||
|
|
3. Check imports in `main.go`: `_ "veza-backend-api/docs"`
|
||
|
|
4. Restart the server
|
||
|
|
|
||
|
|
### Missing Endpoints in Swagger
|
||
|
|
|
||
|
|
1. Verify annotations are present on handler functions
|
||
|
|
2. Check annotation syntax (no typos)
|
||
|
|
3. Regenerate: `swag init -g cmd/api/main.go`
|
||
|
|
4. Check that handler is registered in router
|
||
|
|
|
||
|
|
### Incorrect Documentation
|
||
|
|
|
||
|
|
1. Verify annotations match actual implementation
|
||
|
|
2. Check parameter types and names
|
||
|
|
3. Verify response structures
|
||
|
|
4. Regenerate documentation
|
||
|
|
|
||
|
|
## Files Modified
|
||
|
|
|
||
|
|
- Created: `OPENAPI_MAINTENANCE_GUIDE.md` (this document)
|
||
|
|
- Updated: Added Swagger annotations to key handlers
|
||
|
|
|
||
|
|
## Next Steps
|
||
|
|
|
||
|
|
1. ✅ Document Swagger maintenance process
|
||
|
|
2. ⏳ Add annotations to remaining handlers
|
||
|
|
3. ⏳ Set up CI/CD checks for documentation
|
||
|
|
4. ⏳ Create pre-commit hook for auto-generation
|
||
|
|
5. ⏳ Regular review of Swagger UI for completeness
|
||
|
|
|