Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Introduction

Locky is a robust Role-Based Access Control (RBAC) service built with Go, designed to provide comprehensive user, group, member, and role management with fine-grained permissions.

Overview

Locky implements a multi-layered architecture that combines:

  • JWT-based authentication for secure user identification
  • Casbin RBAC for flexible authorization policies
  • Redis caching for performance optimization
  • MySQL/TiDB for persistent data storage

Key Features

  • User Management: Complete CRUD operations for user accounts
  • Group Management: Organize users into logical groups
  • Member Management: Control group membership and relationships
  • Role Management: Define and assign fine-grained permissions
  • Multi-tier API: Public, Internal, and Private endpoints with different access levels
  • Casbin Integration: Policy-based authorization with dual enforcer setup
    • App-wide permissions (locky policies)
    • Resource-specific permissions (resource policies)

Architecture Highlights

Locky follows a clean architecture pattern with clear separation of concerns:

  1. Client Layer: CLI tools for different user roles (Admin, App, Anonymous)
  2. API Layer: Gin-based HTTP router with middleware stack
  3. Controller Layer: Request handlers organized by access level
  4. Business Logic Layer: Use case implementations
  5. Repository Layer: Data access abstraction
  6. Data Layer: MySQL/TiDB, Redis, and Casbin policy storage

Use Cases

  • Multi-tenant applications requiring organization-level access control
  • Enterprise systems with complex permission requirements
  • Microservices needing centralized authentication and authorization
  • APIs requiring different access levels (public, internal, private)

Getting Started

See the Getting Started guide for installation and setup instructions.

Documentation Structure

This documentation is organized into the following sections:

  • Architecture: Deep dive into system design and components
  • API Reference: Complete API documentation with examples
  • Configuration: Setup and configuration guides
  • Development: Contributing and development workflows
  • Appendix: Additional resources (Swagger, GoDoc)

High-Level Architecture

This page provides an overview of Locky's high-level architecture and how its components interact.

Architecture Diagram

High-Level Architecture

System Layers

Locky is built on a multi-layered architecture that promotes separation of concerns and maintainability:

1. Client Layer

The client layer provides multiple CLI tools for different use cases:

  • Admin CLI (locky-client-admin): Administrative operations with elevated privileges
  • App CLI (locky-client-app): Application-level operations for authenticated users
  • Anonymous CLI (locky-client-anonymous): Public operations that don't require authentication

2. API Layer

The API layer handles HTTP requests and applies cross-cutting concerns:

  • Gin Router: High-performance HTTP router and middleware framework
  • Middleware Stack:
    • JWT Authentication: Validates and decodes JWT tokens
    • Casbin Authorization: Enforces RBAC policies
    • Request Logger: Logs all incoming requests for auditing

3. Controller Layer

Controllers are organized by access level to enforce security boundaries:

  • Public Controllers: Endpoints accessible without authentication (e.g., user registration, login)
  • Internal Controllers: Endpoints for authenticated internal services
  • Private Controllers: Endpoints requiring specific permissions

Each controller handles:

  • User Controller: User account operations
  • Group Controller: Group management
  • Member Controller: Group membership operations
  • Role Controller: Permission management

4. Business Logic Layer

Use cases implement business rules and orchestrate repository operations:

  • User Usecase: User business logic
  • Group Usecase: Group business logic
  • Member Usecase: Membership business logic
  • Role Usecase: Permission business logic

5. Repository Layer

Repositories abstract data access and provide a clean interface to the data layer:

  • User Repository: User data operations
  • Group Repository: Group data operations
  • Member Repository: Membership data operations
  • Role Repository: Role and permission operations (Casbin-backed)
  • Common Repository: Shared operations (JWT token management)
  • Redis Repository: Cache operations

6. Data Layer

The data layer consists of multiple storage systems:

  • MySQL/TiDB: Primary relational database for users, groups, and members
  • Redis: Caching layer for JWT token denylist and session management
  • Casbin Policies: Authorization policy storage
    • Locky Policy: Application-wide permissions
    • Resource Policy: Resource-specific permissions

Data Flow

