mirror of
https://github.com/hanzoai/base.git
synced 2026-10-21 03:41:50 +00:00
One path: /v1/*. We do not use /api/ — that's Casdoor's path. The
BASE_API_PREFIX env knob is gone; the prefix is hard-coded in
apis/base.go and apis/serve.go banner.
Server-side mounts:
- apis: bindHealthApi, bindCollectionApi, bindRecordCrudApi, etc. all
attach under r.Group("/v1") (was r.Group(BASE_API_PREFIX, default /api))
- platform plugin: /api/platform/* -> /v1/platform/* (including auth and
org sub-groups)
- kms plugin: /api/kms/* -> /v1/kms/*
- functions plugin: /api/functions/* -> /v1/functions/*
- cloudsql plugin: /api/cloud-sql/*, /api/meta/* -> /v1/*
- superuser OIDC: /_/api/oidc/config -> /_/v1/oidc/config
- core settings: default RateLimitRule labels /api/batch, /api/ ->
/v1/batch, /v1/
- apis/batch.go: ValidBatchActions regexes match /v1/collections/*;
internal rewrite targets /v1/collections/* (was /v1/base/collections/*,
a stale artifact)
Clients:
- sdk/base-js (BaseClient.collections, files, realtime, CRDT WS,
signIn/refresh/health) targets /v1/*
- sdk/base-react (use-crdt WS path) targets /v1/crdt
- ui-react admin (lib/api.ts, settings.application copy) targets /v1/*
- cmd/cli (NewClient.APIPrefix) defaults to /v1; client_test.go and
cmd/cli_test.go stubServer use /v1/*
- cmd/typegen calls /v1/collections
Upstream paths untouched: Casdoor IAM (/api/login, /api/userinfo,
/api/signup, /api/send-verification-code, /api/get-user), KMS Infisical
(/api/v1/auth/universal-auth/login, /api/v2/workspace/environments),
Kubernetes tasks (/api/v1/namespaces/...), IPFS (/api/v0/...), Gitea/
GitLab/Discord/Strava/Patreon/Box/Wakatime upstream APIs. Those are
their contracts, not ours.
Tests: all 437 prior /api/ test URLs across apis/*_test.go and
plugins/platform/auth_proxy_test.go updated to /v1/. Build + go vet
clean. ./apis ./core ./plugins/platform ./plugins/jsvm ./forms all
green. Pre-existing red probes (network/TestRedProbe_*,
migratecmd/TestAutomigrateCollection*) unchanged.
59 lines
1.6 KiB
Go
59 lines
1.6 KiB
Go
package apis
|
||
|
||
import (
|
||
"net/http"
|
||
"slices"
|
||
|
||
"github.com/hanzoai/base/core"
|
||
"github.com/hanzoai/base/tools/router"
|
||
)
|
||
|
||
// BindHealthzRoute registers health check endpoints.
|
||
// /healthz at root (platform standard) and /health under the API group.
|
||
func BindHealthzRoute(rg *router.Router[*core.RequestEvent]) {
|
||
rg.GET("/healthz", healthCheck)
|
||
}
|
||
|
||
// bindHealthApi registers /v1/health.
|
||
func bindHealthApi(app core.App, rg *router.RouterGroup[*core.RequestEvent]) {
|
||
rg.GET("/health", healthCheck)
|
||
}
|
||
|
||
// healthCheck returns a 200 OK response if the server is healthy.
|
||
func healthCheck(e *core.RequestEvent) error {
|
||
resp := struct {
|
||
Message string `json:"message"`
|
||
Code int `json:"code"`
|
||
Data map[string]any `json:"data"`
|
||
}{
|
||
Code: http.StatusOK,
|
||
Message: "API is healthy.",
|
||
}
|
||
|
||
if e.HasSuperuserAuth() {
|
||
resp.Data = make(map[string]any, 3)
|
||
resp.Data["canBackup"] = !e.App.Store().Has(core.StoreKeyActiveBackup)
|
||
resp.Data["realIP"] = e.RealIP()
|
||
|
||
// loosely check if behind a reverse proxy
|
||
// (usually used in the dashboard to remind superusers in case deployed behind reverse-proxy)
|
||
possibleProxyHeader := ""
|
||
headersToCheck := append(
|
||
slices.Clone(e.App.Settings().TrustedProxy.Headers),
|
||
// common proxy headers
|
||
"CF-Connecting-IP", "Fly-Client-IP", "X‑Forwarded-For",
|
||
)
|
||
for _, header := range headersToCheck {
|
||
if e.Request.Header.Get(header) != "" {
|
||
possibleProxyHeader = header
|
||
break
|
||
}
|
||
}
|
||
resp.Data["possibleProxyHeader"] = possibleProxyHeader
|
||
} else {
|
||
resp.Data = map[string]any{} // ensure that it is returned as object
|
||
}
|
||
|
||
return e.JSON(http.StatusOK, resp)
|
||
}
|