Skip to content

API Docs

When entrest.Config.DisableSpecHandler is false at generation time, entrest embeds the OpenAPI spec in your generated rest package and registers GET {BasePath}/openapi.json and GET {BasePath}/docs (an embedded Scalar UI). With the stdlib handler, GET / (after BasePath is stripped) redirects to /docs. See Configuration — Base URL and path for how mount paths affect these URLs.

Scalar OpenAPI UI

The /docs route is implemented by Server.Docs. It renders a single inline HTML document on each request and loads Scalar from the jsDelivr CDN — there is no separate static site.

Route registration, spec serving, and DisableDocsHandler are covered in Configuration — OpenAPI spec endpoint and API reference docs.

Any OpenAPI viewer that accepts a spec URL can replace the embedded Scalar page:

  1. Set DisableDocsHandler to true so /docs is not registered by the generated handler.
  2. Keep /openapi.json enabled (unless you serve the spec from another origin).
  3. Register your own GET handler that returns a single HTML document.
  4. Point the viewer at {BasePath}/openapi.json (or an absolute URL if the UI is on another host).

The examples below use RapiDoc and mount custom docs at /v1/docs.

This example serves one self-contained HTML page from Go with fmt.Fprintf, loads RapiDoc from the unpkg CDN, and overrides component attributes for a focused dark layout.

main.go
// [...]
func rapidocDocs(baseURL string) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
uri := strings.TrimSuffix(baseURL, "/")
w.Header().Set("Content-Type", "text/html")
w.WriteHeader(http.StatusOK)
fmt.Fprintf(w, `<!doctype html>
<html>
<head>
<meta charset="utf-8">
<meta name="referrer" content="no-referrer">
<script type="module" src="https://unpkg.com/rapidoc@9.3.8/dist/rapidoc-min.js"></script>
<title>Pet Store API</title>
</head>
<body>
<rapi-doc
allow-server-selection="false"
bg-color="#18181C"
fill-request-fields-with-example="false"
font-size="large"
layout="row"
load-fonts="false"
mono-font="Consolas, monaco, monospace"
nav-bg-color="#0F0F0F"
nav-hover-bg-color="#1B1B1B"
primary-color="#10B981"
regular-font="Consolas, monaco, monospace"
render-style="focused"
schema-description-expanded="true"
show-curl-before-try="true"
show-header="false"
show-method-in-nav-bar="as-colored-text"
spec-url=%q
text-color="#BBBBBB"
theme="dark"
use-path-in-nav-bar="true"
persist-auth="true"
></rapi-doc>
</body>
</html>`, uri+"/openapi.json")
}
}
func main() {
// [...]
mux := http.NewServeMux()
mux.HandleFunc("GET /v1/docs{$}", rapidocDocs(cfg.BaseURL))
mux.Handle("/", srv.Handler())
log.Fatal(http.ListenAndServe(":8080", mux))
}

Register the docs route on the same sub-router where you mount the generated API. Set BasePath to match the mount point so spec URLs stay correct — see Configuration — Stdlib vs chi.

main.go
cfg := &rest.ServerConfig{
BaseURL: "https://api.example.com/v1",
BasePath: "/v1",
DisableDocsHandler: true,
}
srv, err := rest.NewServer(db, cfg)
if err != nil {
panic(err)
}
r := chi.NewRouter()
r.Route("/v1", func(r chi.Router) {
r.Get("/docs", rapidocDocs(cfg.BaseURL))
srv.Handler(r)
})
http.ListenAndServe(":8080", r)
llms.txtdocumentation for LLMs