Authentication Flow

  1. User sends credentials to Public Controller (Login endpoint)
  2. Controller validates credentials via User Repository
  3. JWT token is generated and returned to client
  4. Subsequent requests include JWT token in Authorization header
  5. Middleware validates token and extracts user information
  6. Casbin enforcer checks user permissions
  7. Request proceeds to appropriate controller if authorized

Authorization Flow

Locky uses a dual-enforcer approach for fine-grained access control:

  1. App Enforcer (etc/casbin/locky/): Controls access to API endpoints
  2. Resource Enforcer (etc/casbin/resources/): Controls access to specific resources

CRUD Operation Flow

  1. Client sends request through CLI
  2. Gin router routes to appropriate controller
  3. Middleware validates authentication and authorization
  4. Controller parses and validates request
  5. Use case applies business logic
  6. Repository performs database operations
  7. Response flows back through the layers

Configuration

The system is configured through:

  • app.yaml: Main configuration file (database, Redis, JWT settings)
  • Casbin Model Files: Define RBAC model structure
  • Casbin Policy Files: Define actual permissions

Scalability Considerations

  • Stateless API: JWT tokens enable horizontal scaling
  • Redis Caching: Reduces database load
  • Connection Pooling: Efficient database connection management
  • Casbin Policy Caching: In-memory policy evaluation for fast authorization

Security Features

  • JWT with HS256: Secure token-based authentication
  • Token Denylist: Revoked tokens stored in Redis
  • Casbin RBAC: Policy-based authorization
  • Multi-tier Access: Public, Internal, and Private endpoint separation
  • Admin Email Check: Additional verification for administrative operations

Next Steps

Components Overview

This section provides detailed information about each layer of the Locky architecture.

Layer Summary

LayerPurposeKey Components
Client LayerUser interfaces and CLI toolsAdmin CLI, App CLI, Anonymous CLI
API LayerHTTP routing and middlewareGin Router, JWT Auth, Casbin RBAC, Logger
Controller LayerRequest handling and validationPublic, Internal, Private Controllers
Business Logic LayerUse cases and business rulesUser, Group, Member, Role Usecases
Repository LayerData access abstractionUser, Group, Member, Role Repositories
Data LayerPersistent storageMySQL/TiDB, Redis, Casbin Policies

Component Interaction

Each layer communicates with adjacent layers through well-defined interfaces:

Client → API → Controller → Business Logic → Repository → Data

Dependency Flow

  • Downward Dependencies: Each layer depends only on the layer directly below it
  • Interface-Based: Layers communicate through interfaces, not concrete implementations
  • Testability: Each layer can be tested independently with mocks

Common Patterns

Repository Pattern

All data access goes through repositories, providing:

  • Abstraction from underlying storage
  • Consistent error handling
  • Transaction management
  • Query optimization

Use Case Pattern

Business logic is encapsulated in use cases:

  • Single responsibility per use case
  • Orchestration of multiple repositories
  • Business rule validation
  • Domain logic isolation

Middleware Pattern

Cross-cutting concerns are handled by middleware:

  • Authentication
  • Authorization
  • Logging
  • Error handling

Next Steps

Explore each layer in detail:

Client Layer

This page is under construction.

Api Layer

This page is under construction.

Controller Layer

This page is under construction.

Business Layer

This page is under construction.

Repository Layer

This page is under construction.

Data Layer

This page is under construction.

API Overview

Locky provides a RESTful API built with the Gin framework. The API is organized into three access levels to enforce security boundaries.

Base URL

http://localhost:8080/v1

Access Levels

Public Endpoints (/v1/public)

Public endpoints are accessible without authentication:

  • User Registration: Create new user accounts
  • User Login: Authenticate and receive JWT token
  • Health Check: Service status

Internal Endpoints (/v1/internal)

Internal endpoints require JWT authentication and are intended for internal services:

  • User Management: List, count, get user details
  • Group Management: CRUD operations for groups
  • Member Management: Manage group memberships
  • Role Management: Query roles and permissions

Private Endpoints (/v1/private)

Private endpoints require both JWT authentication and specific Casbin permissions:

  • User Administration: Update, delete users
  • Group Administration: Full group management
  • Member Administration: Full membership control
  • Role Administration: Create, update, delete roles

