fiberoapi

package module
v1.2.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Aug 31, 2025 License: MIT Imports: 8 Imported by: 0

README

Fiber OpenAPI

A Go library that extends Fiber to add automatic OpenAPI documentation generation with built-in validation.

Features

  • Complete HTTP methods (GET, POST, PUT, DELETE) with automatic validation
  • Powerful validation via github.com/go-playground/validator/v10
  • Type safety with Go generics
  • Custom error handling
  • OpenAPI documentation generation with automatic schema generation
  • Support for path, query, and body parameters
  • Automatic documentation setup with configurable paths

Installation

go get github.com/labbs/fiber-oapi

Quick Start

Basic Usage with Default Configuration
package main

import (
    "github.com/gofiber/fiber/v2"
    fiberoapi "github.com/labbs/fiber-oapi"
)

func main() {
    app := fiber.New()
    
    // Create OApi app with default configuration
    // Documentation will be available at /docs and /openapi.json
    oapi := fiberoapi.New(app)

    // Your routes here...

    oapi.Listen(":3000")
}
Custom Configuration
func main() {
    app := fiber.New()
    
    // Custom configuration
    config := fiberoapi.Config{
        EnableValidation:  true,                // Enable input validation
        EnableOpenAPIDocs: true,                // Enable automatic docs setup
        OpenAPIDocsPath:   "/documentation",    // Custom docs path
        OpenAPIJSONPath:   "/api-spec.json",    // Custom spec path
    }
    oapi := fiberoapi.New(app, config)

    // Your routes here...

    oapi.Listen(":3000")
}

Usage Examples

GET with path parameters and validation
type GetInput struct {
    Name string `path:"name" validate:"required,min=2"`
}

type GetOutput struct {
    Message string `json:"message"`
}

type GetError struct {
    Code    int    `json:"code"`
    Message string `json:"message"`
}

fiberoapi.GetOApi(oapi, "/greeting/:name", 
    func(c *fiber.Ctx, input GetInput) (GetOutput, GetError) {
        return GetOutput{Message: "Hello " + input.Name}, GetError{}
    }, 
    fiberoapi.OpenAPIOptions{
        OperationID: "get-greeting",
        Tags:        []string{"greeting"},
        Summary:     "Get a personalized greeting",
    })
POST with JSON body and validation
type CreateUserInput struct {
    Username string `json:"username" validate:"required,min=3,max=20,alphanum"`
    Email    string `json:"email" validate:"required,email"`
    Age      int    `json:"age" validate:"required,min=13,max=120"`
}

type CreateUserOutput struct {
    ID      string `json:"id"`
    Message string `json:"message"`
}

type CreateUserError struct {
    Code    int    `json:"code"`
    Message string `json:"message"`
}

fiberoapi.PostOApi(oapi, "/users", 
    func(c *fiber.Ctx, input CreateUserInput) (CreateUserOutput, CreateUserError) {
        if input.Username == "admin" {
            return CreateUserOutput{}, CreateUserError{
                Code:    403,
                Message: "Username 'admin' is reserved",
            }
        }
        
        return CreateUserOutput{
            ID:      "user_" + input.Username,
            Message: "User created successfully",
        }, CreateUserError{}
    }, 
    fiberoapi.OpenAPIOptions{
        OperationID: "create-user",
        Tags:        []string{"users"},
        Summary:     "Create a new user",
    })
PUT with path parameters and JSON body
type UpdateUserInput struct {
    ID       string `path:"id" validate:"required"`
    Username string `json:"username" validate:"omitempty,min=3,max=20,alphanum"`
    Email    string `json:"email" validate:"omitempty,email"`
    Age      int    `json:"age" validate:"omitempty,min=13,max=120"`
}

type UpdateUserOutput struct {
    ID      string `json:"id"`
    Message string `json:"message"`
    Updated bool   `json:"updated"`
}

fiberoapi.PutOApi(oapi, "/users/:id", 
    func(c *fiber.Ctx, input UpdateUserInput) (UpdateUserOutput, CreateUserError) {
        if input.ID == "notfound" {
            return UpdateUserOutput{}, CreateUserError{
                Code:    404,
                Message: "User not found",
            }
        }
        
        return UpdateUserOutput{
            ID:      input.ID,
            Message: "User updated successfully",
            Updated: true,
        }, CreateUserError{}
    }, 
    fiberoapi.OpenAPIOptions{
        OperationID: "update-user",
        Tags:        []string{"users"},
        Summary:     "Update an existing user",
    })
