Skip to content
Draft
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
ed61350
test: assert raw openapi spec matches fixture
gaby Aug 21, 2025
0cded2b
refactor: split route media types
gaby Aug 22, 2025
886ed13
feat: add route tags and deprecation
gaby Aug 22, 2025
60d4596
test: expand openapi middleware coverage
gaby Sep 4, 2025
149c053
test: cover openapi helpers
gaby Sep 4, 2025
ddbaa0f
feat(openapi): add operation helpers
gaby Sep 19, 2025
4ab58fd
refactor: use maps.Copy for metadata cloning
gaby Sep 21, 2025
9b1a022
docs: clarify openapi type reference
gaby Sep 21, 2025
2b4fa75
test: normalize openapi json assertions
gaby Oct 24, 2025
2bab831
chore: address openapi review feedback
gaby Oct 25, 2025
3c33f84
fix: scope openapi handler to its resolved path
gaby Nov 3, 2025
7da513d
Adjust OpenAPI default responses
gaby Dec 27, 2025
abe75b9
Extend OpenAPI helpers with schema refs and examples
gaby Jan 3, 2026
87d1f44
Merge branch 'main' into 2025-08-21-14-48-18
gaby Jan 9, 2026
868cf03
Merge branch 'main' into 2025-08-21-14-48-18
gaby Jan 16, 2026
ac3bc5c
Merge branch 'main' into 2025-08-21-14-48-18
gaby Jan 19, 2026
615d8e9
Merge branch 'main' into 2025-08-21-14-48-18
gaby Jan 21, 2026
abcc817
Merge branch 'main' into 2025-08-21-14-48-18
gaby Jan 23, 2026
603b4ab
Merge branch 'main' into 2025-08-21-14-48-18
gaby Jan 26, 2026
d092785
πŸ› bug: fix merge conflicts and auto-generated HEAD routes in OpenAPI …
Claude Mar 27, 2026
0c16991
πŸ”₯ feat: merge parallel benchmarks from main into router_test.go
Claude Mar 27, 2026
272d61e
🧹 chore: fix lint issues and optimize struct alignment
Claude Mar 27, 2026
1ecf5d1
Merge branch 'main' into 2025-08-21-14-48-18
gaby Mar 27, 2026
b76e04d
🧹 chore: address review comments - clone Tags, filter middleware rout…
Copilot Mar 27, 2026
9158f56
🧹 chore: fix deprecated utils.ToLower lint warning
Copilot Mar 27, 2026
d342624
βœ… test: add auto-HEAD exclusion test for OpenAPI middleware
Copilot Mar 27, 2026
4e33e7d
Merge branch 'main' into 2025-08-21-14-48-18
gaby Mar 29, 2026
49ee7a2
fix: add OpenAPI methods to domainRouter, defensive-copy Tags slice, …
Copilot Mar 29, 2026
38a32b9
refactor: simplify Tags() defensive copy
Copilot Mar 29, 2026
9946f64
πŸ”’ security: harden OpenAPI middleware - fix path generation, add nil …
Claude Mar 30, 2026
8dcfd7c
πŸ§ͺ test: improve openapi middleware coverage to 93.1%
Claude Mar 30, 2026
e3918d1
Merge branch 'main' into 2025-08-21-14-48-18
gaby Apr 1, 2026
057e9eb
Merge branch 'main' into 2025-08-21-14-48-18
gaby Apr 5, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 24 additions & 0 deletions app.go
Original file line number Diff line number Diff line change
Expand Up @@ -706,6 +706,30 @@ func (app *App) Name(name string) Router {
return app
}

// Summary assigns a short summary to the most recently added route.
func (app *App) Summary(sum string) Router {
app.mutex.Lock()
app.latestRoute.Summary = sum
app.mutex.Unlock()
return app
}

// Description assigns a description to the most recently added route.
func (app *App) Description(desc string) Router {
app.mutex.Lock()
app.latestRoute.Description = desc
app.mutex.Unlock()
return app
}

// MediaType assigns a response media type to the most recently added route.
func (app *App) MediaType(typ string) Router {
app.mutex.Lock()
app.latestRoute.MediaType = typ
app.mutex.Unlock()
return app
}

