notelink

package module
v1.0.0 Latest Latest
Warning

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

Go to latest
Published: Feb 16, 2026 License: MIT Imports: 14 Imported by: 0

README

Go Version License Build Status

Notelink is a Go package that simplifies API documentation generation and integrates it with a Fiber web server. It allows developers to define API endpoints with parameters, schemas, and authentication, and automatically generates an interactive HTML documentation page.

FOSSA Status

Features

  • Endpoint Documentation: Define HTTP methods, paths, descriptions, and responses.
  • Parameter Support: Specify query, path, and header parameters.
  • Schema Generation: Automatically generate TypeScript interfaces from Go structs.
  • JWT Authentication: Built-in middleware for token validation.
  • Interactive Testing: Test endpoints directly from the generated HTML docs.

image

Installation

To use Notelink, ensure you have Go installed, then add it to your project:

go get github.com/canvas-tech-horizon/notelink

Dependencies

Notelink requires the following dependencies:

require (
	github.com/gofiber/fiber/v2 v2.52.9
	github.com/golang-jwt/jwt/v5 v5.2.2
    github.com/joho/godotenv v1.5.1 // optional, for .env support
)

Run go mod tidy to install them.

Usage

Here's a complete example to get you started:

Example: Combined API Create a main.go file:

package main

import (
	"log"
	"os"

	"github.com/canvas-tech-horizon/notelink"
	"github.com/gofiber/fiber/v2"
	"github.com/joho/godotenv"
)

type UserResponse struct {
	ID    int    `json:"id"`
	Name  string `json:"name"`
	Email string `json:"email"`
}

func main() {
	// Load .env file
	if err := godotenv.Load(); err != nil {
		log.Println("No .env file found")
	}

	jwtSecret := os.Getenv("JWT_SECRET")
	if jwtSecret == "" {
		jwtSecret = "my-secret-key"
	}

	config := notelink.Config{
		Title:       "Sample API",
		Description: "A sample API with documentation",
		Version:     "1.0.0",
		Host:        "localhost:8080",
		BasePath:    "/api",
	}

	api := notelink.NewApiNote(&config, jwtSecret)

	// Apply JWT middleware to require authentication for the endpoint
	// api.Use(api.JWTMiddleware())

	// Define the handler
	handler := func(c *fiber.Ctx) error {
		users := []UserResponse{
			{ID: 1, Name: "John", Email: "john@example.com"},
		}
		return c.JSON(users)
	}

	// Register the route using DocumentedRouteInput
	api.DocumentedRoute(notelink.DocumentedRouteInput{
		Method:      "GET",
		Path:        "/v1/users",
		Description: "List users",
		Responses: map[string]string{
			"200": "Success",
			"401": "Unauthorized",
		},
		Handler: handler,
		Params: []notelink.Parameter{
			{
				Name:        "limit",
				In:          "query",
				Type:        "number",
				Description: "Max users",
				Required:    false,
			},
		},
		SchemasRequest:  nil,              // No request body for GET
		SchemasResponse: []UserResponse{}, // Response schema
	})

	// Start the server
	if err := api.Listen(); err != nil {
		log.Fatalf("Failed to start server: %v", err)
	}
}

Configuration

Create a .env file for sensitive data:

JWT_SECRET=your-secure-secret-key

Running the Application

go run main.go

Visit http://localhost:8080/api-docs to see the interactive documentation.

API Documentation

The package generates an HTML page with:

Collapsible Sections: Organized by API version and endpoint paths.

  • Method Coloring: GET (green), POST (blue), etc.
  • Parameter Details: Lists all parameters with types and descriptions.
  • Schemas: Displays TypeScript interfaces for request/response bodies.
  • API Testing: Forms to test endpoints directly from the browser.

License

This project is licensed under the MIT License - see the file for details.

Documentation

Overview

Package notelink provides a framework for generating API documentation and integrating it with a Fiber web server. It allows developers to define endpoints with parameters, schemas, and authentication, and automatically generates an interactive HTML documentation page.