DELETE with path parameters
type DeleteUserInput struct {
    ID string `path:"id" validate:"required"`
}

type DeleteUserOutput struct {
    ID      string `json:"id"`
    Message string `json:"message"`
    Deleted bool   `json:"deleted"`
}

fiberoapi.DeleteOApi(oapi, "/users/:id", 
    func(c *fiber.Ctx, input DeleteUserInput) (DeleteUserOutput, CreateUserError) {
        if input.ID == "protected" {
            return DeleteUserOutput{}, CreateUserError{
                Code:    403,
                Message: "User is protected and cannot be deleted",
            }
        }
        
        return DeleteUserOutput{
            ID:      input.ID,
            Message: "User deleted successfully",
            Deleted: true,
        }, CreateUserError{}
    }, 
    fiberoapi.OpenAPIOptions{
        OperationID: "delete-user",
        Tags:        []string{"users"},
        Summary:     "Delete a user",
    })

Configuration

The library supports flexible configuration through the Config struct:

type Config struct {
    EnableValidation  bool   // Enable/disable input validation (default: true)
    EnableOpenAPIDocs bool   // Enable automatic docs setup (default: true)
    OpenAPIDocsPath   string // Path for documentation UI (default: "/docs")
    OpenAPIJSONPath   string // Path for OpenAPI JSON spec (default: "/openapi.json")
}
Default Configuration

If no configuration is provided, the library uses these defaults:

  • Validation: enabled
  • Documentation: enabled
  • Docs path: /docs
  • JSON spec path: /openapi.json
Disabling Features
// Disable documentation but keep validation
config := fiberoapi.Config{
    EnableValidation:  true,
    EnableOpenAPIDocs: false,
}

// Or disable validation but keep docs
config := fiberoapi.Config{
    EnableValidation:  false,
    EnableOpenAPIDocs: true,
    OpenAPIDocsPath:   "/api-docs",
    OpenAPIJSONPath:   "/openapi.json",
}

Validation

This library uses validator/v10 for validation. You can use all supported validation tags:

  • required - Required field
  • min=3,max=20 - Min/max length
  • email - Valid email format
  • alphanum - Alphanumeric characters only
  • uuid4 - UUID version 4
  • url - Valid URL
  • oneof=admin user guest - Value from a list
  • dive - Validation for slice elements
  • gtfield=MinPrice - Greater than another field

Supported Parameter Types

  • Path parameters: path:"paramName" (GET, POST, PUT, DELETE)
  • Query parameters: query:"paramName" (GET, DELETE)
  • JSON body: json:"fieldName" (POST, PUT)

Supported HTTP Methods

  • GET: fiberoapi.GetOApi() - Retrieve resources with path/query parameters
  • POST: fiberoapi.PostOApi() - Create resources with JSON body + optional path parameters
  • PUT: fiberoapi.PutOApi() - Update resources with path parameters + JSON body
  • DELETE: fiberoapi.DeleteOApi() - Delete resources with path parameters + optional query parameters

Error Handling

Validation errors are automatically formatted and returned with HTTP status 400:

{
  "error": "Validation failed",
  "details": "Key: 'CreateUserInput.Username' Error:Field validation for 'Username' failed on the 'min' tag"
}

Custom errors use the StatusCode from your error struct.

Testing

Run tests:

go test -v

Example

See the _examples/ folder for a complete usage example.

Documentation

When EnableOpenAPIDocs is set to true (default), the library automatically sets up:

  • Swagger UI: Available at the configured docs path (default: /docs)
  • OpenAPI JSON: Available at the configured JSON path (default: /openapi.json)
  • Automatic Schema Generation: Input and output types are automatically converted to OpenAPI schemas
  • Components Section: All schemas are properly organized in the components/schemas section

No manual setup required! Just visit http://localhost:3000/docs to see your API documentation.

OpenAPI Schema Generation

The library automatically generates OpenAPI 3.0 schemas from your Go types:

