Skip to main content

๐Ÿงพ apigen โ€“ API Documentation Generator

The karma/apigen package helps you auto-generate OpenAPI-style REST documentation directly from Go structs. It supports dynamic path params, field overrides, global variables, reusable request/response bodies, and inline headers. Itโ€™s ideal for documenting internal or external APIs with zero OpenAPI spec learning curve.

๐Ÿš€ Quick Start

๐Ÿ“ฆ Installation

go get github.com/MelloB1989/karma/apigen

โœ… Create a New API Definition

api := apigen.NewAPIDefinition(
	"GitLab Issues API",                      // Title
	"API for managing issues in GitLab",      // Description
	[]string{"https://gitlab.com/api/v4"},    // Base URLs
	"./docs",                                 // Output folder
	"gitlab_issues",                          // Output filename prefix
)

๐ŸŒ Add Global Variables

These are available as $variables in your documentation templates:
api.AddGlobalVariable("api_version", "v4")
api.AddGlobalVariable("default_per_page", "20")

๐Ÿ” Request and Response Bodies

๐Ÿงฑ Generate Request Body from Struct

body, err := apigen.RequestBodyFromStruct(MyRequestStruct{}, "application/json", true, []apigen.FieldOverride{})
Use FieldOverride to provide examples, override descriptions, or exclude specific fields.

Example override:

[]apigen.FieldOverride{
	{
		Name:     "DueDate",
		Example:  "2025-06-30",
		Required: new(bool),
	},
	{
		Name:    "TableName",
		Exclude: true,
	},
}

๐Ÿ“ฆ Generate Response from Struct

response, err := apigen.ResponseFromStruct(
	200,
	"User created successfully",
	UserResponse{},
	"application/json",
	[]apigen.FieldOverride{},
)

๐Ÿงฉ Define Endpoints

Use AddEndpoint to declare a REST endpoint with method, path, headers, params, and expected responses.

Example โ€“ POST /projects/{project_id}/issues

api.AddEndpoint(apigen.Endpoint{
	Path:        "/projects/{project_id}/issues",
	Method:      "POST",
	Summary:     "Create new issue",
	Description: "Creates a new issue in GitLab",
	PathParams: []apigen.Parameter{
		{
			Name:        "project_id",
			Type:        "integer",
			Required:    true,
			Description: "GitLab project ID",
			Example:     "12345",
		},
	},
	Headers: apigen.KarmaHeaders{
		apigen.HeaderPrivateToken: "YOUR_GITLAB_TOKEN",
		apigen.HeaderContentType:  "application/json",
		apigen.HeaderAccept:       "application/json",
	},
	RequestBody: requestBody,
	Responses: []apigen.Response{
		*successResponse,
		{
			StatusCode:  400,
			Description: "Bad request",
			Example:     []byte(`{"message": "Invalid input"}`),
		},
	},
})

๐Ÿ” Authentication Example: Auth APIs

auth := apigen.NewAPIDefinition(
	"Auth APIs",
	"Authentication APIs for users",
	[]string{"http://localhost:9000"},
	"./docs/auth",
	"auth",
)

Example โ€“ POST /auth/login

loginBody, _ := apigen.RequestBodyFromStruct(LoginBody{}, apigen.ContentTypeJSON, true, nil)
successResp, _ := apigen.ResponseFromStruct(200, "OTP sent", LoginSuccess{}, apigen.ContentTypeJSON, nil)

auth.AddEndpoint(apigen.Endpoint{
	Path:        "/auth/login",
	Method:      "POST",
	Summary:     "Login with phone number",
	Description: "Send OTP to user phone",
	RequestBody: loginBody,
	Responses: []apigen.Response{
		*successResp,
		{
			StatusCode: 400,
			Description: "Invalid phone number",
			Example:     []byte(`{"success": false, "message": "Invalid phone number"}`),
		},
	},
})

๐Ÿ“„ Export Documentation

err := api.ExportAll()
if err != nil {
	log.Fatalf("Export failed: %v", err)
}
This generates markdown or HTML documentation in the specified folder (e.g., ./docs/gitlab_issues.md or .html depending on config).

๐Ÿง  Tips

  • PathParams can be defined explicitly or inferred from {} in path strings.
  • Headers are centralized via KarmaHeaders constants.
  • Use FieldOverride.Exclude to hide internal struct fields (e.g., TableName, Id, CreatedAt).
  • Combine multiple APIDefinition blocks for different modules (e.g. Auth, Admin, Public APIs).

๐Ÿ“ฆ Constants Reference

  • apigen.ContentTypeJSON: "application/json"
  • apigen.HeaderAccept: "Accept"
  • apigen.HeaderContentType: "Content-Type"
  • apigen.HeaderPrivateToken: "PRIVATE-TOKEN"

๐Ÿงช Real Example Output

The example generates documentation for:
  • GET /projects/{project_id}/issues
  • POST /projects/{project_id}/issues
  • GET /projects/{project_id}/issues/{issue_id}
  • POST /auth/login
  • POST /auth/verify_otp
  • POST /auth/register
All with automatic type inference, examples, field descriptions, and header control.