The package supports:

  • Endpoint documentation with methods, paths, descriptions, and responses
  • Parameter definitions (query, path, header)
  • Automatic TypeScript schema generation from Go structs
  • JWT authentication middleware
  • Interactive API testing via a generated HTML interface

To use this package, create an ApiNote instance with a configuration and JWT secret, then define routes using the DocumentedRoute method. The documentation is served at "/api-docs" by default.

Example:

config := notelink.Config{Title: "My API", Host: "localhost:8080"}
api := notelink.NewApiNote(&config, "secret-key")
api.DocumentedRoute("GET", "/api/v1/hello", "Say hello", map[string]string{"200": "Success"}, handler, nil)
api.Listen()

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func ValidateParameters added in v1.0.0

func ValidateParameters(c fiber.Ctx, params []Parameter) error

ValidateParameters validates path/query/header parameters

func ValidateRequestBody added in v1.0.0

func ValidateRequestBody(c fiber.Ctx, schema interface{}) error

ValidateRequestBody validates request body against schema

Types

type ApiNote

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

ApiNote is the main structure for API documentation and routing. It integrates with a Fiber application to serve both the API endpoints and their documentation.

func NewApiNote

func NewApiNote(config *Config, jwtSecret string) *ApiNote

NewApiNote creates a new ApiNote instance with the provided configuration and JWT secret. It initializes a Fiber application and sets up the "/api-docs" route for documentation.

The config parameter defines the API's title, host, and other metadata. The jwtSecret is used for JWT authentication middleware.

Returns a pointer to the initialized ApiNote.

func (*ApiNote) DocumentedRoute

func (an *ApiNote) DocumentedRoute(input *DocumentedRouteInput) error

DocumentedRoute registers an API endpoint with its documentation and handler. It accepts a DocumentedRouteInput object containing the route details and processes it to add the route to the Fiber app and store endpoint details for documentation.

Parameters:

  • input: DocumentedRouteInput object containing method, path, description, responses, handler, params, schemasRequest, and schemasResponse

Example usage:

api.DocumentedRoute(notelink.DocumentedRouteInput{
    Method:      "POST",
    Path:        "/v3/users",
    Description: "Create a new user (Authenticated)",
    Responses: map[string]string{
        "201": "User created",
        "400": "Invalid input",
        "401": "Unauthorized",
    },
    Handler: handlerFunc,
    Params:  []notelink.Parameter{},
    SchemasRequest:  CreateUserRequest{},
    SchemasResponse: UserResponse{},
})

func (*ApiNote) ExportOpenAPIToFile added in v1.0.0

func (an *ApiNote) ExportOpenAPIToFile(filepath string) error

ExportOpenAPIToFile exports the OpenAPI specification to a JSON file

func (*ApiNote) Fiber added in v0.1.7

func (an *ApiNote) Fiber() *fiber.App

Fiber returns the underlying *fiber.App instance used by the ApiNote.

This allows external packages or components to directly access and configure the Fiber application (e.g., for adding routes, middleware, etc.).

func (*ApiNote) GenerateOpenAPISpec added in v1.0.0

func (an *ApiNote) GenerateOpenAPISpec() *OpenAPISpec

GenerateOpenAPISpec creates an OpenAPI 3.1 specification from registered endpoints

func (*ApiNote) Handler

func (an *ApiNote) Handler() fiber.Handler

Handler returns a Fiber handler that serves the API documentation as HTML. The documentation is generated dynamically based on registered endpoints.

The returned handler sets the Content-Type to "text/html" and responds with status 200.

func (*ApiNote) JWTMiddleware

func (an *ApiNote) JWTMiddleware() fiber.Handler

JWTMiddleware returns a Fiber middleware handler that validates JWT tokens. It checks the "Authorization" header for a "Bearer" token and verifies it using the configured jwtSecret.

If the token is valid, it sets the "user_id" in the context from the token's "sub" claim. If invalid or missing, it returns a 401 Unauthorized response.

Example usage:

api.Use(api.JWTMiddleware())

func (*ApiNote) Listen

func (an *ApiNote) Listen() error

Listen starts the Fiber server on the port specified in Config.Host. The Host field should be in the format "host:port" (e.g., "localhost:8080"). If no port is specified, it defaults to ":8080".