// This struct automatically becomes an OpenAPI schema
type User struct {
    ID       string `json:"id"`
    Username string `json:"username" validate:"required,min=3"`
    Email    string `json:"email" validate:"required,email"`
    Age      int    `json:"age" validate:"min=13,max=120"`
}

Generated OpenAPI spec will include:

  • Complete path definitions with parameters
  • Request/response schemas
  • Validation rules as schema constraints
  • Proper HTTP status codes
  • Operation IDs, tags, and descriptions

Migration from v1

If you're migrating from a previous version that used SetupDocs(), you can:

  1. Recommended: Use the new configuration system:
// Old way
oapi := fiberoapi.New(app)
oapi.SetupDocs()

// New way
oapi := fiberoapi.New(app) // Uses defaults, docs auto-configured
  1. Backward compatibility: SetupDocs() is still available but deprecated.
New HTTP Methods

Version 2.0+ includes full CRUD support:

// All methods now available:
fiberoapi.GetOApi(oapi, "/users/:id", handler, options)      // ✅ Available
fiberoapi.PostOApi(oapi, "/users", handler, options)        // ✅ Available  
fiberoapi.PutOApi(oapi, "/users/:id", handler, options)     // ✅ New in v2.0
fiberoapi.DeleteOApi(oapi, "/users/:id", handler, options)  // ✅ New in v2.0

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func Delete added in v1.2.0

func Delete[TInput any, TOutput any, TError any](
	router OApiRouter,
	path string,
	handler HandlerFunc[TInput, TOutput, TError],
	options OpenAPIOptions,
)

Delete defines a DELETE operation for the OpenAPI documentation

func Get added in v1.2.0

func Get[TInput any, TOutput any, TError any](
	router OApiRouter,
	path string,
	handler HandlerFunc[TInput, TOutput, TError],
	options OpenAPIOptions,
)

Get defines a GET operation for the OpenAPI documentation

func Head[TInput any, TOutput any, TError any](
	router OApiRouter,
	path string,
	handler HandlerFunc[TInput, TOutput, TError],
	options OpenAPIOptions,
)

Head defines a HEAD operation for the OpenAPI documentation

func Method added in v1.2.0

func Method[TInput any, TOutput any, TError any](
	router OApiRouter,
	m string,
	path string,
	handler HandlerFunc[TInput, TOutput, TError],
	options OpenAPIOptions,
)

Method defines a generic method for registering HTTP operations with OpenAPI documentation

func Patch added in v1.2.0

func Patch[TInput any, TOutput any, TError any](
	router OApiRouter,
	path string,
	handler HandlerFunc[TInput, TOutput, TError],
	options OpenAPIOptions,
)

Patch defines a PATCH operation for the OpenAPI documentation

func Post added in v1.2.0

func Post[TInput any, TOutput any, TError any](
	router OApiRouter,
	path string,
	handler HandlerFunc[TInput, TOutput, TError],
	options OpenAPIOptions,
)

Post defines a POST operation for the OpenAPI documentation

func Put added in v1.2.0

func Put[TInput any, TOutput any, TError any](
	router OApiRouter,
	path string,
	handler HandlerFunc[TInput, TOutput, TError],
	options OpenAPIOptions,
)

Put defines a PUT operation for the OpenAPI documentation

Types

type Config

type Config struct {
	EnableValidation  bool   // Enable request validation (default: true)
	EnableOpenAPIDocs bool   // Enable automatic docs setup (default: true)
	OpenAPIDocsPath   string // Path for documentation UI (default: "/docs")
	OpenAPIJSONPath   string // Path for OpenAPI JSON spec (default: "/openapi.json")
}

Config represents configuration for the OApi wrapper

func DefaultConfig

func DefaultConfig() Config

DefaultConfig returns the default configuration

type DocConfig

type DocConfig struct {
	Title       string
	Description string
	Version     string
	DocsPath    string // Path where docs will be served, default: "/docs"
	JSONPath    string // Path where OpenAPI JSON will be served, default: "/openapi.json"
}

DocConfig contains configuration for the documentation

func DefaultDocConfig

func DefaultDocConfig() DocConfig

DefaultDocConfig returns default documentation configuration

type HandlerFunc