Authentication

JWT Token

All authenticated endpoints require a JWT token in the Authorization header:

Authorization: Bearer <jwt_token>

Token Lifecycle

  1. Obtain Token: POST to /v1/public/users/login with credentials
  2. Use Token: Include in Authorization header for subsequent requests
  3. Token Expiry: Tokens expire after configured duration (default: 24 hours)
  4. Token Revocation: Logout endpoint adds token to Redis denylist

Authorization

Authorization is handled by Casbin with two policy sets:

App Policies (etc/casbin/locky/)

Controls access to API endpoints based on user roles.

Example policy:

p, admin, /v1/private/*, *
p, user, /v1/internal/users, GET

Resource Policies (etc/casbin/resources/)

Controls access to specific resources (groups, members).

Example policy:

p, user:123, group:456, read
p, user:123, group:456, write

Request/Response Format

Request Format

{
  "name": "example",
  "email": "user@example.com"
}

Response Format

{
  "data": {
    "id": 1,
    "uuid": "f3b3b3b3-3b3b-3b3b-3b3b-3b3b3b3b3b3b",
    "name": "example"
  },
  "message": "Success"
}

Error Format

{
  "error": "Invalid credentials",
  "code": 401
}

Rate Limiting

Currently, rate limiting is not implemented but can be added via middleware.

API Versioning

The API is versioned in the URL path (/v1/). Future versions will be released as /v2/, etc.

Next Steps

Authentication

This page is under construction.

Endpoints

This page is under construction.

Users

This page is under construction.

Groups

This page is under construction.

Members

This page is under construction.

Roles

This page is under construction.

Configuration Guide

Locky uses YAML-based configuration files for all runtime settings. This guide explains how to configure Locky for different environments.

Configuration Files

FilePurposeStatus
etc/app.yamlRuntime configurationNot in Git (local only)
etc/app.yaml.exampleProduction templateIn Git (template)
etc/app.dev.yamlDevelopment defaultsIn Git (for development)

Quick Start

Development Setup

# Copy development configuration
cp etc/app.dev.yaml etc/app.yaml

# Or start with Docker Compose (auto-configured)
docker-compose up -d

Production Setup

# Create configuration from template
cp etc/app.yaml.example etc/app.yaml

# Edit with your actual credentials
vi etc/app.yaml

Configuration Sections

Server Configuration

Server:
  host: "0.0.0.0"
  port: 8080
  jwt_secret: "your-secure-secret-256-bits"
  jwt:
    key: "your-jwt-key"

Important:

  • jwt_secret: Must be at least 256 bits (32 characters)
  • jwt.key: Used for signing JWT tokens
  • Generate secure random values for production

Database Configuration

MySQL:
  host: "mysql-host"
  user: "mysql-user"
  pass: "mysql-password"
  port: 3306
  db: "database-name"
  max_idle_conns: 10
  max_open_conns: 100
  conn_max_lifetime: 3600

Connection Pool Settings:

  • max_idle_conns: Maximum idle connections (default: 10)
  • max_open_conns: Maximum open connections (default: 100)
  • conn_max_lifetime: Connection lifetime in seconds (default: 3600)

Redis Configuration

Redis:
  host: "redis-host"
  port: 6379
  pass: "redis-password"
  db: 0

Note: The db field accepts either integer or string format.

Casbin Configuration

Casbin:
  app_model: "etc/casbin/locky/model.conf"
  app_policy: "etc/casbin/locky/policy.csv"
  resource_model: "etc/casbin/resources/model.conf"
  resource_policy: "etc/casbin/resources/policy.csv"

Dual Enforcer Setup:

  • App Enforcer: Controls API endpoint access
  • Resource Enforcer: Controls resource-level permissions

Environment-Specific Configuration

Development

Development configuration (app.dev.yaml) includes:

  • Localhost database connections
  • Default credentials for Docker Compose
  • Debug-friendly settings

Production

Production configuration must include:

  • Secure JWT secrets (256+ bits)
  • Production database credentials
  • Redis credentials
  • Appropriate connection pool sizes
  • Production-grade Casbin policies

Security Best Practices

  1. Never commit etc/app.yaml - It's in .gitignore for a reason
  2. Use environment variables for sensitive data (optional approach)
  3. Rotate JWT secrets regularly
  4. Use strong passwords for MySQL and Redis
  5. Limit connection pool sizes based on your infrastructure
  6. Review Casbin policies before deployment

Environment Variables (Alternative)

While Locky primarily uses YAML configuration, you can also use environment variables:

export LOCKY_JWT_SECRET="your-secret"
export LOCKY_MYSQL_PASSWORD="your-db-password"
export LOCKY_REDIS_PASSWORD="your-redis-password"

Validation

Validate your configuration before starting:

# Test database connection
go run cmd/server/main.go --config etc/app.yaml --validate

# Check Casbin policies
casbin-cli check etc/casbin/locky/model.conf etc/casbin/locky/policy.csv

Troubleshooting

Connection Errors

Error: dial tcp: lookup mysql-host: no such host

Solution: Verify hostname and network connectivity

JWT Errors

Error: jwt_secret must be at least 256 bits

Solution: Generate a longer secret:

openssl rand -base64 32

Casbin Errors

Error: failed to load casbin policy

Solution: Check file paths and CSV format in policy files

Next Steps

Environment

This page is under construction.

Casbin

This page is under construction.

Getting Started

This guide will help you get Locky up and running on your local machine.

Prerequisites

  • Go 1.22+: Download
  • MySQL 8.0+ or TiDB: Database server
  • Redis 6.0+: Cache server
  • Docker & Docker Compose (optional): For quick setup

Quick Start with Docker Compose

The fastest way to get started:

# Clone the repository
git clone https://github.com/ryo-arima/locky.git
cd locky

# Start MySQL and Redis
docker-compose up -d

# Copy development configuration
cp etc/app.dev.yaml etc/app.yaml

# Run database migrations (if any)
# TODO: Add migration commands

# Build the server
go build -o .bin/locky-server ./cmd/server/main.go

# Start the server
./.bin/locky-server

The server will start on http://localhost:8080.

Manual Setup

1. Install Dependencies

# Install Go dependencies
go mod download
go mod vendor

2. Setup Database

# Create MySQL database
mysql -u root -p
> CREATE DATABASE locky;
> CREATE USER 'locky'@'localhost' IDENTIFIED BY 'password';
> GRANT ALL PRIVILEGES ON locky.* TO 'locky'@'localhost';
> FLUSH PRIVILEGES;

3. Setup Redis

# Start Redis (macOS with Homebrew)
brew services start redis

# Or with Docker
docker run -d -p 6379:6379 redis:alpine

4. Configure Application

# Copy configuration template
cp etc/app.yaml.example etc/app.yaml

# Edit configuration
vi etc/app.yaml

Update the following sections:

  • MySQL connection details
  • Redis connection details
  • JWT secrets

5. Build the Application

# Build all binaries
make build

# Or build individually
go build -o .bin/locky-server ./cmd/server/main.go
go build -o .bin/locky-client-admin ./cmd/client/admin/main.go
go build -o .bin/locky-client-app ./cmd/client/app/main.go
go build -o .bin/locky-client-anonymous ./cmd/client/anonymous/main.go

6. Run the Server

./.bin/locky-server

Verify Installation

Check Server Status

# Health check
curl http://localhost:8080/v1/public/health

# Expected response:
# {"status": "ok"}

Register a User

curl -X POST http://localhost:8080/v1/public/users/register \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Test User",
    "email": "test@example.com",
    "password": "securepassword"
  }'

Login

curl -X POST http://localhost:8080/v1/public/users/login \
  -H "Content-Type: application/json" \
  -d '{
    "email": "test@example.com",
    "password": "securepassword"
  }'

# Save the JWT token from response
export TOKEN="<jwt_token_here>"

Access Protected Endpoint

curl http://localhost:8080/v1/internal/users \
  -H "Authorization: Bearer $TOKEN"

Using the CLI Clients

Admin Client

./.bin/locky-client-admin --help

App Client

./.bin/locky-client-app --help

Anonymous Client

./.bin/locky-client-anonymous --help

Makefile Commands

Locky includes a Makefile for common tasks:

# Build all binaries
make build

# Run tests
make test

# Clean build artifacts
make clean

# Generate documentation
make docs

# Start development environment
make dev-up

# Stop development environment
make dev-down

Development Workflow

  1. Make Changes: Edit source code
  2. Build: make build
  3. Test: make test
  4. Run: ./.bin/locky-server
  5. Verify: Test with curl or CLI clients

Troubleshooting

Port Already in Use

# Find process using port 8080
lsof -i :8080

# Kill the process
kill -9 <PID>

Database Connection Failed

  • Verify MySQL is running: mysql -u root -p
  • Check credentials in etc/app.yaml
  • Ensure database exists: SHOW DATABASES;

Redis Connection Failed

  • Verify Redis is running: redis-cli ping
  • Check Redis host/port in configuration
  • Test connection: redis-cli -h localhost -p 6379

Casbin Policy Errors

  • Verify policy files exist in etc/casbin/
  • Check CSV format (no trailing commas)
  • Validate model syntax

Next Steps

Building

This page is under construction.

Testing

This page is under construction.

Contributing

This page is under construction.

Swagger Documentation

Locky provides comprehensive API documentation via Swagger/OpenAPI specification.

Accessing Swagger UI

View the interactive Swagger UI online:

📖 Open Swagger UI (Opens in new window)

Or use the relative link when browsing documentation: 📖 Open Swagger UI

Local Development

When running Locky locally, Swagger UI is available at:

http://localhost:8080/swagger/index.html

Swagger Files

The Swagger specification is maintained in:

  • Source: docs/swagger/swagger.yaml
  • Online: swagger.yaml
  • Generated: Auto-generated from code annotations

Swagger Specification Overview

The Swagger specification includes:

API Information

  • Title: Locky API
  • Version: 1.0.0
  • Base Path: /v1
  • Schemes: HTTP, HTTPS
  • Consumes: application/json
  • Produces: application/json

Endpoints Documented

Public Endpoints

  • POST /v1/public/users/register - User registration
  • POST /v1/public/users/login - User authentication
  • GET /v1/public/health - Health check

Internal Endpoints

  • GET /v1/internal/users - List users
  • GET /v1/internal/users/count - Count users
  • GET /v1/internal/users/{id} - Get user details
  • GET /v1/internal/groups - List groups
  • GET /v1/internal/groups/count - Count groups
  • GET /v1/internal/members - List members
  • GET /v1/internal/roles - List roles

Private Endpoints

  • PUT /v1/private/users/{id} - Update user
  • DELETE /v1/private/users/{id} - Delete user
  • POST /v1/private/groups - Create group
  • PUT /v1/private/groups/{id} - Update group
  • DELETE /v1/private/groups/{id} - Delete group
  • POST /v1/private/members - Add member
  • DELETE /v1/private/members/{id} - Remove member
  • POST /v1/private/roles - Create role
  • PUT /v1/private/roles/{id} - Update role
  • DELETE /v1/private/roles/{id} - Delete role

Data Models

The specification includes complete schemas for:

Request Models

  • UserRequest - User registration/update
  • GroupRequest - Group creation/update
  • MemberRequest - Member addition
  • RoleRequest - Role creation/update

Response Models

  • User - User object
  • Group - Group object
  • Member - Member object
  • Role - Role object
  • Count - Count response

Common Properties

All models include:

  • id - Unique identifier (uint64)
  • uuid - UUID string
  • created_at - Creation timestamp
  • updated_at - Last update timestamp
  • deleted_at - Soft delete timestamp (nullable)

Using Swagger UI

Try Out API Endpoints

  1. Open Swagger UI in browser
  2. Click on an endpoint to expand
  3. Click "Try it out"
  4. Fill in parameters
  5. Click "Execute"
  6. View response

Authentication

For protected endpoints:

  1. Get JWT token via /v1/public/users/login
  2. Click "Authorize" button in Swagger UI
  3. Enter token in format: Bearer <token>
  4. Click "Authorize"
  5. Try protected endpoints

Generating Swagger Documentation

From Code Annotations

Locky uses swaggo/swag for generating Swagger docs from code comments:

# Install swag CLI
go install github.com/swaggo/swag/cmd/swag@latest

# Generate documentation
swag init -g cmd/server/main.go -o docs/swagger

# Documentation will be generated in docs/swagger/

Swagger Annotations Example

// @Summary Register a new user
// @Description Create a new user account
// @Tags users
// @Accept json
// @Produce json
// @Param request body entity.UserRequest true "User registration request"
// @Success 201 {object} entity.User
// @Failure 400 {object} map[string]string
// @Router /v1/public/users/register [post]
func (c *userController) Register(ctx *gin.Context) {
    // Implementation
}

Swagger vs OpenAPI

  • OpenAPI 3.0: Modern specification format
  • Swagger 2.0: Legacy format (currently used by Locky)
  • Migration: Consider upgrading to OpenAPI 3.0

Interactive Documentation

Swagger Editor

Edit the specification online:

  1. Visit Swagger Editor
  2. Paste contents of docs/swagger/swagger.yaml
  3. View formatted documentation
  4. Validate specification

Postman Integration

Import Swagger spec into Postman:

  1. Open Postman
  2. Click "Import"
  3. Select docs/swagger/swagger.yaml
  4. Use generated collection for testing

API Testing with Swagger

Swagger UI provides built-in testing:

  1. Authentication: Test login flow
  2. CRUD Operations: Test all endpoints
  3. Validation: Verify request/response schemas
  4. Error Handling: Test error scenarios

Best Practices

Maintaining Documentation

  • Update Swagger annotations when changing APIs
  • Regenerate docs after code changes
  • Validate specification regularly
  • Keep examples up-to-date

Documentation Quality

  • Clear descriptions for all endpoints
  • Comprehensive parameter documentation
  • Example request/response bodies
  • Document all error codes

Swagger Tools

CLI Tools

# Validate Swagger spec
swagger validate docs/swagger/swagger.yaml

# Generate client SDKs
swagger generate client -f docs/swagger/swagger.yaml

# Generate server code
swagger generate server -f docs/swagger/swagger.yaml

Online Validators

Next Steps

GoDoc

Locky's Go package documentation is generated using standard Go documentation tools.

Viewing GoDoc

GitHub Pages

📖 GoDoc Overview (Links to pkg.go.dev)

Or use the relative link when browsing documentation: 📖 GoDoc Overview

Online - pkg.go.dev (When Published)

Once the package is published, view the official Go documentation online:

📖 View on pkg.go.dev

Local Documentation

Generate and view documentation locally:

# Install godoc tool (if not already installed)
go install golang.org/x/tools/cmd/godoc@latest

# Start local documentation server
godoc -http=:6060

# Open in browser
open http://localhost:6060/pkg/github.com/ryo-arima/locky/

Generated HTML

Pre-generated HTML documentation is available in:

docs/godoc/

Package Structure

Main Packages

PackageDescription
pkg/serverHTTP server implementation
pkg/clientCLI client implementations
pkg/configConfiguration management
pkg/entityData models and DTOs

Server Packages

PackageDescription
pkg/server/controllerRequest handlers
pkg/server/middlewareMiddleware components
pkg/server/repositoryData access layer

Entity Packages

PackageDescription
pkg/entity/modelDatabase models
pkg/entity/requestRequest DTOs
pkg/entity/responseResponse DTOs

Client Packages

PackageDescription
pkg/client/controllerCLI command handlers
pkg/client/repositoryAPI client layer
pkg/client/usecaseClient business logic

Key Types and Functions

Configuration

// BaseConfig holds application configuration
type BaseConfig struct {
    YamlConfig YamlConfig
    DB         *gorm.DB
}

// LoadConfig loads configuration from YAML file
func LoadConfig(path string) (*BaseConfig, error)

Server

// InitRouter initializes the Gin router with all routes and middleware
func InitRouter(conf config.BaseConfig) *gin.Engine

// Start starts the HTTP server
func Start(router *gin.Engine, port int) error

Repository

// UserRepository provides user data access
type UserRepository interface {
    ListUsers(filters map[string]interface{}) ([]model.User, error)
    GetUser(id uint) (*model.User, error)
    CreateUser(user *model.User) error
    UpdateUser(user *model.User) error
    DeleteUser(id uint) error
}

Entity Models

// User represents a user account
type User struct {
    ID        uint      `gorm:"primaryKey"`
    UUID      string    `gorm:"uniqueIndex"`
    Name      string
    Email     string    `gorm:"uniqueIndex"`
    Password  string
    CreatedAt time.Time
    UpdatedAt time.Time
    DeletedAt *time.Time `gorm:"index"`
}

Documentation Standards

Package Comments

Every package should have a package-level comment:

// Package server implements the HTTP server and routing logic.
//
// The server package provides:
//   - Gin-based HTTP routing
//   - Middleware integration (JWT, Casbin, logging)
//   - Controller initialization
//   - Repository wiring
//
// Example usage:
//
//   config := config.LoadConfig("etc/app.yaml")
//   router := server.InitRouter(config)
//   server.Start(router, 8080)
package server

Function Comments

All exported functions must have documentation:

// ListUsers retrieves a list of users based on the provided filters.
//
// Filters can include:
//   - name: Filter by name (partial match)
//   - email: Filter by email (exact match)
//   - limit: Maximum number of results
//   - offset: Number of results to skip
//
// Returns a slice of User models and an error if the operation fails.
func (r *userRepository) ListUsers(filters map[string]interface{}) ([]model.User, error)

Type Comments

All exported types must be documented:

// User represents a user account in the system.
//
// Users can belong to multiple groups and have various roles
// that determine their permissions within the application.
type User struct {
    ID        uint      `gorm:"primaryKey" json:"id"`
    UUID      string    `gorm:"uniqueIndex" json:"uuid"`
    Name      string    `json:"name"`
    Email     string    `gorm:"uniqueIndex" json:"email"`
    Password  string    `json:"-"` // Never serialize password
    CreatedAt time.Time `json:"created_at"`
    UpdatedAt time.Time `json:"updated_at"`
    DeletedAt *time.Time `gorm:"index" json:"deleted_at,omitempty"`
}

Generating Documentation

Standard godoc

# Generate HTML documentation
godoc -html github.com/ryo-arima/locky > docs/godoc/index.html

# Generate documentation for specific package
godoc -html github.com/ryo-arima/locky/pkg/server > docs/godoc/server.html

pkgsite (Modern godoc)

# Install pkgsite
go install golang.org/x/pkgsite/cmd/pkgsite@latest

# Run local server
pkgsite -http=:6060

# View documentation
open http://localhost:6060/github.com/ryo-arima/locky

Documentation Best Practices

Writing Good Documentation

  1. Start with a summary: One-line description of what it does
  2. Explain the why: Not just what, but why it exists
  3. Provide examples: Show common usage patterns
  4. Document parameters: Explain each parameter's purpose
  5. Document return values: Explain what's returned and when
  6. Document errors: List possible error conditions
  7. Link related items: Reference related types/functions

Example Structure

// FunctionName does something specific.
//
// More detailed explanation of what the function does,
// why it exists, and how it should be used.
//
// Parameters:
//   - param1: Description of first parameter
//   - param2: Description of second parameter
//
// Returns:
//   - result: Description of return value
//   - error: Possible error conditions
//
// Example:
//
//   result, err := FunctionName(arg1, arg2)
//   if err != nil {
//       log.Fatal(err)
//   }
//   fmt.Println(result)
func FunctionName(param1 string, param2 int) (result string, err error)

Package Dependencies

View package dependencies:

# Generate dependency graph
go mod graph

# Visualize with graphviz
go mod graph | dot -Tsvg -o docs/dependencies.svg

Code Examples in Documentation

GoDoc supports executable examples:

// Example_listUsers demonstrates how to list users
func Example_listUsers() {
    config := config.LoadConfig("etc/app.yaml")
    repo := repository.NewUserRepository(config)
    
    users, err := repo.ListUsers(map[string]interface{}{
        "limit": 10,
    })
    if err != nil {
        log.Fatal(err)
    }
    
    for _, user := range users {
        fmt.Println(user.Name)
    }
}

Testing Documentation

Verify documentation builds correctly:

# Check for documentation issues
go vet ./...

# Run documentation tests
go test -v ./...

Next Steps