Returns an error if the server fails to start.

func (*ApiNote) ScalarUIHandler added in v1.0.0

func (an *ApiNote) ScalarUIHandler() fiber.Handler

ScalarUIHandler returns a handler that serves the Scalar API documentation UI Scalar is a modern alternative to Swagger UI with a cleaner interface

func (*ApiNote) SwaggerUIHandler added in v1.0.0

func (an *ApiNote) SwaggerUIHandler() fiber.Handler

SwaggerUIHandler returns a handler that serves the Swagger UI The Swagger UI is loaded from CDN and points to /api-docs/openapi.json

func (*ApiNote) Use

func (an *ApiNote) Use(middleware ...fiber.Handler)

Use adds one or more middleware handlers to be applied to all subsequent routes. Middleware is executed in the order it is added. These middlewares are treated as custom (non-authentication) middleware and will not set the AuthRequired flag in endpoint documentation.

Example:

api.Use(RequestLoggerMiddleware()) // Apply custom logging to all following routes

func (*ApiNote) UseCustomAuth added in v0.3.1

func (an *ApiNote) UseCustomAuth(middleware ...fiber.Handler)

UseCustomAuth adds custom authentication middleware to all subsequent routes. Routes defined after calling this method will have AuthRequired set to true in their documentation, indicating they require authentication.

This method allows you to use your own authentication logic instead of the built-in JWT middleware while still properly documenting that routes require authentication.

Example:

api.UseCustomAuth(MyCustomAuthMiddleware()) // All routes defined after this will require custom authentication

func (*ApiNote) UseJWT added in v0.3.1

func (an *ApiNote) UseJWT()

UseJWT adds JWT authentication middleware to all subsequent routes. Routes defined after calling this method will have AuthRequired set to true in their documentation, indicating they require authentication.

This is a convenience method that calls JWTMiddleware() and tracks it separately from custom middleware, allowing proper documentation of authentication requirements.

Example:

api.UseJWT() // All routes defined after this will require JWT authentication

type Components added in v1.0.0

type Components struct {
	Schemas         map[string]*JSONSchema    `json:"schemas,omitempty"`
	SecuritySchemes map[string]SecurityScheme `json:"securitySchemes,omitempty"`
}

type Config

type Config struct {
	Title                string
	Description          string
	Version              string
	Host                 string
	BasePath             string
	AuthToken            string // Optional authorization token (e.g., Bearer token)
	DocsUI               string // UI to use for /api-docs endpoint: "scalar" (default) or "swagger"
	EnableValidation     bool   // Enable server-side validation (default: true)
	StrictTypeValidation bool   // Strict type checking vs coercion (default: false)
}

Config holds the API documentation configuration

type DocumentedRouteInput added in v0.2.0

type DocumentedRouteInput struct {
	SchemasRequest  interface{}       `json:"schemasRequest"`
	SchemasResponse interface{}       `json:"schemasResponse"`
	Responses       map[string]string `json:"responses"`
	Handler         fiber.Handler     `json:"handler"`
	AuthRequired    *bool             `json:"authRequired"`
	Method          string            `json:"method"`
	Path            string            `json:"path"`
	Description     string            `json:"description"`
	Params          []Parameter       `json:"params"`
}

DocumentedRouteInput represents the input for registering a documented route

type Endpoint

type Endpoint struct {
	Method         string
	Path           string
	Description    string
	Responses      map[string]string
	RequestSchema  interface{}
	ResponseSchema interface{}
	Parameters     []Parameter
	AuthRequired   bool // Indicates if authorization is required
}

Endpoint represents a single API endpoint with schema and parameters

type JSONSchema added in v1.0.0

type JSONSchema struct {
	AdditionalProperties interface{}            `json:"additionalProperties,omitempty"`
	Properties           map[string]*JSONSchema `json:"properties,omitempty"`
	Items                *JSONSchema            `json:"items,omitempty"`
	Minimum              *float64               `json:"minimum,omitempty"`
	Type                 string                 `json:"type,omitempty"`
	Format               string                 `json:"format,omitempty"`
	Title                string                 `json:"title,omitempty"`
	Description          string                 `json:"description,omitempty"`
	Ref                  string                 `json:"$ref,omitempty"`
	Required             []string               `json:"required,omitempty"`
	Nullable             bool                   `json:"nullable,omitempty"`
}

