Add a command to write the OpenAPI spec without a server
CI / test (push) Successful in 28s
CI / integration (push) Successful in 39s
CI / publish (push) Skipped
CI / docker (push) Successful in 51s

`just openapi [dir]` (go run ./cmd/openapi) writes openapi.json (3.1) and openapi-3.0.json without a database or configuration. A test checks it matches the spec the server serves.
This commit is contained in:
Sansan committed 2026-10-06 17:01:12 +02:00
1 parent 973ebf224b
commit 6da96f79e7
6 files changed
+108 -1

No files matched your search

+7
View File
@@ -46,6 +46,13 @@ func TestOpenAPISpecIsValid(t *testing.T) {
assert.Len(t, spec31.Paths, spec.Paths.Len())
}
func TestOpenAPISpecWithoutServerMatchesServedSpec(t *testing.T) {
served := newTestEnv(t).do(http.MethodGet, "/openapi.json").Body.Bytes()
offline, err := OpenAPISpec().MarshalJSON()
require.NoError(t, err)
assert.JSONEq(t, string(served), string(offline))
}
func TestOpenAPIDocumentsTheV1API(t *testing.T) {
spec := loadSpec(t, newTestEnv(t))
+14 -1
View File
@@ -8,12 +8,25 @@ import (
"music-server/internal/server/middleware"
"github.com/a-h/templ"
"github.com/danielgtaylor/huma/v2"
"github.com/labstack/echo/v5"
echoMiddleware "github.com/labstack/echo/v5/middleware"
"go.uber.org/zap"
)
func (s *Server) RegisterRoutes() http.Handler {
e, _ := s.routes()
return e
}
// OpenAPISpec returns the API description. It needs no database or configuration:
// the handlers are registered but never called.
func OpenAPISpec() *huma.OpenAPI {
_, a := (&Server{}).routes()
return a.v1.OpenAPI()
}
func (s *Server) routes() (*echo.Echo, apis) {
e := echo.New()
e.HTTPErrorHandler = httpErrorHandler
if len(s.cfg.TrustedProxies) > 0 {
@@ -58,7 +71,7 @@ func (s *Server) RegisterRoutes() http.Handler {
for _, r := range e.Router().Routes() {
logging.GetLogger().Debug("Registered route", zap.String("method", r.Method), zap.String("path", r.Path))
}
return e
return e, a
}
func redirect(to string) echo.HandlerFunc {