{"id":35180583,"url":"https://github.com/nicolasbonnici/gorest","last_synced_at":"2026-06-14T00:06:32.076Z","repository":{"id":317770733,"uuid":"1068739361","full_name":"nicolasbonnici/gorest","owner":"nicolasbonnici","description":"GoREST is a library that helps you easily create production-grade REST APIs","archived":false,"fork":false,"pushed_at":"2026-06-09T20:38:58.000Z","size":108440,"stargazers_count":9,"open_issues_count":2,"forks_count":1,"subscribers_count":0,"default_branch":"trunk","last_synced_at":"2026-06-09T22:22:17.556Z","etag":null,"topics":["go","rest-api","sql"],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/nicolasbonnici.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2025-10-02T20:48:19.000Z","updated_at":"2026-06-09T20:38:21.000Z","dependencies_parsed_at":"2026-05-15T21:04:55.282Z","dependency_job_id":null,"html_url":"https://github.com/nicolasbonnici/gorest","commit_stats":null,"previous_names":["nicolasbonnici/gorest"],"tags_count":55,"template":false,"template_full_name":null,"purl":"pkg:github/nicolasbonnici/gorest","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nicolasbonnici%2Fgorest","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nicolasbonnici%2Fgorest/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nicolasbonnici%2Fgorest/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nicolasbonnici%2Fgorest/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/nicolasbonnici","download_url":"https://codeload.github.com/nicolasbonnici/gorest/tar.gz/refs/heads/trunk","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nicolasbonnici%2Fgorest/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":34304656,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-06-13T02:00:06.617Z","response_time":62,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["go","rest-api","sql"],"created_at":"2025-12-29T01:17:32.720Z","updated_at":"2026-06-14T00:06:32.060Z","avatar_url":"https://github.com/nicolasbonnici.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"# GoREST\n\n[![Test](https://github.com/nicolasbonnici/gorest/actions/workflows/test.yml/badge.svg?branch=trunk)](https://github.com/nicolasbonnici/gorest/actions/workflows/test.yml)\n[![Go Report Card](https://goreportcard.com/badge/github.com/nicolasbonnici/gorest)](https://goreportcard.com/report/github.com/nicolasbonnici/gorest)\n[![License](https://img.shields.io/badge/license-MIT-blue.svg)](LICENSE)\n\n🚀 **GoREST** is a Go library for building type-safe REST APIs in Go from your existing database schema or from scratch.\n\n\u003e [!WARNING]\n\u003e **Pre-1.0 Development**: The API is not yet stabilized and may introduce breaking changes until v1.0.0 is released. Pin to a specific version tag and test thoroughly before production use.\n\n## ✨ Features\n\n- ⚡ Type-safe generic CRUD operations with hooks system\n- 🚀 **Unified processor module** eliminating handler boilerplate - handlers become one-liners with automatic RBAC, validation, pagination, filtering \u0026 serialization\n- 🔧 Fluent SQL query builder with database abstraction\n- 🔑 **Built-in JWT authentication** with user management, registration, login, and token refresh\n- 🔐 RBAC Role based access control layer with field-level permissions and voter system\n- 🧐 Audit log\n- ✅ Security best practices, rate limiting, CORS, response compression and many more configurable core middleware\n- 🎭 Hook layer to add your business logic and override any API layer\n- 🧩 Modular plugin system that can add features, override some or all existing endpoints or even CLI commands\n- 🛠 **Code generation plugin** for REST endpoints, DTOs and models ([gorest-codegen](https://github.com/nicolasbonnici/gorest-codegen))\n- 🌐 JSON-LD support with semantic web context (@context, @type, @id)\n- 🔗 Advanced resource deserialization with IRI and optional on demand relations\n- 🔍 Advanced serialization, filtering \u0026 ordering\n- 📄 Page based pagination with Hydra collections\n- 👨🏻‍💻 DAL, migrations and fixtures with PostgreSQL, MySQL and SQLite engines support\n- 🛡️ Production grade errors and processes management\n- 🏷️ API versioning\n- 📜 OpenAPI 3 spec generation ([gorest-openapi](https://github.com/nicolasbonnici/gorest-openapi))\n- 💚 Status endpoint for health check ([gorest-status](https://github.com/nicolasbonnici/gorest-status))\n- 🐳 Docker and Kubernetes support\n- 🧪 Full test coverage with automated testing\n\n---\n\n## 🚀 Quick Start\n\n### 1. Create Your Project\n```bash\nmkdir my-api \u0026\u0026 cd my-api\ngo mod init github.com/yourusername/my-api\ngo get github.com/nicolasbonnici/gorest@latest\n```\n\n### 2. Install Development Environment\n\nFirst you need Go 1.25+ installed, then run:\n\n```bash\nmake install\n```\n\nThat's it! Your development environment is now set up.\n\n### 3. Configure Your API\n\nCreate `gorest.yaml` in your project root:\n\n```yaml\nserver:\n  scheme: \"${SERVER_SCHEME:-http}\"\n  host: \"${SERVER_HOST:-localhost}\"\n  port: \"${SERVER_PORT:-8000}\"\n  environment: \"${ENV:-development}\"\n  cors_origins: \"${CORS_ORIGINS:-*}\"\n  compression_enabled: true  # gzip/deflate/brotli support (default: true)\n  compression_level: 2       # 1=speed, 2=balanced, 3=best compression\n\n\ndatabase:\n  url: \"${DATABASE_URL}\"\n\npagination:\n  default_limit: \"${PAGINATION_DEFAULT_LIMIT:-10}\"\n  max_limit: \"${PAGINATION_MAX_LIMIT:-1000}\"\n\nauth:\n  enabled: true\n  jwt_secret: \"${JWT_SECRET}\"\n  jwt_ttl: 900\n\nplugins:\n  - name: openapi\n    enabled: true\n    config:\n      title: \"My API\"\n      version: \"1.0.0\"\n```\n\nSet required environment variables:\n```bash\nexport ENV=\"production\"              # default: development\nexport DATABASE_URL=\"postgres://user:pass@localhost:5432/mydb?sslmode=require\"\nexport SERVER_SCHEME=\"https\"         # default: http\nexport SERVER_HOST=\"api.example.com\" # default: localhost\nexport SERVER_PORT=\"8080\"            # default: 8000\nexport JWT_SECRET=$(openssl rand -base64 32)\nexport CORS_ORIGINS=\"localhost:8000\" # default: *\nexport PAGINATION_DEFAULT_LIMIT=\"20\" # default: 10\nexport PAGINATION_MAX_LIMIT=\"5000\"   # default: 1000\n```\n\nOr use a `.env` file (dotenv\u003e support):\n```bash\nENV=production\nDATABASE_URL=postgres://user:pass@localhost:5432/mydb?sslmode=require\nSERVER_SCHEME=https\nSERVER_HOST=api.example.com\nSERVER_PORT=8080\nJWT_SECRET=your-secret-key-here\nCORS_ORIGINS=example.com\nPAGINATION_DEFAULT_LIMIT=20\nPAGINATION_MAX_LIMIT=5000\n```\n\n📚 **[Full configuration documentation →](CONFIGURATION.md)**\n\n#### Environment Variable Interpolation\n\nGoREST supports bash-style environment variable interpolation with default fallback values:\n\n**Syntax:**\n- `${VAR}` - Use environment variable VAR (leaves `${VAR}` unchanged if not set)\n- `${VAR:-default}` - Use environment variable VAR, or \"default\" if not set\n\n**Examples:**\n```yaml\nserver:\n  # Will use environment variable or fallback to default\n  port: \"${SERVER_PORT:-8000}\"\n  host: \"${SERVER_HOST:-localhost}\"\n\n  # Required variable (no default)\n  environment: \"${ENV}\"\n\ndatabase:\n  # Complex defaults work too\n  url: \"${DATABASE_URL:-postgres://user:pass@localhost:5432/dev?sslmode=disable}\"\n\npagination:\n  # Numeric defaults\n  default_limit: \"${PAGINATION_DEFAULT_LIMIT:-10}\"\n  max_limit: \"${PAGINATION_MAX_LIMIT:-1000}\"\n\nauth:\n  # Empty default\n  jwt_secret: \"${JWT_SECRET:-}\"\n```\n\n**Behavior:**\n- If the environment variable is set (even to an empty string), its value is used\n- If the environment variable is not set and a default is provided, the default is used\n- If the environment variable is not set and no default is provided, the original `${VAR}` string remains\n\n**Note:** Environment variable interpolation only works for string fields in the configuration. Integer fields like `port`, `default_limit`, and `max_limit` must be specified as numeric values directly in the YAML file.\n\n### 3. Create Your Main Application\n\nYou can either write your routes manually or use the **[gorest-codegen](https://github.com/nicolasbonnici/gorest-codegen)** plugin to generate them from your database schema.\n\n**Manual approach:**\n```go\npackage main\n\nimport (\n    \"github.com/gofiber/fiber/v2\"\n    \"github.com/nicolasbonnici/gorest\"\n    \"github.com/nicolasbonnici/gorest/crud\"\n    \"github.com/nicolasbonnici/gorest/database\"\n)\n\ntype User struct {\n    ID    string `json:\"id\" db:\"id\"`\n    Email string `json:\"email\" db:\"email\"`\n}\n\nfunc (User) TableName() string { return \"users\" }\n\nfunc main() {\n    cfg := gorest.Config{\n        ConfigPath: \".\",\n        RegisterRoutes: func(router fiber.Router, db database.Database, paginationLimit, paginationMaxLimit int, pluginRegistry *plugin.PluginRegistry) {\n            userCRUD := crud.New[User](db)\n            router.Get(\"/users\", func(c *fiber.Ctx) error {\n                result, _ := userCRUD.GetAllPaginated(c.Context(), crud.PaginationOptions{Limit: 10})\n                return c.JSON(result.Items)\n            })\n        },\n    }\n    gorest.Start(cfg)\n}\n```\n\n**With code generation plugin:**\n```bash\n# Install and run gorest-codegen\ngo run github.com/nicolasbonnici/gorest-codegen/cmd/codegen@latest all\n```\n\n```go\npackage main\n\nimport (\n    \"github.com/yourusername/my-api/generated/resources\"\n    \"github.com/nicolasbonnici/gorest\"\n)\n\nfunc main() {\n    cfg := gorest.Config{\n        ConfigPath:     \".\",\n        RegisterRoutes: resources.RegisterGeneratedRoutes,\n    }\n    gorest.Start(cfg)\n}\n```\n\n### 4. Run Your API\n```bash\ngo run main.go\n```\n\nYour API is now running at: **${SERVER_SCHEME}://${SERVER_HOST}:${SERVER_PORT}/v1.0.0/**\n- 📚 API specs: **${SERVER_SCHEME}://${SERVER_HOST}:${SERVER_PORT}/v1.0.0/openapi**\n- 💚 Status: **${SERVER_SCHEME}://${SERVER_HOST}:${SERVER_PORT}/v1.0.0/status**\n\n(With default values: **http://localhost:8000/v1.0.0/**)\n\n**Note**: Development builds default to `/v1.0.0` prefix. Use build-time version injection for production deployments.\n\n---\n\n## 📦 GoREST usage\n\nImport GoREST library directly in your Go projects:\n\n```bash\ngo get github.com/nicolasbonnici/gorest@latest\n```\n\n### Available Packages\n\n| Package | Description |\n|---------|-------------|\n| `processor` | Unified API processor eliminating handler boilerplate |\n| `query` | Type-safe SQL query builder |\n| `crud` | Type-safe CRUD operations with hooks |\n| `database` | Multi-database abstraction |\n| `expand` | Relation expansion (IRI to object) |\n| `filter` | Query filtering \u0026 ordering |\n| `serializer` | JSON-LD response serialization |\n| `hooks` | Lifecycle hooks for business logic |\n| `plugin` | Plugin interfaces |\n| `pluginloader` | Plugin factory \u0026 loading |\n| `pagination` | Hydra-compliant pagination |\n| `response` | HTTP response helpers |\n| `migrations` | Database migration system |\n| `fixtures` | Test fixture management |\n\n### Example\n\n```go\nimport (\n    \"github.com/gofiber/fiber/v2\"\n    \"github.com/nicolasbonnici/gorest/database\"\n    \"github.com/nicolasbonnici/gorest/crud\"\n    authpkg \"github.com/nicolasbonnici/gorest/auth\"\n)\n\ntype User struct {\n    ID    string `json:\"id\" db:\"id\"`\n    Email string `json:\"email\" db:\"   email\"`\n}\n\nfunc (User) TableName() string { return \"users\" }\n\nfunc main() {\n    db, _ := database.Open(\"postgres\", \"postgres://...\")\n    defer db.Close()\n\n    userCRUD := crud.New[User](db)\n    router := fiber.New()\n\n    router.Get(\"/users\", auth.RequireAuth(\"secret\", func(c *fiber.Ctx) error {\n        ctx := auth.Context(c)\n        result, _ := userCRUD.GetAllPaginated(ctx, crud.PaginationOptions{Limit: 10})\n        return c.JSON(result.Items)\n    }))\n\n    router.Listen(\":8000\")\n}\n```\n\n📚 [Full API documentation on pkg.go.dev](https://pkg.go.dev/github.com/nicolasbonnici/gorest)\n\n---\n\n## 📚 Core Documentation\n\n### Configuration \u0026 Setup\n- **[Configuration →](CONFIGURATION.md)** - YAML configuration, environment overrides, and templates\n\n### API Development\n- **[Processor →](processor/README.md)** - Unified API processor eliminating CRUD boilerplate with one-liner handlers\n\n### Data Management\n- **[Query Builder →](QUERY_BUILDER.md)** - Type-safe SQL query builder with fluent API\n- **[Filtering \u0026 Ordering →](FILTERING.md)** - Advanced query filtering, comparison operators, and ordering\n- **[Relation Expansion →](serializer/EXPAND_USAGE.md)** - Expand IRI references to full nested objects\n- **[Serializer →](serializer/README.md)** - Flexible resource serializer with JSON-LD support\n- **[Database Migrations →](migrations/README.md)** - Migration system with multi-database support\n- **[Migration CLI →](migrations/CLI.md)** - `migrate` CLI for running, rolling back, and repairing migrations\n- **[User \u0026 Role CLI →](cmd/user/CLI.md)** - `user` CLI for managing users, assigning roles, and viewing role hierarchy\n- **[Fixtures →](fixtures/README.md)** - Test fixture management\n\n### Business Logic\n- **[DTOs \u0026 Field Control →](DTOS.md)** - Control resource attributes with `dto` tags\n- **[Hooks System →](HOOKS.md)** - Lifecycle hooks for custom business logic\n- **[Plugins →](PLUGINS.md)** - Plugin system, built-in plugins, and custom plugin creation\n\n---\n   \n## 🔍 Quick Examples\n\n### Query Builder\n\n```go\nimport \"github.com/nicolasbonnici/gorest/query\"\n\n// Build type-safe SQL queries\nsql, args := query.New(db.Dialect()).\n    Select(\"id\", \"name\", \"email\").\n    From(\"users\").\n    Where(query.Eq(\"status\", \"active\")).\n    Where(query.Gt(\"age\", 18)).\n    OrderBy(\"created_at\", query.DESC).\n    Limit(10).\n    Build()\n\n// Use in hooks without string manipulation\nfunc (h *PostHooks) ModifySelectQuery(ctx context.Context, op hooks.Operation, builder *query.SelectBuilder) (*query.SelectBuilder, bool) {\n    if !isAuthenticated(ctx) {\n        builder = builder.Where(query.Eq(\"status\", \"published\"))\n        return builder, true\n    }\n    return builder, false\n}\n```\n\n📚 **[Full query builder documentation →](QUERY_BUILDER.md)**\n\n### Processor Pattern\n\n```go\nimport \"github.com/nicolasbonnici/gorest/processor\"\n\n// Create processor with configuration\nproc := processor.New(processor.ProcessorConfig[\n    models.Todo,\n    dtos.TodoCreateDTO,\n    dtos.TodoUpdateDTO,\n    dtos.TodoResponseDTO,\n]{\n    DB:                 db,\n    CRUD:               crud.New[models.Todo](db),\n    Converter:          \u0026converters.TodoConverter{},\n    PaginationLimit:    20,\n    PaginationMaxLimit: 100,\n    AllowedFields:      []string{\"id\", \"title\", \"status\", \"created_at\"},\n}).\n    WithCreateHook(hooks.CreateHook).\n    WithUpdateHook(hooks.UpdateHook)\n\n// Handlers become one-liners\ntype TodoResource struct {\n    processor processor.Processor[models.Todo, dtos.TodoCreateDTO, dtos.TodoUpdateDTO, dtos.TodoResponseDTO]\n}\n\nfunc (r *TodoResource) Create(c *fiber.Ctx) error  { return r.processor.Create(c) }\nfunc (r *TodoResource) GetAll(c *fiber.Ctx) error  { return r.processor.GetAll(c) }\nfunc (r *TodoResource) GetByID(c *fiber.Ctx) error { return r.processor.GetByID(c) }\nfunc (r *TodoResource) Update(c *fiber.Ctx) error  { return r.processor.Update(c) }\nfunc (r *TodoResource) Delete(c *fiber.Ctx) error  { return r.processor.Delete(c) }\n```\n\n📚 **[Full processor documentation →](processor/README.md)**\n\n### Filtering \u0026 Ordering\n\n```bash\n# Filter by status\nGET /v1.0.0/todos?status=active\n\n# Multiple filters with comparison\nGET /v1.0.0/todos?status=active\u0026priority[gte]=5\n\n# Order results\nGET /v1.0.0/todos?order[createdAt]=desc\n\n# Combine all\nGET /v1.0.0/todos?status=active\u0026priority[gte]=5\u0026order[createdAt]=desc\u0026limit=10\n```\n\n📚 **[Full filtering documentation →](FILTERING.md)**\n\n### Expand Relations\n\n```bash\n# IRI reference (default)\nGET /v1.0.0/todos/123\n# Returns: { \"user\": \"/v1.0.0/users/456\", ... }\n\n# Expand to full object\nGET /v1.0.0/todos/123?expand[]=user\n# Returns: { \"user\": { \"id\": \"456\", \"name\": \"Alice\", ... }, ... }\n```\n\n📚 **[Full expansion documentation →](serializer/EXPAND_USAGE.md)**\n\n### JSON-LD Support\n\n```bash\n# Regular JSON\ncurl -H \"Accept: application/json\" http://localhost:8000/v1.0.0/todos/123\n\n# JSON-LD with semantic context\ncurl -H \"Accept: application/ld+json\" http://localhost:8000/v1.0.0/todos/123\n\n# Production with custom version\ncurl -H \"Accept: application/json\" https://api.example.com/v2.1.0/todos/123\n```\n\n📚 **[Full JSON-LD documentation →](serializer/README.md)**\n\n---\n\n## 📂 Project Structure\n\n### Basic Project\n```   \nmy-api/\n├── gorest.yaml              # Configuration\n└── main.go                  # Your application\n```\n\n### With Code Generation Plugin (optional)\n```\nmy-api/\n├── gorest.yaml              # Configuration\n├── main.go                  # Your application\n└── generated/               # Generated by gorest-codegen plugin\n    ├── models/              # DB models\n    ├── resources/           # REST handlers\n    ├── dtos/                # Data transfer objects\n    └── openapi/             # OpenAPI schema\n```\n\n### GoREST Library\n```\ngorest/\n├── processor/               # Unified API processor\n├── auth/                    # Built-in authentication layer\n├── crud/                    # Generic CRUD\n├── database/                # Multi-DB abstraction\n│   ├── postgres/\n│   ├── mysql/\n│   └── sqlite/\n├── migrations/              # Migration system\n├── fixtures/                # Fixture management\n├── expand/                  # Relation expansion\n├── filter/                  # Query filtering\n├── serializer/              # JSON-LD serialization\n├── hooks/                   # Lifecycle hooks\n├── plugin/                  # Plugin interfaces\n├── pluginloader/            # Plugin loading\n├── middleware/              # Core middleware\n├── pagination/              # Hydra pagination\n└── response/                # HTTP helpers\n```\n\n---\n\n## 🛠 Development Commands\n\n```bash\n# Testing\nmake test-up          # Start test databases\nmake test-schema      # Load test schema\nmake test             # Run all tests\nmake test-coverage    # Run tests with coverage\n```\n\n**Code Generation Plugin:**\nSee [gorest-codegen](https://github.com/nicolasbonnici/gorest-codegen) for generating models, resources, DTOs and OpenAPI specs from your database schema.\n\n---\n\n## 🚀 Production Deployment\n\n### Docker\n\nUsing GoREST status plugin [gorest-status](https://github.com/nicolasbonnici/gorest-status)\n\n```dockerfile\n# Dockerfile\nFROM golang:1.23-alpine AS builder\nWORKDIR /app\nCOPY . .\n# Inject version from git tag at build time\nRUN go build -ldflags \"-X github.com/nicolasbonnici/gorest.Version=$(git describe --tags --always)\" -o api\n\nFROM alpine:latest\nRUN apk --no-cache add ca-certificates curl\nWORKDIR /root/\nCOPY --from=builder /app/api .\nCMD [\"./api\"]\n```\n\n```yaml\n# docker-compose.yml\nservices:\n  api:\n    build:\n      context: .\n      args:\n        VERSION: v1.0.0  # Or use git describe --tags\n    ports: [\"8000:8000\"]\n    environment:\n      - DATABASE_URL=${DATABASE_URL}\n      - JWT_SECRET=${JWT_SECRET}\n    healthcheck:\n      test: [\"CMD\", \"curl\", \"-f\", \"http://localhost:8000/v1.0.0/status\"]\n      interval: 30s\n      timeout: 3s\n      retries: 3\n```\n\n### Nginx Reverse Proxy\n\n```nginx\nupstream gorest {\n    server localhost:8000;\n}\n\nserver {\n    listen 443 ssl http2;\n    server_name api.example.com;\n\n    # SSL configuration\n    ssl_certificate /path/to/cert.pem;\n    ssl_certificate_key /path/to/key.pem;\n\n    # Redirect root to latest versioned API docs\n    location = / {\n        return 301 https://$host/v2.0.0/openapi;\n    }\n\n    # Proxy all versioned routes\n    location / {\n        proxy_pass http://gorest;\n        proxy_set_header Host $host;\n        proxy_set_header X-Real-IP $remote_addr;\n        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;\n        proxy_set_header X-Forwarded-Proto $scheme;\n\n        # Recommended headers\n        proxy_set_header X-Request-ID $request_id;\n        proxy_buffering off;\n    }\n}\n```\n\n### Kubernetes Health Checks\n\n```yaml\nlivenessProbe:\n  httpGet:\n    path: /v1.0.0/status\n    port: 8000\n  initialDelaySeconds: 10\n  periodSeconds: 30\n\nreadinessProbe:\n  httpGet:\n    path: /v1.0.0/status\n    port: 8000\n  initialDelaySeconds: 5\n  periodSeconds: 10\n```\n\n---\n\n## 🏷️ API Versioning\n\nGoREST automatically versions your API routes based on your git tags with zero configuration required. All routes are prefixed with the version for consistency across development, staging, and production environments.\n\n### How It Works\n\nAll routes are automatically prefixed with the version for consistency across all environments:\n\n| Environment | Build Command | Version Variable | Route Example |\n|-------------|--------------|------------------|---------------|\n| Development | `go build` | `dev` → **v1.0.0** (fallback) | `/v1.0.0/posts` |\n| Staging | `go build -ldflags \"-X github.com/nicolasbonnici/gorest.Version=v1.0.0-rc1\"` | `v1.0.0-rc1` | `/v1.0.0-rc1/posts` |\n| Production | `go build -ldflags \"-X github.com/nicolasbonnici/gorest.Version=v2.3.1\"` | `v2.3.1` | `/v2.3.1/posts` |\n| From Git | `go build -ldflags \"-X github.com/nicolasbonnici/gorest.Version=$(git describe --tags)\"` | Git tag | `/v1.2.3/posts` |\n\n**Fallback behavior**: If no version is provided or version is `\"dev\"`, routes default to `/v1.0.0` prefix.\n\n### Build with Version\n\n```bash\n# Development build (defaults to v1.0.0)\ngo build\n# Routes: /v1.0.0/posts, /v1.0.0/health, /v1.0.0/login\n\n# Production build with version from git tag\ngo build -ldflags \"-X github.com/nicolasbonnici/gorest.Version=$(git describe --tags --always)\"\n# Routes: /v1.2.3/posts, /v1.2.3/health, /v1.2.3/login\n\n# Or use a specific version\ngo build -ldflags \"-X github.com/nicolasbonnici/gorest.Version=v2.0.0\"\n# Routes: /v2.0.0/posts, /v2.0.0/health, /v2.0.0/login\n```\n\n### Example\n\n```bash\n# Development build (defaults to v1.0.0)\ngo build\ncurl http://localhost:8000/v1.0.0/posts\n\n# Production build with version v2.0.0\ngo build -ldflags \"-X github.com/nicolasbonnici/gorest.Version=v2.0.0\"\ncurl http://localhost:8000/v2.0.0/posts\n```\n\n### What Gets Versioned\n\nAll routes are automatically versioned, including:\n- **User routes**: Your application endpoints (e.g., `/v1.0.0/posts`, `/v2.0.0/users`)\n- **Plugin endpoints**: Built-in plugin routes (e.g., `/v1.0.0/health`, `/v1.0.0/login`, `/v1.0.0/openapi`)\n\n### Benefits\n\n✅ **Consistent across environments** - Same URL structure in dev, staging, and production (all use proper semantic versions)\n✅ **Easy API evolution** - Support multiple API versions simultaneously\n✅ **Clear versioning** - Version is always visible in the URL\n✅ **Zero configuration** - Defaults to v1.0.0, or use build-time version injection\n✅ **No weird prefixes** - Always uses proper semantic versioning (v1.0.0, v2.1.3, etc.)\n\n### Multiple API Versions\n\nTo support multiple API versions simultaneously, deploy separate instances with different version builds:\n\n```bash\n# Build v1.0.0\ngo build -ldflags \"-X github.com/nicolasbonnici/gorest.Version=v1.0.0\" -o api-v1\n\n# Build v2.0.0 with breaking changes\ngo build -ldflags \"-X github.com/nicolasbonnici/gorest.Version=v2.0.0\" -o api-v2\n\n# Run both on different ports\nPORT=8001 ./api-v1 \u0026  # Serves /v1.0.0/*\nPORT=8002 ./api-v2 \u0026  # Serves /v2.0.0/*\n```\n\nUse a reverse proxy to route by version prefix:\n\n```nginx\n# Route v1 requests\nlocation /v1.0.0/ {\n    proxy_pass http://localhost:8001/v1.0.0/;\n}\n\n# Route v2 requests\nlocation /v2.0.0/ {\n    proxy_pass http://localhost:8002/v2.0.0/;\n}\n\n# Default to latest version\nlocation / {\n    proxy_pass http://localhost:8002/v2.0.0/;\n}\n```\n\n---\n\n## 🔒 Security\n\n- **Passwords**: bcrypt hashing with automatic salts\n- **JWT**: 32+ character secrets required\n- **CORS**: Configurable origins\n- **Rate Limiting**: Configurable per-IP limits\n- **SQL Injection**: Parameterized queries\n- **Input Validation**: go-playground/validator support\n- **Security Headers**: X-Frame-Options, C   SP, HSTS, etc.\n\n---\n\n## Git Hooks\n\nThis directory contains git hooks for the GoREST project to maintain code quality.\n\n### Available Hooks\n\n#### pre-commit\n\nRuns before each commit to ensure code quality:\n- **Linting**: Runs `make lint` to check code style and potential issues\n- **Tests**: Runs `make test` to verify all tests pass\n\n### Installation\n\n#### Automatic Installation\n\nRun the install script from the project root:\n\n```bash\n./.githooks/install.sh\n```\n\n### Manual Installation\n\nCopy the hooks to your `.git/hooks` directory:\n\n```bash\ncp .githooks/pre-commit .git/hooks/pre-commit\nchmod +x .git/hooks/pre-commit\n```\n\n## 🤝 Contributing\n\nSee [CONTRIBUTING.md](CONTRIBUTING.md) for guidelines.\n\nQuick start:\n```bash\ngit clone https://github.com/YOUR_USERNAME/gorest.git\ncd gorest\nmake test-up \u0026\u0026 make test-schema \u0026\u0026 make test\n```\n\n---\n\n## 📋 Changelog\n\nSee [CHANGELOG.md](CHANGELOG.md) for release history.\n\n---\n\n## 📜 License\n\nMIT – free to use in your projects 🚀\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnicolasbonnici%2Fgorest","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fnicolasbonnici%2Fgorest","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnicolasbonnici%2Fgorest/lists"}