geoserver

package module
v2.0.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: May 4, 2026 License: MIT Imports: 41 Imported by: 0

README ΒΆ

geoserver/v2

Go Reference CI Integration tests GitHub Release

πŸš€ v2.0.0 is published β€” first stable release. v2 covers the gap-analysis plan's "everyone needs it" surface, every tier-2 item from ../docs/v2-tier2-gaps.md, plus four longer-tail surfaces (fonts, password rotation, GWC additions, monitoring). Public API is locked; no breaking changes will land in v2.x. Coverage:

  • Catalog: workspaces, datastores, feature types, coverage stores, coverages, layers (incl. add-style sub-resource), layer groups, styles, namespaces. Fonts: c.Fonts.List (JVM-exposed font families).
  • Settings: global c.Settings + per-service c.Services.WMS()/WFS()/WCS()/WMTS() (global + per-workspace overrides).
  • System: c.System.Reload and ResetCache. About: ping, version, manifests, system status. Logging: c.Logging.Get/Update for runtime log-level changes. Monitoring (gs-monitor ext baked into dev/test image): c.Monitor.List/ListRaw/Get for the request audit log.
  • Security: users, groups, roles, role-user assignment + ACL Layers()/Services()/REST()/Catalog() + auth providers / filters / filter chains + URL checks (SSRF allow-list) + c.Security.MasterPassword (keystore) + c.Security.SelfPassword (auth'd user rotation).
  • Resources: c.Resources Get / List / Stat / Exists / Put / Move / Copy / Delete against /rest/resource/{path} β€” read or write any file in the data dir. Templates (FTL): c.Templates global + six fluent scopes.
  • File-upload publishing: c.Datastores.UploadFile (Shapefile / GeoPackage / external) and c.CoverageStores.UploadFile + HarvestGranule (GeoTIFF / ImageMosaic / mosaic granules).
  • Mosaic granules: c.Coverages.InWorkspace(ws).InCoverageStore(cs).Granules(cov) β€” Schema / List / Get / Delete / DeleteByFilter for image-mosaic / structured coverages.
  • Cascaded stores + layers: c.WMSStores / c.WMSLayers / c.WMTSStores / c.WMTSLayers for federation / proxy setups.
  • GeoWebCache: c.GWC.Layers() (cache config), Seed() (seed/reseed/truncate), DiskQuota(), Global() (singleton config), Gridsets() (named tile-matrix sets), MassTruncate() (bulk cache invalidation).
  • Importer extension: c.Imports (sessions + tasks). The dev/test docker image bakes the plugin in for CI integration coverage.
  • OWS: c.WMS / c.WFS / c.WCS GetCapabilities; WFS DescribeFeatureType; WCS DescribeCoverage. WFS XSLT transforms: c.WFSTransforms β€” surface preserved for legacy / custom builds; the gs-xslt-wfs extension was removed from upstream in 2.24 and is not shipped for 2.27 / 2.28.

Surface is locked β€” no breaking changes will land in v2.x. v1.x is end-of-feature; security patches only on the release/v1 branch (post-restructure). New integrations should target v2.

This module ships with its own go.mod at /v2/; v1 and v2 release independently (v1.x.y / v2.x.y tags).

Contents

Install

go get github.com/hishamkaram/geoserver/v2@v2.0.0
import geoserver "github.com/hishamkaram/geoserver/v2"

v2 is a separate Go module under /v2/; v1 and v2 release independently (v1.x.y / v2.x.y tags). v2 is the recommended line for new integrations.

Requirements: Go 1.25+. Tested against GeoServer 2.27.4 LTS and 2.28.0 stable on every PR.

Why v2 over v1?

If you're starting a new integration today, v2 is the better foundation. It gives you:

  • Sub-clients per resource. c.Workspaces.Get(ctx, name), c.Datastores.InWorkspace(ws).Create(ctx, ...), c.FeatureTypes.InWorkspace(ws).InDatastore(ds).Discover(ctx, ...) β€” instead of v1's monolithic ~90-method *GeoServer.
  • Immutable client; concurrency-safe by construction. All fields private; configured via functional options at construction; no post-construction mutation. Auth is layered on as an http.RoundTripper so OpenTelemetry, Vault-rotated creds, and retry libs compose naturally.
  • Mandatory context.Context first arg on every method. No Background() shims, no twin pairs.
  • iter.Seq2 pagination on every List endpoint. for ws, err := range c.Workspaces.Iter(ctx, opts) { ... }.
  • Surfaces v1 doesn't have β€” per-service OWS settings (c.Services.WMS()/WFS()/WCS()/WMTS()), file-upload publishing on stores (c.Datastores.UploadFile, c.CoverageStores.UploadFile/HarvestGranule), GeoWebCache (c.GWC.Layers()/Seed()/DiskQuota()), the Importer extension (c.Imports), the Resource API (c.Resources), the full ACL surface (c.ACL.Layers()/Services()/REST()/Catalog()), WFS DescribeFeatureType, and WCS DescribeCoverage.

If you're already on v1 and don't need any of the above, there is no rush β€” v1.x is non-breaking and continues to receive security and bug-fix patches. See ../docs/migration-v1-to-v2.md for the per-resource migration mapping.

Design tenets

v2 breaks v1's monolithic *GeoServer surface into a sub-client per resource, with a few lock-in decisions documented in ../ROADMAP.md:

  • Immutable *Client. All fields private; no post-construction mutation. Concurrent use is safe.
  • Mandatory context.Context as first arg on every public method. No Background shims.
  • Sub-client pattern. c.Workspaces.List(ctx, opts) instead of v1's gs.GetWorkspacesContext(ctx).
  • Single error type (*APIError) with package sentinels (ErrNotFound, ErrConflict, …). errors.Is and errors.As are the supported match styles.
  • Auth via http.RoundTripper. Basic / bearer auth attaches at construction; per-call paths don't re-authenticate. Custom RoundTrippers (OpenTelemetry, Vault-rotated creds, retry libs) layer naturally.
  • Pagination via iter.Seq2. c.Workspaces.Iter(ctx, opts) returns a iter.Seq2[Workspace, error]. Non-paginating endpoints fall back to single-page Seq2.
  • Zero runtime third-party deps. stdlib net/http, encoding/json, encoding/xml, log/slog, context, iter only.

Quick start

package main

import (
    "context"
    "errors"
    "fmt"
    "log/slog"
    "os"
    "time"

    geoserver "github.com/hishamkaram/geoserver/v2"
    "github.com/hishamkaram/geoserver/v2/rest/workspaces"
)

func main() {
    c, err := geoserver.New("http://localhost:8080/geoserver/",
        geoserver.WithBasicAuth("admin", "geoserver"),
        geoserver.WithTimeout(10*time.Second),
        geoserver.WithLogger(slog.New(slog.NewTextHandler(os.Stderr, nil))),
    )
    if err != nil {
        panic(err)
    }

    ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
    defer cancel()

    list, err := c.Workspaces.List(ctx, workspaces.ListOptions{})
    if err != nil {
        panic(err)
    }
    for _, ws := range list {
        fmt.Println(ws.Name)
    }

    _, err = c.Workspaces.Get(ctx, "doesnotexist")
    if errors.Is(err, geoserver.ErrNotFound) {
        fmt.Println("workspace doesn't exist")
    }
}
Workspace-scoped resources

Resources nested under a workspace (datastores, feature types, coverages, …) are accessed via an InWorkspace scope:

import "github.com/hishamkaram/geoserver/v2/rest/datastores"

ds := c.Datastores.InWorkspace("topp")

_ = ds.Create(ctx, datastores.PostGIS{
    Name: "states", Host: "db", Port: 5432, Database: "gis",
    User: "u", Password: "p",
})

stores, _ := ds.List(ctx, datastores.ListOptions{})
_ = ds.Delete(ctx, "states", datastores.DeleteOptions{Recurse: true})
2-level scoped resources (feature types, coverages)

Resources nested under both a workspace and a parent store drill in through two In… calls:

import "github.com/hishamkaram/geoserver/v2/rest/featuretypes"

ft := c.FeatureTypes.InWorkspace("topp").InDatastore("states_pg")

// Discover tables in the datastore not yet configured.
names, _ := ft.Discover(ctx, featuretypes.DiscoverOptions{
    Kind: featuretypes.DiscoverAvailableWithGeometry,
})

// Publish one of them as a feature type.
_ = ft.Create(ctx, &featuretypes.FeatureType{
    Name: "states", NativeName: "states",
    SRS: "EPSG:4326", Enabled: true,
})

The same shape applies to coverages under a coverage store (raster side):

import "github.com/hishamkaram/geoserver/v2/rest/coverages"

cov := c.Coverages.InWorkspace("ne").InCoverageStore("states_tiff")

// Publish a configured coverage from the underlying GeoTIFF.
_ = cov.Create(ctx, &coverages.Coverage{
    Name: "states_published", NativeCoverageName: "states.tif",
})

Runnable examples

The examples/ directory contains self-contained main packages demonstrating each idiom:

  • workspaces/ β€” flat sub-client CRUD; errors.Is matching.
  • publish-postgis/ β€” end-to-end workspace β†’ datastore β†’ feature type β†’ layer flow with the hierarchical sub-clients.
  • style-upload/ β€” two-step style publish via Create + UploadSLD.
  • error-handling/ β€” full sentinel set + *APIError inspection via errors.As.

Run any with go run ./v2/examples/<name> against a make compose-up stack, or compile-check all with make examples-v2.

Resource status

Resource v1 v2
Workspaces full ported (flat; c.Workspaces)
Datastores full ported (workspace-scoped; c.Datastores.InWorkspace(ws))
Feature types full ported (2-level hierarchy; c.FeatureTypes.InWorkspace(ws).InDatastore(ds))
Coverage stores full ported (workspace-scoped; c.CoverageStores.InWorkspace(ws))
Coverages full ported (2-level hierarchy; c.Coverages.InWorkspace(ws).InCoverageStore(cs))
Layers full ported + new add-style sub-resource (c.Layers.InWorkspace(ws).AddStyle/ListStyles)
Layer groups full ported (c.LayerGroups.InWorkspace(ws))
Styles full ported (global + workspace scope; UploadSLD for body upload)
Namespaces full ported (c.Namespaces)
Global settings full ported (c.Settings.Get / Update)
Per-service OWS settings (none) new in v2 (c.Services.WMS() / WFS() / WCS() / WMTS() β€” global + per-workspace overrides)
System (reload + cache reset) full ported (c.System.Reload, ResetCache)
About full ported (c.About.Ping, c.About.Version)
Security (users, groups, roles) full ported (c.Security.Users(), Groups(), Roles)
ACL β€” layer rules full ported (c.ACL.Layers())
ACL β€” service / REST / catalog rules partial ported in v2 (c.ACL.Services(), c.ACL.REST(), c.ACL.Catalog()) β€” REST DELETE has documented firewall caveat
Resource API (data-dir byte-stream access) (none) new in v2 (c.Resources Get/List/Stat/Exists/Put/Move/Copy/Delete)
File-upload publishing on stores (none) new in v2 (c.Datastores.UploadFile, c.CoverageStores.UploadFile / HarvestGranule)
GeoWebCache (cache config + seed + diskquota) (none) new in v2 (c.GWC.Layers(), Seed(), DiskQuota(), Global(), Gridsets(), MassTruncate())
Importer extension (batch ingest) (none) new in v2 (c.Imports; dev/test docker image bakes the plugin in)
WMS GetCapabilities full ported (c.WMS.GetCapabilities + InWorkspace)
WFS GetCapabilities + DescribeFeatureType (none β€” WMS only) new in v2 (c.WFS.GetCapabilities, DescribeFeatureType)
WCS GetCapabilities + DescribeCoverage (none β€” WMS only) new in v2 (c.WCS.GetCapabilities, DescribeCoverage)
Mosaic / structured-coverage granules (none) new in v2 (c.Coverages.InWorkspace(ws).InCoverageStore(cs).Granules(cov) β€” Schema / List / Get / Delete / DeleteByFilter)
FTL templates (none) new in v2 (c.Templates + six fluent scopes; List / Get / Put / Delete)
Auth providers / filters / chains (none) new in v2 (c.Security.AuthProviders, AuthFilters, FilterChains)
URL checks (SSRF allow-list) (none) new in v2 (c.URLChecks)
Cascaded WMS / WMTS stores + layers (none) new in v2 (c.WMSStores, c.WMSLayers, c.WMTSStores, c.WMTSLayers)
WFS XSLT transforms (none) new in v2 (c.WFSTransforms) β€” surface preserved for legacy / custom builds; the gs-xslt-wfs extension was removed from upstream in 2.24 and is not shipped for 2.27 / 2.28
About β€” manifests + system status (none) new in v2 (c.About.Manifests, c.About.SystemStatus)
Logging (runtime log-level config) (none) new in v2 (c.Logging.Get / Update)
Fonts list (none) new in v2 (c.Fonts.List)
Master password & self password (none) new in v2 (c.Security.MasterPassword.Get/Update, c.Security.SelfPassword.Change)
Monitoring (request audit log) (none) new in v2 (c.Monitor.List/ListRaw/Get; dev/test docker image bakes the gs-monitor plugin in)

See ../ROADMAP.md for the milestone checklist. The original tier-2 gap-analysis backlog is closed and the longer-tail surfaces above are also done; remaining longer-tail endpoints (opensearch-eo is community / SNAPSHOT-only on 2.27 / 2.28; revisit when stable) are tracked in ../docs/v2-tier2-gaps.md.

Contributing to v2

The "everyone needs it" surface and the tier-2 backlog are both closed; remaining work is the longer-tail list above plus wire-quirk fixes when adopters report them.

To add a new sub-client:

  1. Pick a reference pattern that matches the shape:
    • Flat CRUD: rest/workspaces/, rest/namespaces/.
    • Workspace-scoped: rest/datastores/, rest/coveragestores/, rest/layers/.
    • 2-level hierarchy: rest/featuretypes/, rest/coverages/.
    • Generic-typed dispatch: rest/services/ (per-service WMS/WFS/WCS/WMTS).
    • Out-of-/rest/ URL prefix: rest/gwc/ (paths under /gwc/rest/).
    • XML wire format: ows/wms/, ows/wfs/, ows/wcs/.
  2. Define types.go β€” wire-format request/response structs, public option types, custom (Un)MarshalJSON for any wire quirks.
  3. Define <resource>.go β€” type Client struct{ core Core }, func New(core Core), methods. Each subpackage's Core interface declares only the transport methods it actually uses (Do / DoXML / DoRaw / DoStream); add only what's needed.
  4. Define <resource>_test.go (httptest unit tests) and <resource>_integration_test.go with the //go:build integration tag.
  5. Wire into *Client in ../geoserver.go.

Run integration tests locally before push. make compose-up && cd v2 && go test -tags=integration ./rest/<resource>/. CI's wire-format coverage runs on real GeoServer 2.27.4 LTS + 2.28.0 stable, but local-first catches quirks faster.

The Core interface in each subpackage is the abstraction over the parent *Client's plumbing β€” it lets sub-clients issue requests without importing the root package (which would create an import cycle).

See ../CONTRIBUTING.md for the general PR workflow and ../docs/migration-v1-to-v2.md for the v1 β†’ v2 migration guide.

Documentation ΒΆ

Overview ΒΆ

Package geoserver is a Go client for the GeoServer REST API (v2 line).

Status ΒΆ

v2 has full v1 feature parity at master and exceeds it. The package covers every "everyone needs it" endpoint group identified in the gap analysis: catalog (workspaces, datastores, feature types, coverage stores, coverages, layers, layer groups, styles, namespaces), settings, system (reload + cache reset), about, security (users / groups / roles + layer ACL), per-service OWS configuration (WMS / WFS / WCS / WMTS), file-upload publishing on stores, layer–style associations, GeoWebCache (per-layer cache config + seed/reseed/truncate + diskquota), the Importer extension (batch ingest), and the OWS read-only trio (GetCapabilities + DescribeFeatureType + DescribeCoverage).

Public API is stable as of v2.0.0 β€” no breaking changes will land in v2.x. v2 is the recommended line for new integrations; v1 is end-of-feature on the release/v1 branch (security patches only):

import "github.com/hishamkaram/geoserver/v2"     // v2: stable
import "github.com/hishamkaram/geoserver"        // v1: end-of-feature

See ../ROADMAP.md for the v2 milestones and ../docs/migration-v1-to-v2.md for the v1 β†’ v2 migration guide.

Design tenets ΒΆ

v2 is a clean redesign that breaks v1's monolithic *GeoServer surface into a sub-client per resource:

  • Immutable *Client. All fields private. Configured via functional options at construction; no post-construction mutation. Concurrent use is safe.
  • Mandatory context.Context as first arg on every public method. No Background shims, no twin pairs.
  • Sub-client pattern. Public fields like (*Client).Workspaces and (*Client).Datastores expose typed per-resource clients with consistent List / Get / Create / Update / Delete / Iter shapes. Hierarchical resources fluently chain through scope β€” c.Datastores.InWorkspace("topp"), c.FeatureTypes.InWorkspace(ws).InDatastore(ds).
  • Single error type. Every HTTP error is a *APIError wrapping one of the package sentinels (ErrNotFound, ErrConflict, …) so errors.Is and errors.As are the supported match styles.
  • Auth via http.RoundTripper. Basic / bearer auth attaches to the transport layer once at construction; per-call paths don't re-authenticate. Custom RoundTrippers (OpenTelemetry, retry libs, Vault-rotated creds) layer naturally.
  • Streaming uploads. Resources that accept binary payloads take io.Reader and never slurp into memory.
  • Pagination via iter.Seq2. List endpoints expose Iter for range-over-func; non-paginating endpoints fall back to a single-page Seq2.
  • Zero runtime third-party dependencies. stdlib net/http, encoding/json, encoding/xml, log/slog, context, iter only. Test deps allowed.

Quick start ΒΆ

c, err := geoserver.New("http://localhost:8080/geoserver/",
    geoserver.WithBasicAuth("admin", "geoserver"),
    geoserver.WithTimeout(10*time.Second),
)
if err != nil {
    return err
}

ctx := context.Background()
wss, err := c.Workspaces.List(ctx, workspaces.ListOptions{})
if errors.Is(err, geoserver.ErrUnauthorized) {
    // handle bad credentials
}
Example (ErrorHandling) ΒΆ

Example_errorHandling shows the two idiomatic ways to inspect a returned error: errors.Is against the package sentinels for status-code matching, and errors.As to a *geoserver.APIError for the full request context.

package main

import (
	"context"
	"errors"
	"fmt"

	geoserver "github.com/hishamkaram/geoserver/v2"
)

func main() {
	c, _ := geoserver.New("http://localhost:8080/geoserver",
		geoserver.WithBasicAuth("admin", "geoserver"))

	_, err := c.Workspaces.Get(context.Background(), "no-such-workspace")
	switch {
	case err == nil:
		// found
	case errors.Is(err, geoserver.ErrNotFound):
		fmt.Println("not found β€” create it instead")
	case errors.Is(err, geoserver.ErrUnauthorized):
		fmt.Println("credentials rejected")
	default:
		// Inspect the typed error for diagnostics.
		var apiErr *geoserver.APIError
		if errors.As(err, &apiErr) {
			fmt.Printf("%s %s -> %d\n", apiErr.Method, apiErr.URL, apiErr.StatusCode)
		}
	}
}

Index ΒΆ

Examples ΒΆ

Constants ΒΆ

This section is empty.

Variables ΒΆ

View Source
var (
	ErrBadRequest           = errors.New("geoserver: bad request")
	ErrUnauthorized         = errors.New("geoserver: unauthorized")
	ErrForbidden            = errors.New("geoserver: forbidden")
	ErrNotFound             = errors.New("geoserver: not found")
	ErrMethodNotAllowed     = errors.New("geoserver: method not allowed")
	ErrConflict             = errors.New("geoserver: conflict")
	ErrUnsupportedMediaType = errors.New("geoserver: unsupported media type")
	ErrRateLimited          = errors.New("geoserver: rate limited")
	ErrServerError          = errors.New("geoserver: internal server error")
	ErrBadGateway           = errors.New("geoserver: bad gateway")
	ErrServiceUnavailable   = errors.New("geoserver: service unavailable")
	ErrGatewayTimeout       = errors.New("geoserver: gateway timeout")
)

Sentinel errors. APIError.Is wraps these so callers can match status codes via errors.Is(err, ErrNotFound) etc.

The set mirrors v1's sentinel list; the Error type itself is renamed (v1: *Error β†’ v2: *APIError) and tightened β€” v2 does not preserve v1's "abstract:%s\ndetails:%s\n" format because v2 is a clean break.

Functions ΒΆ

This section is empty.

Types ΒΆ

type APIError ΒΆ

type APIError struct {
	// Op identifies the public operation that produced the error
	// (e.g., "Workspaces.Create"). Set by the resource-client
	// wrapper. Useful for logging.
	Op string

	// URL is the request URL.
	URL string

	// Method is the HTTP method.
	Method string

	// StatusCode is the HTTP status code from GeoServer.
	StatusCode int

	// Body is the response body, truncated to a fixed cap (8 KiB)
	// to avoid unbounded retention. Useful for diagnostics; do not
	// parse for control flow β€” use errors.Is against the package
	// sentinels instead.
	Body []byte
}

APIError represents a non-2xx response from GeoServer. The single error type for the v2 module β€” every wire-level failure surfaces as *APIError so callers can match either by sentinel (errors.Is) or by inspecting fields (errors.As).

func (*APIError) Error ΒΆ

func (e *APIError) Error() string

Error returns a stable, parseable message of the form

geoserver: <Op> <Method> <URL>: <statusCode> <statusText>: <body-preview>

Body preview is truncated to ~120 bytes.

func (*APIError) HTTPStatusCode ΒΆ

func (e *APIError) HTTPStatusCode() int

HTTPStatusCode returns the HTTP status code that produced the error. A stable accessor (in addition to the APIError.StatusCode field) so sub-clients in v2/rest/* can branch on the status without importing the root package β€” that would create an import cycle since the root imports each rest/<resource>.

func (*APIError) Is ΒΆ

func (e *APIError) Is(target error) bool

Is reports whether target matches the sentinel for this APIError's status code. Lets callers use errors.Is(err, ErrNotFound) directly on an *APIError.

func (*APIError) Unwrap ΒΆ

func (e *APIError) Unwrap() error

Unwrap returns the sentinel for this status code, enabling errors.Is.

type Client ΒΆ

type Client struct {

	// Workspaces is the entry point for workspace operations.
	Workspaces *workspaces.Client

	// Datastores is the entry point for datastore operations. Datastore
	// operations are workspace-scoped β€” see [datastores.Client.InWorkspace].
	Datastores *datastores.Client

	// FeatureTypes is the entry point for feature-type operations.
	// Feature-type operations are 2-level scoped β€” see
	// [featuretypes.Client.InWorkspace] and [featuretypes.WorkspaceClient.InDatastore].
	FeatureTypes *featuretypes.Client

	// CoverageStores is the entry point for coverage-store operations.
	// Coverage-store operations are workspace-scoped β€” see
	// [coveragestores.Client.InWorkspace].
	CoverageStores *coveragestores.Client

	// Coverages is the entry point for coverage operations. Coverage
	// operations are 2-level scoped β€” see [coverages.Client.InWorkspace]
	// and [coverages.WorkspaceClient.InCoverageStore].
	Coverages *coverages.Client

	// Layers is the entry point for layer operations. Layer operations
	// are workspace-scoped β€” see [layers.Client.InWorkspace].
	Layers *layers.Client

	// LayerGroups is the entry point for layer-group operations.
	// Layer-group operations are workspace-scoped β€” see
	// [layergroups.Client.InWorkspace].
	LayerGroups *layergroups.Client

	// Styles is the entry point for style operations. The client
	// operates against the global /rest/styles endpoint by default;
	// use [styles.Client.InWorkspace] for a workspace-scoped client.
	Styles *styles.Client

	// Namespaces is the entry point for namespace operations.
	// Namespaces are flat under /rest/namespaces.
	Namespaces *namespaces.Client

	// Settings is the entry point for the singleton global-settings
	// document β€” Get / Update against /rest/settings.
	Settings *settings.Client

	// About is the entry point for server health and version info β€”
	// Ping (liveness check) and Version (full component versions).
	About *about.Client

	// Security is the entry point for users, groups, roles, and
	// user-role assignment under /rest/security. See
	// [security.Client] for the nested sub-client surface.
	Security *security.Client

	// ACL is the entry point for access-control-list rules under
	// /rest/security/acl. Currently exposes layer ACLs via
	// [acl.Client.Layers]; service-level and catalog-level ACL
	// endpoints can be added in follow-up PRs.
	ACL *acl.Client

	// System is the entry point for server-management operations β€”
	// Reload (catalog + configuration from disk) and ResetCache
	// (store / raster / schema caches). Both require admin auth.
	System *system.Client

	// WMS is the entry point for WMS service operations β€” currently
	// GetCapabilities (XML, decoded into [wms.Capabilities]). Use
	// [wms.Client.InWorkspace] for a workspace-scoped capabilities
	// document.
	WMS *wms.Client

	// WFS is the entry point for WFS service operations β€” currently
	// GetCapabilities (XML, decoded into [wfs.Capabilities]). Use
	// [wfs.Client.InWorkspace] for a workspace-scoped capabilities
	// document.
	WFS *wfs.Client

	// WCS is the entry point for WCS service operations β€” currently
	// GetCapabilities (XML, decoded into [wcs.Capabilities]). Use
	// [wcs.Client.InWorkspace] for a workspace-scoped capabilities
	// document.
	WCS *wcs.Client

	// Imports is the entry point for the GeoServer Importer
	// extension at /rest/imports β€” bulk-ingest sessions for batch
	// publishing, migrations, and drop-and-republish workflows.
	// The extension is NOT installed by default; calls to a
	// GeoServer without it return ErrNotFound.
	Imports *imports.Client

	// GWC is the entry point for GeoWebCache REST endpoints β€”
	// per-layer cache config, seed/reseed/truncate tasks, and
	// disk-quota policy. Lives at /gwc/rest/ (outside the /rest/
	// catalog tree). Reach the typed sub-clients via
	// `c.GWC.Layers()`, `Seed()`, `DiskQuota()`.
	GWC *gwc.Client

	// Services is the entry point for per-service OWS configuration
	// (`/services/{wms,wfs,wcs,wmts}/settings`). Reach the typed
	// per-service clients via `c.Services.WMS()`, `WFS()`, `WCS()`,
	// `WMTS()`. Each exposes `Get`/`Update` for global settings and
	// `.InWorkspace(ws)` for per-workspace overrides (`Get`/`Update`/`Delete`).
	Services *services.Client

	// Resources is the entry point for the GeoServer Resource API at
	// /rest/resource/{path} β€” generic byte-stream access to files
	// in the GeoServer data directory. Daily-driver methods cover
	// reading file contents, listing directories, uploading new
	// resources (FTL templates, SLD includes, icons), moving /
	// copying files, and recursive deletion.
	Resources *resources.Client

	// Templates is the entry point for FreeMarker (FTL) templates
	// that customize GetFeatureInfo HTML output, WMS HTML
	// capabilities, and other text outputs. Six scope levels are
	// supported β€” global, per workspace, per datastore, per feature
	// type, per coverage store, per coverage β€” via fluent
	// `c.Templates.InWorkspace(ws).In...()` chains.
	Templates *templates.Client

	// URLChecks is the entry point for URL External Access Checks
	// at /rest/urlchecks. Allow/deny lists for external URL
	// references in styles, mosaics, and remote stores. Used by
	// SSRF-conscious deployments to constrain which off-server
	// URLs GeoServer is permitted to fetch.
	URLChecks *urlchecks.Client

	// WMSStores is the entry point for cascaded WMS stores β€”
	// references to remote WMS servers re-published through this
	// GeoServer instance. Workspace-scoped via
	// `c.WMSStores.InWorkspace(ws)`.
	WMSStores *wmsstores.Client

	// WMSLayers is the entry point for cascaded WMS layers β€”
	// individual remote WMS layers published locally. 2-level
	// scoped: `c.WMSLayers.InWorkspace(ws).InStore(s)` for the
	// canonical CRUD path, `c.WMSLayers.InWorkspace(ws)` for the
	// workspace-wide list / get / delete.
	WMSLayers *wmslayers.Client

	// WMTSStores is the entry point for cascaded WMTS stores.
	// Same scoping pattern as [Client.WMSStores].
	WMTSStores *wmtsstores.Client

	// WMTSLayers is the entry point for cascaded WMTS layers.
	// Same scoping pattern as [Client.WMSLayers].
	WMTSLayers *wmtslayers.Client

	// WFSTransforms is the entry point for XSLT transforms that
	// re-shape WFS GetFeature output (HTML reports, KML, custom XML).
	// The endpoint is part of the gs-xslt-wfs extension; calls
	// against an unequipped GeoServer return ErrNotFound.
	WFSTransforms *wfstransforms.Client

	// Logging is the entry point for the singleton logging
	// configuration document at /rest/logging β€” adjust the active
	// log4j profile (DEFAULT_LOGGING, VERBOSE_LOGGING, etc.) and
	// the stdout-mirror toggle without bouncing the server.
	Logging *logging.Client

	// Fonts is the entry point for the read-only /rest/fonts
	// endpoint β€” list of font families the JVM exposes to GeoServer's
	// SLD labelling pipeline. Sanity-check before publishing styles
	// that reference specific fonts; typos would otherwise surface as
	// silent label-rendering fallbacks.
	Fonts *fonts.Client

	// Monitor is the entry point for the read-only audit log at
	// /rest/monitor/requests, exposed by the gs-monitor extension.
	// The dev/test docker image bakes the extension in; calls
	// against an unequipped GeoServer return ErrNotFound.
	Monitor *monitor.Client
	// contains filtered or unexported fields
}

Client is the v2 GeoServer REST client. All fields are private; the client is configured at construction via Option values and is immutable thereafter. Concurrent use across goroutines is safe.

Resource methods live on sub-clients accessed via the public fields:

Workspaces     β€” workspace CRUD
Datastores     β€” datastore CRUD (workspace-scoped via InWorkspace)
FeatureTypes   β€” feature-type CRUD (workspace+datastore-scoped via InWorkspace().InDatastore())
CoverageStores β€” coverage-store CRUD (workspace-scoped via InWorkspace)
Coverages      β€” coverage CRUD (workspace+coverage-store-scoped via InWorkspace().InCoverageStore())
Layers         β€” layer CRUD (workspace-scoped via InWorkspace)
LayerGroups    β€” layer-group CRUD (workspace-scoped via InWorkspace)
Styles         β€” style metadata + SLD body upload (global by default; .InWorkspace(ws) for workspace-scoped)
Namespaces     β€” namespace CRUD (flat global)
Settings       β€” singleton global settings document (Get / Update)
About          β€” health check + version info (Ping / Version)
Security       β€” users, groups, roles, user-role assignment
ACL            β€” access-control rules (Layers; future: Services, Catalog)
(more sub-clients as resources port; see ROADMAP.md)

func New ΒΆ

func New(serverURL string, opts ...Option) (*Client, error)

New constructs an immutable *Client for the GeoServer instance at serverURL. serverURL must be a valid http:// or https:// URL, with or without a trailing slash. Apply options for HTTP client, auth, timeout, logging, headers.

Returns an error if any option is invalid or serverURL fails to parse β€” misconfiguration surfaces immediately rather than at first-call time.

Example ΒΆ

ExampleNew constructs a Client against a local GeoServer instance. All other configuration (auth, timeout, logging) is layered via geoserver.Option values.

package main

import (
	"time"

	geoserver "github.com/hishamkaram/geoserver/v2"
)

func main() {
	c, err := geoserver.New("http://localhost:8080/geoserver",
		geoserver.WithBasicAuth("admin", "geoserver"),
		geoserver.WithTimeout(10*time.Second),
	)
	if err != nil {
		// In real code: handle the error. New only fails on
		// invalid serverURL or option misconfiguration.
		panic(err)
	}
	_ = c
}
Example (BasicAuth) ΒΆ

ExampleNew_basicAuth shows the typical credential setup for an on-premise GeoServer instance.

package main

import (
	"os"

	geoserver "github.com/hishamkaram/geoserver/v2"
)

func main() {
	_, _ = geoserver.New(
		"https://geoserver.example.com/geoserver",
		geoserver.WithBasicAuth("admin", os.Getenv("GEOSERVER_PASSWORD")),
	)
}
Example (BearerToken) ΒΆ

ExampleNew_bearerToken shows how to authenticate against a GeoServer fronted by an OAuth2 / JWT proxy.

package main

import (
	"os"

	geoserver "github.com/hishamkaram/geoserver/v2"
)

func main() {
	_, _ = geoserver.New(
		"https://geoserver.example.com/geoserver",
		geoserver.WithBearerToken(os.Getenv("GEOSERVER_TOKEN")),
	)
}
Example (Logging) ΒΆ

ExampleNew_logging wires the client's slog handler to text output on stderr at debug level β€” every HTTP request is logged.

package main

import (
	"log/slog"
	"os"

	geoserver "github.com/hishamkaram/geoserver/v2"
)

func main() {
	logger := slog.New(slog.NewTextHandler(os.Stderr, &slog.HandlerOptions{
		Level: slog.LevelDebug,
	}))
	_, _ = geoserver.New(
		"http://localhost:8080/geoserver",
		geoserver.WithLogger(logger),
	)
}

type Option ΒΆ

type Option func(*clientConfig) error

Option configures a *Client at construction. Options are applied in order; later options override earlier ones for the same field.

func WithBasicAuth ΒΆ

func WithBasicAuth(username, password string) Option

WithBasicAuth attaches HTTP basic-auth headers to every request. Mutually exclusive with WithBearerToken; later option wins.

func WithBearerToken ΒΆ

func WithBearerToken(token string) Option

WithBearerToken attaches a bearer token to every request. Mutually exclusive with WithBasicAuth; later option wins.

func WithHTTPClient ΒΆ

func WithHTTPClient(c *http.Client) Option

WithHTTPClient supplies a custom *http.Client. The client's Transport (if any) is wrapped β€” auth and user-agent layers are applied on top. Mutually exclusive with WithTransport; later option wins.

func WithHeader ΒΆ

func WithHeader(key, value string) Option

WithHeader adds a default header sent on every request. Multiple calls accumulate. Authoritative for headers set before request-level overrides apply.

func WithLogger ΒΆ

func WithLogger(l *slog.Logger) Option

WithLogger sets the *slog.Logger the client uses for HTTP-level logging. Default: a discard handler (silent).

func WithTimeout ΒΆ

func WithTimeout(d time.Duration) Option

WithTimeout sets the *http.Client's Timeout. Zero means no timeout (rely on context deadlines instead). Default: 30 seconds.

func WithTransport ΒΆ

func WithTransport(rt http.RoundTripper) Option

WithTransport supplies the base http.RoundTripper for the client's HTTP transport. Auth and user-agent layers wrap this. Mutually exclusive with WithHTTPClient; later option wins.

func WithUserAgent ΒΆ

func WithUserAgent(ua string) Option

WithUserAgent sets the User-Agent header sent on every request. Default: "geoserver-go/v2".

Directories ΒΆ

Path Synopsis
examples
error-handling command
error-handling is a runnable v2 example: demonstrate how to match GeoServer errors with `errors.Is` against package sentinels and inspect the typed *geoserver.APIError via `errors.As`.
error-handling is a runnable v2 example: demonstrate how to match GeoServer errors with `errors.Is` against package sentinels and inspect the typed *geoserver.APIError via `errors.As`.
publish-postgis command
publish-postgis is a runnable v2 example: end-to-end flow that creates a workspace, registers a PostGIS datastore, publishes a feature type, and reads the resulting layer back.
publish-postgis is a runnable v2 example: end-to-end flow that creates a workspace, registers a PostGIS datastore, publishes a feature type, and reads the resulting layer back.
style-upload command
style-upload is a runnable v2 example: register a style's metadata, then upload an SLD body via UploadSLD.
style-upload is a runnable v2 example: register a style's metadata, then upload an SLD body via UploadSLD.
workspaces command
workspaces is a runnable v2 example: list, create, get, and delete a GeoServer workspace using the v2 functional-options constructor and flat *Client.Workspaces sub-client.
workspaces is a runnable v2 example: list, create, get, and delete a GeoServer workspace using the v2 functional-options constructor and flat *Client.Workspaces sub-client.
internal
testenv
Package testenv holds shared helpers for v2 integration tests.
Package testenv holds shared helpers for v2 integration tests.
transport
Package transport contains the HTTP transport algorithms for the v2 GeoServer client.
Package transport contains the HTTP transport algorithms for the v2 GeoServer client.
wire
Package wire holds wire-format types shared across GeoServer v2 resource sub-packages.
Package wire holds wire-format types shared across GeoServer v2 resource sub-packages.
ows
wcs
Package wcs is the v2 sub-client for the GeoServer WCS service.
Package wcs is the v2 sub-client for the GeoServer WCS service.
wfs
Package wfs is the v2 sub-client for the GeoServer WFS service.
Package wfs is the v2 sub-client for the GeoServer WFS service.
wms
Package wms is the v2 sub-client for the GeoServer WMS service.
Package wms is the v2 sub-client for the GeoServer WMS service.
rest
about
Package about is the v2 sub-client for the GeoServer /rest/about/version resource.
Package about is the v2 sub-client for the GeoServer /rest/about/version resource.
acl
Package acl is the v2 sub-client for the GeoServer access-control-list endpoints under /rest/security/acl.
Package acl is the v2 sub-client for the GeoServer access-control-list endpoints under /rest/security/acl.
coverages
Package coverages is the v2 sub-client for the GeoServer /rest/workspaces/{ws}/coveragestores/{cs}/coverages resource.
Package coverages is the v2 sub-client for the GeoServer /rest/workspaces/{ws}/coveragestores/{cs}/coverages resource.
coveragestores
Package coveragestores is the v2 sub-client for the GeoServer /rest/workspaces/{ws}/coveragestores resource.
Package coveragestores is the v2 sub-client for the GeoServer /rest/workspaces/{ws}/coveragestores resource.
datastores
Package datastores is the v2 sub-client for the GeoServer /rest/workspaces/{ws}/datastores resource.
Package datastores is the v2 sub-client for the GeoServer /rest/workspaces/{ws}/datastores resource.
featuretypes
Package featuretypes is the v2 sub-client for the GeoServer /rest/workspaces/{ws}/datastores/{ds}/featuretypes resource.
Package featuretypes is the v2 sub-client for the GeoServer /rest/workspaces/{ws}/datastores/{ds}/featuretypes resource.
fonts
Package fonts is the v2 sub-client for the GeoServer /rest/fonts endpoint.
Package fonts is the v2 sub-client for the GeoServer /rest/fonts endpoint.
gwc
Package gwc is the v2 sub-client for the GeoWebCache REST endpoints at `/gwc/rest/` β€” universal for any GeoServer deployment serving map tiles.
Package gwc is the v2 sub-client for the GeoWebCache REST endpoints at `/gwc/rest/` β€” universal for any GeoServer deployment serving map tiles.
imports
Package imports is the v2 sub-client for the GeoServer Importer extension at `/rest/imports`.
Package imports is the v2 sub-client for the GeoServer Importer extension at `/rest/imports`.
layergroups
Package layergroups is the v2 sub-client for the GeoServer /rest/workspaces/{ws}/layergroups resource.
Package layergroups is the v2 sub-client for the GeoServer /rest/workspaces/{ws}/layergroups resource.
layers
Package layers is the v2 sub-client for the GeoServer /rest/workspaces/{ws}/layers resource.
Package layers is the v2 sub-client for the GeoServer /rest/workspaces/{ws}/layers resource.
logging
Package logging is the v2 sub-client for the GeoServer /rest/logging endpoint β€” singleton configuration for the active log4j profile and stdout logging.
Package logging is the v2 sub-client for the GeoServer /rest/logging endpoint β€” singleton configuration for the active log4j profile and stdout logging.
monitor
Package monitor is the v2 sub-client for the GeoServer /rest/monitor/requests endpoint β€” read-only audit log of OWS and REST requests handled by the server.
Package monitor is the v2 sub-client for the GeoServer /rest/monitor/requests endpoint β€” read-only audit log of OWS and REST requests handled by the server.
namespaces
Package namespaces is the v2 sub-client for the GeoServer /rest/namespaces resource.
Package namespaces is the v2 sub-client for the GeoServer /rest/namespaces resource.
resources
Package resources is the v2 sub-client for the GeoServer Resource REST API at /rest/resource/{path}.
Package resources is the v2 sub-client for the GeoServer Resource REST API at /rest/resource/{path}.
security
Package security is the v2 sub-client for the GeoServer security subsystem β€” users, groups, roles, and user-role assignment under /rest/security.
Package security is the v2 sub-client for the GeoServer security subsystem β€” users, groups, roles, and user-role assignment under /rest/security.
services
Package services is the v2 sub-client for GeoServer's per-service OWS configuration endpoints β€” `/rest/services/{wms,wfs,wcs,wmts}/settings`.
Package services is the v2 sub-client for GeoServer's per-service OWS configuration endpoints β€” `/rest/services/{wms,wfs,wcs,wmts}/settings`.
settings
Package settings is the v2 sub-client for the GeoServer /rest/settings resource β€” the global server configuration document covering service metadata (charset, online-resource), JAI tunables, and coverage-access tuning.
Package settings is the v2 sub-client for the GeoServer /rest/settings resource β€” the global server configuration document covering service metadata (charset, online-resource), JAI tunables, and coverage-access tuning.
styles
Package styles is the v2 sub-client for the GeoServer /rest/styles and /rest/workspaces/{ws}/styles resources.
Package styles is the v2 sub-client for the GeoServer /rest/styles and /rest/workspaces/{ws}/styles resources.
system
Package system is the v2 sub-client for GeoServer's server-management endpoints under /rest β€” currently `POST /rest/reload` and `POST /rest/reset`.
Package system is the v2 sub-client for GeoServer's server-management endpoints under /rest β€” currently `POST /rest/reload` and `POST /rest/reset`.
templates
Package templates is the v2 sub-client for the GeoServer /rest/.../templates endpoint family.
Package templates is the v2 sub-client for the GeoServer /rest/.../templates endpoint family.
urlchecks
Package urlchecks is the v2 sub-client for the GeoServer URL External Access Checks endpoint at /rest/urlchecks.
Package urlchecks is the v2 sub-client for the GeoServer URL External Access Checks endpoint at /rest/urlchecks.
wfstransforms
Package wfstransforms is the v2 sub-client for the GeoServer XSLT-based WFS output transforms at /rest/services/wfs/transforms.
Package wfstransforms is the v2 sub-client for the GeoServer XSLT-based WFS output transforms at /rest/services/wfs/transforms.
wmslayers
Package wmslayers is the v2 sub-client for GeoServer's cascaded WMS layers β€” published references to remote WMS server layers served through the local GeoServer.
Package wmslayers is the v2 sub-client for GeoServer's cascaded WMS layers β€” published references to remote WMS server layers served through the local GeoServer.
wmsstores
Package wmsstores is the v2 sub-client for the GeoServer cascaded WMS store endpoint at /rest/workspaces/{ws}/wmsstores.
Package wmsstores is the v2 sub-client for the GeoServer cascaded WMS store endpoint at /rest/workspaces/{ws}/wmsstores.
wmtslayers
Package wmtslayers is the v2 sub-client for GeoServer's cascaded WMS layers β€” published references to remote WMS server layers served through the local GeoServer.
Package wmtslayers is the v2 sub-client for GeoServer's cascaded WMS layers β€” published references to remote WMS server layers served through the local GeoServer.
wmtsstores
Package wmtsstores is the v2 sub-client for the GeoServer cascaded WMS store endpoint at /rest/workspaces/{ws}/wmtsstores.
Package wmtsstores is the v2 sub-client for the GeoServer cascaded WMS store endpoint at /rest/workspaces/{ws}/wmtsstores.
workspaces
Package workspaces is the v2 sub-client for the GeoServer /rest/workspaces resource.
Package workspaces is the v2 sub-client for the GeoServer /rest/workspaces resource.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL