grafana/grafana
Unified storage / app-platform
Grafana is migrating its data model from per-domain SQL tables (driven by pkg/services/sqlstore/) to a Kubernetes-style "resource" model served by an API server. This is called the app-platform or unified storage layer.
What lives where
| Concern | Legacy | New |
|---|---|---|
| Storage | pkg/services/sqlstore/ (xorm) |
pkg/storage/unified/ (resource server) |
| API surface | pkg/api/ (REST handlers) |
pkg/services/apiserver/ (Kubernetes apiserver) |
| Resource definitions | scattered Go structs | apps/<name>/kinds/ (CUE) |
| Generated types | hand-written Go structs | make gen-apps outputs |
| Routing | pkg/api/api.go route table |
/apis/<group>/<version>/<resource> aggregator |
Why
- Schema-driven — CUE definitions in
kinds/are the single source of truth and generate Go + TS + OpenAPI. - Versioning — Kubernetes-style group/version/kind makes schema evolution explicit (
v0alpha1→v1→v2alpha1→v2beta1→v2). - Multi-tenancy primitives — the apiserver naturally namespaces resources, so OSS, Cloud, and Enterprise can use the same API surface with different scoping.
- Ecosystem — kubectl-like clients, controllers, and operators become possible (see
pkg/operators/and the Grafana App SDK).
Layout
pkg/apis/ # k8s group/version manifests living in pkg/
pkg/apimachinery/ # Shared k8s helpers (meta, watch, etc.)
pkg/apiserver/ # apiserver scaffolding
pkg/aggregator/ # k8s aggregator-style routing
pkg/services/apiserver/ # DI integration with Grafana server
pkg/storage/unified/ # Resource server (gRPC) — the persistence layer
pkg/storage/secret/ # Secret resource backend
apps/<name>/ # Per-app modules (resources + storage adapters)Resource server
pkg/storage/unified/resource/ defines the ResourceServer gRPC service: get, list, watch, create, update, delete on resources, plus search, history, and snapshot operations. Implementations in pkg/storage/unified/sql/ back the resource server with the existing relational database (so OSS deployments still need only one DB).
Per-app code
Each apps/<name>/ is its own Go module with:
kinds/— CUE schemas declaring the resource (name, version, spec, status).pkg/apis/<group>/<version>/— generated Go types + apiserver registration.pkg/storage/— adapter from the resource server interface to the legacy SQL table (when a resource is dual-written).pkg/migration/— schema conversion between versions.Makefileandgen-appsintegration.
The largest app today is apps/dashboard/, which manages dashboards across multiple coexisting schema versions and contains the v1 ↔ v2 conversion code.
Dual write
During migration, many resources are stored in both the legacy SQL table and the unified resource server. A "dual writer" wraps the new path so writes go to both places and reads can fall back. See apps/<name>/pkg/storage/dualwrite.go (where present).
The dual-write feature is gated by feature flags (grafanaAPIServer* family in pkg/services/featuremgmt/registry.go).
Aggregator
pkg/aggregator/ implements an extension-point aggregator inspired by kube-aggregator. It lets enterprise builds and external operators plug in additional API groups without touching the OSS source.
Search
The unified resource server has its own search index (built from resource events) implemented under pkg/storage/unified/search/. Long-term this replaces the dashboards search store; today it coexists.
Frontend
The frontend mostly still talks to the legacy /api/... endpoints, but is gradually adopting /apis/... calls — typically through @grafana/api-clients (generated TypeScript clients from the OpenAPI spec).
Key source files
| File | Purpose |
|---|---|
pkg/services/apiserver/service.go |
apiserver lifecycle inside Grafana server |
pkg/storage/unified/resource/ |
Resource gRPC service |
pkg/storage/unified/sql/ |
SQL backend for the resource server |
pkg/aggregator/ |
API aggregator |
apps/dashboard/pkg/migration/conversion/ |
Dashboard schema conversion |
apps/folder/ |
Folder resource |
apps/iam/ |
Identity & access resources |
See also
- Apps lens — per-app deep dives.
- SQL store and migrations — the legacy storage layer.
Built by Factory AutoWiki from public repository content. It is a generated preview for codebase exploration, not source-maintained documentation.