grafana/grafana
API layer
pkg/api/ is the legacy REST surface — the HTTP handlers that have powered Grafana since the Go server was introduced in 2014. New endpoints increasingly live in app-platform style under apps/ and pkg/apis/, but pkg/api/ is still the dominant external API.
Layout
pkg/api/
├── api.go # Route table — wires every endpoint to a handler
├── http_server.go # HTTPServer struct that holds all service dependencies
├── routing/ # Tree of RouteRegister abstraction over httprouter
├── response/ # Helpers for building JSON responses with status codes
├── apierrors/ # Mapping from typed errors to HTTP status codes
├── dtos/ # Request/response Go structs (DTOs)
├── pluginproxy/ # /api/datasources/proxy/* and /api/plugins/* proxies
├── frontendlogging/ # Browser logging endpoint helpers
├── webassets/ # Resolved index.html for the SPA
├── static/ # Static asset handling
├── avatar/ # Gravatar proxying
├── <resource>.go # Per-resource handlers: dashboard.go, folder.go, …
└── <resource>_test.go # Co-located testsThere are roughly 80 resource files in pkg/api/ and another 80 test files — each a thin handler that authenticates the request, resolves the right service, and returns JSON.
Routing
Routes are declared in pkg/api/api.go using a RouteRegister-based DSL:
r.Get("/api/dashboards/uid/:uid", routing.Wrap(hs.GetDashboard))
r.Group("/api/folders", func(folderRoute routing.RouteRegister) {
folderRoute.Get("/", middleware.ReqOrgAdmin, routing.Wrap(hs.GetFolders))
folderRoute.Get("/:uid", middleware.CanAdminPlugins, routing.Wrap(hs.GetFolderByUID))
// ...
}, middleware.ReqSignedIn)routing.Wrap adapts a func(c *contextmodel.ReqContext) response.Response handler into a stdlib http.HandlerFunc. The routing package abstracts over the underlying mux (pkg/web/) so handlers always see a *ReqContext carrying the authenticated identity and request-scoped helpers.
Middleware chain
The middleware tree is constructed in pkg/middleware/middleware.go. A typical request travels through:
graph LR
R[Request] --> RID[RequestID]
RID --> Logger[Access log]
Logger --> Recov[Recovery]
Recov --> CORS[CORS]
CORS --> Auth[Authentication<br/>contexthandler.go]
Auth --> RBAC[RBAC checks<br/>per-route]
RBAC --> Quota[Quota]
Quota --> HandlerAuthentication lives in pkg/services/contexthandler/contexthandler.go and dispatches to the auth-method clients in pkg/services/authn/ (basic, OAuth, JWT, anonymous, render token, service account, …).
HTTPServer struct
HTTPServer in pkg/api/http_server.go is the god-struct for the legacy API: it holds references to every service that any handler needs. New service dependencies are added by:
- Adding the field to
HTTPServer. - Adding the parameter to
ProvideHTTPServer(...). - Letting Wire fill it in.
This file regularly grows / shrinks during refactors. Newer subsystems prefer to have their own api/ subpackage rather than living on HTTPServer directly.
Errors and responses
- Handlers return
response.Response— a small wrapper over status code + body + headers. - Typed errors from services are mapped to HTTP statuses in
pkg/api/apierrors/usingerrutilcodes (pkg/util/errutil/). - The convention is to return
response.Err(err)for service errors andresponse.JSON(http.StatusOK, body)for success.
Swagger / OpenAPI
Swagger annotations (go-swagger) are sprinkled across handler comments. make swagger-gen aggregates these into:
public/api-merged.json— full merged spec.public/api-spec.json— OSS-only.
The aggregated spec is used by @grafana/api-clients to generate TypeScript clients (yarn generate-apis).
App-platform endpoints
Newer code routes through the apiserver instead of pkg/api/. The shape:
- A resource is declared in
apps/<name>/kinds/(CUE). - Codegen produces Go types and (in
apps/<name>/pkg/apis/) the Kubernetes-style group/version/resource registration. - The aggregator (
pkg/aggregator/) andpkg/services/apiserver/make the resource available under/apis/<group>/<version>/<resource>.
For consumers, both the legacy /api/... paths and the new /apis/... paths coexist and may serve overlapping data — see Unified storage for how the two layers interact.
Key source files
| File | Purpose |
|---|---|
pkg/api/api.go |
Route table — single source of truth for all legacy endpoints |
pkg/api/http_server.go |
HTTPServer dependencies struct |
pkg/api/routing/ |
RouteRegister abstraction |
pkg/api/response/response.go |
Response helpers |
pkg/api/apierrors/ |
Typed-error → status mapping |
pkg/middleware/middleware.go |
Middleware chain |
pkg/services/contexthandler/contexthandler.go |
Auth dispatcher / *ReqContext builder |
Where to start when modifying the API
- Add a new endpoint to an existing resource: edit the resource's
.gofile inpkg/api/, add toapi.go, write the test, regenerate Swagger. - Add a new resource entirely: prefer creating a new app under
apps/<name>/with CUE schemas andmake gen-apps— this is the future direction. - Change a request DTO: update
pkg/api/dtos/, thenmake swagger-genand (if a TS client uses it)yarn generate-apis.
Built by Factory AutoWiki from public repository content. It is a generated preview for codebase exploration, not source-maintained documentation.
Previous
Backend
Next
Services