JSONSchema represents JSON Schema (compatible with OpenAPI 3.1)

type MediaType added in v1.0.0

type MediaType struct {
	Schema  *JSONSchema `json:"schema,omitempty"`
	Example interface{} `json:"example,omitempty"`
}

type OpenAPIInfo added in v1.0.0

type OpenAPIInfo struct {
	Title       string `json:"title"`
	Description string `json:"description,omitempty"`
	Version     string `json:"version"`
}

type OpenAPIServer added in v1.0.0

type OpenAPIServer struct {
	URL         string `json:"url"`
	Description string `json:"description,omitempty"`
}

type OpenAPISpec added in v1.0.0

type OpenAPISpec struct {
	OpenAPI    string                `json:"openapi"`
	Info       OpenAPIInfo           `json:"info"`
	Servers    []OpenAPIServer       `json:"servers,omitempty"`
	Paths      map[string]PathItem   `json:"paths"`
	Components *Components           `json:"components,omitempty"`
	Security   []map[string][]string `json:"security,omitempty"`
}

OpenAPI 3.1 root structure

type Operation added in v1.0.0

type Operation struct {
	OperationID string                `json:"operationId"`
	Summary     string                `json:"summary,omitempty"`
	Description string                `json:"description,omitempty"`
	Parameters  []ParameterSpec       `json:"parameters,omitempty"`
	RequestBody *RequestBody          `json:"requestBody,omitempty"`
	Responses   map[string]Response   `json:"responses"`
	Security    []map[string][]string `json:"security,omitempty"`
	Tags        []string              `json:"tags,omitempty"`
}

type Parameter

type Parameter struct {
	Name        string
	In          string // "query", "path", "header"
	Type        string // e.g., "string", "number", "boolean"
	Description string
	Required    bool
}

Parameter represents an API parameter

type ParameterSpec added in v1.0.0

type ParameterSpec struct {
	Schema      *JSONSchema `json:"schema"`
	Name        string      `json:"name"`
	In          string      `json:"in"` // "query", "path", "header", "cookie"
	Description string      `json:"description,omitempty"`
	Required    bool        `json:"required,omitempty"`
}

type PathItem added in v1.0.0

type PathItem struct {
	Get     *Operation `json:"get,omitempty"`
	Post    *Operation `json:"post,omitempty"`
	Put     *Operation `json:"put,omitempty"`
	Delete  *Operation `json:"delete,omitempty"`
	Patch   *Operation `json:"patch,omitempty"`
	Head    *Operation `json:"head,omitempty"`
	Options *Operation `json:"options,omitempty"`
	Trace   *Operation `json:"trace,omitempty"`
}

type RequestBody added in v1.0.0

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

type Response added in v1.0.0

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

type SecurityScheme added in v1.0.0

type SecurityScheme struct {
	Type         string `json:"type"` // "http", "apiKey", "oauth2", "openIdConnect"
	Scheme       string `json:"scheme,omitempty"`
	BearerFormat string `json:"bearerFormat,omitempty"`
	Description  string `json:"description,omitempty"`
	Name         string `json:"name,omitempty"`
	In           string `json:"in,omitempty"`
}

type ValidationError added in v1.0.0

type ValidationError struct {
	Field   string `json:"field"`
	Message string `json:"message"`
	Type    string `json:"type,omitempty"`
}

ValidationError represents a single validation error

type ValidationErrorResponse added in v1.0.0

type ValidationErrorResponse struct {
	ErrorMessage string            `json:"error"`
	Errors       []ValidationError `json:"errors,omitempty"`
}

ValidationErrorResponse represents the validation error response

func (*ValidationErrorResponse) Error added in v1.0.0

func (v *ValidationErrorResponse) Error() string

Error implements the error interface

Jump to

Keyboard shortcuts

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