// GetRoute Get route by name
func (app *App) GetRoute(name string) Route {
for _, routes := range app.stack {
Expand Down
103 changes: 103 additions & 0 deletions docs/middleware/openapi.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
---
id: openapi
---

# OpenAPI

OpenAPI middleware for [Fiber](https://github.com/gofiber/fiber) that generates an OpenAPI specification based on the routes registered in your application.

## Signatures

```go
func New(config ...Config) fiber.Handler
```

## Examples

Import the middleware package that is part of the Fiber web framework

```go
import (
"github.com/gofiber/fiber/v3"
"github.com/gofiber/fiber/v3/middleware/openapi"
)
```

After you initiate your Fiber app, you can use the following possibilities:

```go
// Initialize default config. Register the middleware *after* all routes
// so that the spec includes every handler.
app.Use(openapi.New())

// Or extend your config for customization
app.Use(openapi.New(openapi.Config{
Title: "My API",
Version: "1.0.0",
ServerURL: "https://example.com",
}))

// Customize metadata for specific operations
app.Use(openapi.New(openapi.Config{
Operations: map[string]openapi.Operation{
"GET /users": {
Summary: "List users",
Description: "Returns all users",
MediaType: fiber.MIMEApplicationJSON,
},
},
}))

// Routes may optionally document themselves using Summary, Description and MediaType
app.Get("/users", listUsers).
Summary("List users").
Description("List all users").
MediaType(fiber.MIMEApplicationJSON)

// If not specified, routes default to an empty summary and description and a
// "text/plain" response media type.
```

Each documented route automatically includes a `200` response with the description `OK` to satisfy the minimum OpenAPI requirements.

`CONNECT` routes are ignored because the OpenAPI specification does not define a `connect` operation.

## Config

| Property | Type | Description | Default |
|:------------|:------------------------|:----------------------------------------------------------------|:------------------:|
| Next | `func(fiber.Ctx) bool` | Next defines a function to skip this middleware when returned true. | `nil` |
| Title | `string` | Title is the title for the generated OpenAPI specification. | `"Fiber API"` |
| Version | `string` | Version is the version for the generated OpenAPI specification. | `"1.0.0"` |
| Description | `string` | Description is the description for the generated specification. | `""` |
| ServerURL | `string` | ServerURL is the server URL used in the generated specification.| `""` |
| Path | `string` | Path is the route where the specification will be served. | `"/openapi.json"` |
| Operations | `map[string]Operation` | Per-route metadata keyed by `METHOD /path`. | `nil` |

## Default Config

```go
var ConfigDefault = Config{
Next: nil,
Title: "Fiber API",
Version: "1.0.0",
Description: "",
ServerURL: "",
Path: "/openapi.json",
Operations: nil,
}
```

### Operation

```go
type Operation struct {
OperationID string
Summary string
Description string
Tags []string
Deprecated bool
MediaType string
}
```

4 changes: 4 additions & 0 deletions docs/whats_new.md
Original file line number Diff line number Diff line change
Expand Up @@ -1288,6 +1288,10 @@ Deprecated fields `Duration`, `Store`, and `Key` have been removed in v3. Use `E

Monitor middleware is migrated to the [Contrib package](https://github.com/gofiber/contrib/tree/main/monitor) with [PR #1172](https://github.com/gofiber/contrib/pull/1172).

### OpenAPI

Introduces an `openapi` middleware that inspects registered routes and serves a generated OpenAPI 3.0 specification. Each operation includes a summary and default `200` response. Routes may attach descriptions and return media types directly or configure them globally.

### Proxy

The proxy middleware has been updated to improve consistency with Go naming conventions. The `TlsConfig` field in the configuration struct has been renamed to `TLSConfig`. Additionally, the `WithTlsConfig` method has been removed; you should now configure TLS directly via the `TLSConfig` property within the `Config` struct.
Expand Down
18 changes: 18 additions & 0 deletions group.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,24 @@ func (grp *Group) Name(name string) Router {
return grp
}

// Summary assigns a short summary to the most recently added route in the group.
func (grp *Group) Summary(sum string) Router {
grp.app.Summary(sum)
return grp
}

// Description assigns a description to the most recently added route in the group.
func (grp *Group) Description(desc string) Router {
grp.app.Description(desc)
return grp
}

// MediaType assigns a response media type to the most recently added route in the group.
func (grp *Group) MediaType(typ string) Router {
grp.app.MediaType(typ)
return grp
}

// Use registers a middleware route that will match requests
// with the provided prefix (which is optional and defaults to "/").
// Also, you can pass another app instance as a sub-router along a routing path.
Expand Down
98 changes: 98 additions & 0 deletions middleware/openapi/config.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
package openapi

import (
"github.com/gofiber/fiber/v3"
)

// Config defines the config for middleware.
type Config struct {

Check failure on line 8 in middleware/openapi/config.go

View workflow job for this annotation

GitHub Actions / lint

fieldalignment: struct with 96 pointer bytes could be 88 (govet)
// Next defines a function to skip this middleware when returned true.
//
// Optional. Default: nil
Next func(c fiber.Ctx) bool

// Title is the title for the generated OpenAPI specification.
//
// Optional. Default: "Fiber API"
Title string

// Version is the version for the generated OpenAPI specification.
//
// Optional. Default: "1.0.0"
Version string

// Description is the description for the generated OpenAPI specification.
//
// Optional. Default: ""
Description string

// ServerURL is the server URL used in the generated specification.
//
// Optional. Default: ""
ServerURL string

// Path is the route where the specification will be served.
//
// Optional. Default: "/openapi.json"
Path string

// Operations allows providing per-route metadata keyed by
// "METHOD /path" (e.g. "GET /users").
//
// Optional. Default: nil
Operations map[string]Operation
}

// ConfigDefault is the default config.
var ConfigDefault = Config{
Next: nil,
Title: "Fiber API",
Version: "1.0.0",
Description: "",
ServerURL: "",
Path: "/openapi.json",
Operations: nil,
}

func configDefault(config ...Config) Config {
if len(config) < 1 {
return ConfigDefault
}

cfg := config[0]

if cfg.Next == nil {
cfg.Next = ConfigDefault.Next
}
if cfg.Title == "" {
cfg.Title = ConfigDefault.Title
}
if cfg.Version == "" {
cfg.Version = ConfigDefault.Version
}
if cfg.Description == "" {
cfg.Description = ConfigDefault.Description
}
if cfg.ServerURL == "" {
cfg.ServerURL = ConfigDefault.ServerURL
}
if cfg.Path == "" {
cfg.Path = ConfigDefault.Path
}
if cfg.Operations == nil {
cfg.Operations = ConfigDefault.Operations
}

return cfg
}

// Operation configures metadata for a single route in the generated spec.
type Operation struct {

Check failure on line 90 in middleware/openapi/config.go

View workflow job for this annotation

GitHub Actions / lint

fieldalignment: struct with 88 pointer bytes could be 72 (govet)
OperationID string
Summary string
Description string
Tags []string
Deprecated bool
// MediaType defines the media type for the 200 response.
MediaType string
}
Loading
Loading