type HandlerFunc[TInput any, TOutput any, TError any] func(c *fiber.Ctx, input TInput) (TOutput, TError)

HandlerFunc represents a handler function with typed input and output

type OApiApp

type OApiApp struct {
	// contains filtered or unexported fields
}

OApiApp wraps fiber.App with OpenAPI capabilities

func New

func New(app *fiber.App, config ...Config) *OApiApp

New creates a new OApiApp with optional configuration

func (*OApiApp) Config

func (o *OApiApp) Config() Config

Config returns the current configuration

func (*OApiApp) GenerateOpenAPISpec

func (o *OApiApp) GenerateOpenAPISpec() map[string]interface{}

GenerateOpenAPISpec generates a complete OpenAPI 3.0 specification

func (*OApiApp) GetApp added in v1.2.0

func (o *OApiApp) GetApp() *OApiApp

Implement OApiRouter interface for OApiApp

func (*OApiApp) GetOperations

func (o *OApiApp) GetOperations() []OpenAPIOperation

GetOperations returns all registered operations (useful for testing and documentation generation)

func (*OApiApp) GetPrefix added in v1.2.0

func (o *OApiApp) GetPrefix() string

func (*OApiApp) Group added in v1.2.0

func (app *OApiApp) Group(prefix string, handlers ...fiber.Handler) *OApiGroup

Group creates a new OApiGroup that wraps a fiber.Router

func (*OApiApp) SetupDocs

func (o *OApiApp) SetupDocs(config ...DocConfig)

SetupDocs configures documentation routes for the OApiApp

type OApiGroup added in v1.2.0

type OApiGroup struct {
	fiber.Router // Embedded fiber.Router (includes all standard Fiber methods)
	// contains filtered or unexported fields
}

OApiGroup wraps a fiber.Router and adds OpenAPI methods

func Group added in v1.2.0

func Group(router OApiRouter, prefix string, handlers ...fiber.Handler) *OApiGroup

Group creates a new group from an OApiRouter (app or group)

func (*OApiGroup) GetApp added in v1.2.0

func (g *OApiGroup) GetApp() *OApiApp

Implement OApiRouter interface for OApiGroup

func (*OApiGroup) GetPrefix added in v1.2.0

func (g *OApiGroup) GetPrefix() string

func (*OApiGroup) Group added in v1.2.0

func (g *OApiGroup) Group(prefix string, handlers ...fiber.Handler) *OApiGroup

Group creates a new sub-group within this group

type OApiRouter added in v1.2.0

type OApiRouter interface {
	GetApp() *OApiApp
	GetPrefix() string
}

OApiRouter interface that both OApiApp and OApiGroup implement

type OpenAPIOperation

type OpenAPIOperation struct {
	Method     string
	Path       string
	Options    OpenAPIOptions
	InputType  reflect.Type
	OutputType reflect.Type
	ErrorType  reflect.Type
}

OpenAPIOperation represents a registered operation

type OpenAPIOptions

type OpenAPIOptions struct {
	OperationID string                   `json:"operationId,omitempty"`
	Tags        []string                 `json:"tags,omitempty"`
	Summary     string                   `json:"summary,omitempty"`
	Description string                   `json:"description,omitempty"`
	Parameters  []map[string]interface{} `json:"parameters,omitempty"`
}

OpenAPIOptions represents options for OpenAPI operations

type OpenAPIParameter

type OpenAPIParameter struct {
	Name        string                 `json:"name"`
	In          string                 `json:"in"` // "path", "query", "header", "cookie"
	Required    bool                   `json:"required,omitempty"`
	Description string                 `json:"description,omitempty"`
	Schema      map[string]interface{} `json:"schema"`
}

type OpenAPIRequestBody

type OpenAPIRequestBody struct {
	Description string                 `json:"description,omitempty"`
	Required    bool                   `json:"required,omitempty"`
	Content     map[string]interface{} `json:"content"`
}

type OpenAPIResponse

type OpenAPIResponse struct {
	Description string                 `json:"description"`
	Content     map[string]interface{} `json:"content,omitempty"`
}

type PathInfo

type PathInfo struct {
	Name   string
	IsPath bool
	Index  int // Position in the path for validation
}

PathInfo represents information about a path parameter

Directories

Path Synopsis

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL