Documentation
¶
Overview ¶
Package query provides a Go client library for the Neo4j Query API.
Index ¶
- Variables
- func Float64List(list []any) ([]float64, bool)
- func Int64List(list []any) ([]int64, bool)
- func IsNotFound(err error) bool
- func StringList(list []any) ([]string, bool)
- func WithTransformer[T any](svc QueryService, ctx context.Context, cypher string, params map[string]any, ...) (T, error)
- type APIFlavor
- type AccessMode
- type Duration
- type EagerResult
- type Error
- type ErrorDetail
- type Node
- type Notification
- type Option
- func WithAPIFlavor(flavor APIFlavor) Option
- func WithAccessMode(mode AccessMode) Option
- func WithBaseURL(baseURL string) Option
- func WithBasicAuth(username, password string) Option
- func WithBearerToken(token string) Option
- func WithDatabase(database string) Option
- func WithDefaultHeaders(headers map[string]string) Option
- func WithHTTPClient(client *http.Client) Option
- func WithLogger(logger *slog.Logger) Option
- func WithMaxResponseSize(maxResponse int) Option
- func WithMaxRetry(maxRetry int) Option
- func WithStreamingSupport(enabled bool) Option
- func WithTimeout(timeout time.Duration) Option
- func WithUserAgent(ua string) Option
- type Path
- type PlanOperator
- type Point
- type QueryAPIClient
- type QueryError
- type QueryErrors
- type QueryService
- type Record
- func (r *Record) AsMap() map[string]any
- func (r *Record) Get(field string) (any, bool)
- func (r *Record) GetBool(field string) (bool, bool)
- func (r *Record) GetBytes(field string) ([]byte, bool)
- func (r *Record) GetDuration(field string) (decode.Duration, bool)
- func (r *Record) GetFloat64(field string) (float64, bool)
- func (r *Record) GetInt64(field string) (int64, bool)
- func (r *Record) GetList(field string) ([]any, bool)
- func (r *Record) GetMap(field string) (map[string]any, bool)
- func (r *Record) GetNode(field string) (*decode.Node, bool)
- func (r *Record) GetPath(field string) (decode.Path, bool)
- func (r *Record) GetPoint(field string) (decode.Point, bool)
- func (r *Record) GetRelationship(field string) (*decode.Relationship, bool)
- func (r *Record) GetString(field string) (string, bool)
- func (r *Record) GetTime(field string) (time.Time, bool)
- func (r *Record) IsNull(field string) bool
- func (r *Record) Keys() []string
- func (r *Record) String() string
- func (r *Record) Values() []any
- type Relationship
- type Response
- type ResultTransformer
- type StreamResult
- type StreamSummary
- type VersionError
Constants ¶
This section is empty.
Variables ¶
var ClientVersion = clientVersionFallback
ClientVersion is the version of this client library, embedded in every User-Agent header.
Why debug.ReadBuildInfo()? Go consumers import this library by source (via the module proxy). There are no compiled binaries to stamp at build time. When a consumer builds their application, the Go toolchain records all module dependencies and their exact versions in the binary. debug.ReadBuildInfo() reads that information at runtime, so the User-Agent automatically reflects the version the consumer actually imported (e.g. "v1.10.0") without any source edits or workflow tricks.
Why info.Deps and not info.Main? info.Main describes the consumer's own application module, not this SDK — its Version is "(devel)" for essentially any normal `go build` regardless of which SDK version was imported. This SDK's own version only appears in info.Deps, keyed by module path, which is what resolveClientVersion looks up.
In local and test builds (where this module is its own main module and so never appears in its own Deps) or if the lookup otherwise comes up empty, we fall back to clientVersionFallback ("development") to make it obvious the binary is not tracking a release.
Functions ¶
func Float64List ¶
Float64List converts a []any list to []float64. Returns nil, false if any element is not a float64.
func Int64List ¶
Int64List converts a []any list to []int64. Returns nil, false if any element is not an int64.
func IsNotFound ¶
IsNotFound reports whether err is a 404 Not Found API error.
func StringList ¶
StringList converts a []any list to []string. Returns nil, false if any element is not a string.
func WithTransformer ¶
func WithTransformer[T any](svc QueryService, ctx context.Context, cypher string, params map[string]any, transformer ResultTransformer[T]) (T, error)
WithTransformer executes a Cypher statement via svc and applies transformer to the result. It is a package-level generic function rather than a method on queryService because Go interfaces cannot have generic methods.
This mirrors the pattern used by the Neo4j Go driver, where neo4j.ExecuteQuery is a package-level generic function that accepts the Driver interface:
// Driver pattern:
result, err := neo4j.ExecuteQuery(ctx, driver, cypher, params,
neo4j.EagerResultTransformer, ...)
// This SDK — same shape:
result, err := query.WithTransformer(svc, ctx, cypher, params,
query.EagerResultTransformer)
Because it accepts QueryService (the interface), it works against any implementation including test doubles.
Types ¶
type APIFlavor ¶ added in v0.2.0
type APIFlavor int
APIFlavor selects which Neo4j HTTP API the client will target.
const ( // FlavorQueryV2 targets the modern Query API v2 endpoint (/db/{db}/query/v2). // This is the default. FlavorQueryV2 APIFlavor = iota // FlavorLegacyHTTP targets the older Cypher HTTP Transaction API // endpoint (/db/{db}/tx/commit). Use this for comparison testing against // Neo4j versions that pre-date the Query API. FlavorLegacyHTTP )
type AccessMode ¶ added in v0.3.0
type AccessMode int
AccessMode controls the accessMode sent with every API request.
const ( // AccessModeUnset sends no accessMode at all. This is the default: the // server-side router forwards the request to whichever cluster member // can handle it — any member for a read, the leader for a write. AccessModeUnset AccessMode = iota // AccessModeRead sets the accessMode to "read". AccessModeRead // AccessModeWrite sets the accessMode to "write". AccessModeWrite )
type Duration ¶
Duration represents a Neo4j DURATION value. It cannot be represented as time.Duration because months and days are calendar-relative.
type EagerResult ¶
type EagerResult struct {
Keys []string
Records []*Record
Notifications []decode.Notification
QueryPlan *decode.PlanOperator
Bookmarks []string
// QueryType is the kind of query executed: "r" (read only), "rw" (read
// write), "w" (write only), or "s" (schema write).
QueryType string
// ResultAvailableAfter is how long the result took to become available.
ResultAvailableAfter time.Duration
// ResultConsumedAfter is how long the result took to be fully consumed.
ResultConsumedAfter time.Duration
}
EagerResult holds the fully materialised result of a query. Mirrors neo4j.EagerResult in the Go driver.
func (*EagerResult) HasWarnings ¶
func (e *EagerResult) HasWarnings() bool
HasWarnings returns true if any WARNING severity notifications are present.
func (*EagerResult) String ¶
func (e *EagerResult) String() string
String returns a human-readable summary of the result, useful for debugging.
func (*EagerResult) Warnings ¶
func (e *EagerResult) Warnings() []decode.Notification
Warnings returns only the notifications with severity "WARNING".
type ErrorDetail ¶
type ErrorDetail = api.ErrorDetail
ErrorDetail represents individual error details within an Error.
type Notification ¶
type Notification = decode.Notification
Notification is an advisory message from Neo4j about the executed statement. Notifications are not errors — the query succeeded and rows are returned alongside them.
type Option ¶
type Option func(*options) error
Option is a functional option for configuring the AuraAPIClient.
func WithAPIFlavor ¶ added in v0.2.0
WithAPIFlavor selects which Neo4j HTTP API endpoint the client targets. Use FlavorLegacyHTTP to target the older Cypher HTTP Transaction API (/db/{db}/tx/commit) for comparison testing. Defaults to FlavorQueryV2.
func WithAccessMode ¶ added in v0.3.0
func WithAccessMode(mode AccessMode) Option
WithAccessMode sets the accessMode sent with every API request. Use AccessModeRead for read-only workloads to allow the server to route the request to a read replica, or AccessModeWrite to force leader routing. Defaults to AccessModeUnset, which sends no accessMode at all and lets the server-side router forward the request to whichever cluster member can handle it.
func WithBaseURL ¶
WithBaseURL overrides the default base URL of the Neo4j server. The SDK does not enforce HTTPS — it is the caller's responsibility to use an appropriate scheme for their deployment. Use HTTPS for any server that is not on a trusted loopback interface.
func WithBasicAuth ¶
func WithBearerToken ¶
func WithDefaultHeaders ¶
WithDefaultHeaders adds the given headers to every API request. It is a no-op when headers is nil or empty. Keys matching Authorization, Content-Type, Accept, or User-Agent (case-insensitive) are rejected with an error to prevent callers from inadvertently overriding security-sensitive or protocol-critical headers.
func WithHTTPClient ¶
WithHTTPClient sets a custom *http.Client to use for all API requests. This lets callers inject a custom transport (e.g. for mTLS, proxies, or testing). Returns an error if client is nil.
Note: when a custom client is supplied, WithTimeout has no effect. The caller is responsible for setting a Timeout on the provided *http.Client directly.
func WithLogger ¶
WithLogger sets a custom slog.Logger. Defaults to warn-level logging to stderr.
func WithMaxResponseSize ¶
WithMaxResponseSize sets the maximum size for response. Default is 10mb
func WithMaxRetry ¶
WithMaxRetry sets the maximum number of retries for failed requests. Defaults to 3.
func WithStreamingSupport ¶ added in v0.5.0
WithStreamingSupport enables the Query API's streaming (JSON Lines) response format, which unlocks QueryService.ExecuteStream for incremental record consumption instead of buffering the entire response. Execute is unaffected either way. Defaults to disabled.
Not supported together with WithAPIFlavor(FlavorLegacyHTTP): the legacy Cypher HTTP Transaction API does not support streaming. NewClient returns an error if both are set.
func WithTimeout ¶
WithTimeout sets a custom API timeout. Defaults to 120 seconds.
func WithUserAgent ¶
WithUserAgent overrides the default User-Agent header sent with every request. Returns an error if ua is empty.
type Path ¶
Path represents a Neo4j PATH value — an alternating sequence of nodes and relationships.
type PlanOperator ¶
type PlanOperator = decode.PlanOperator
PlanOperator is one node in an EXPLAIN or PROFILE query plan tree.
type Point ¶
Point represents a Neo4j POINT value with an SRID identifying the coordinate reference system. Common SRIDs: 4326 (WGS-84 2D), 4979 (WGS-84 3D), 7203 (Cartesian 2D), 9157 (Cartesian 3D).
type QueryAPIClient ¶
type QueryAPIClient struct {
// Grouped services — using interface types for testability.
Query QueryService
// contains filtered or unexported fields
}
QueryAPIClient is the main client for the Neo4j Query API.
func NewClient ¶
func NewClient(opts ...Option) (*QueryAPIClient, error)
NewClient creates a new Query API client with functional options.
func (*QueryAPIClient) CheckVersion ¶
func (c *QueryAPIClient) CheckVersion(ctx context.Context) error
CheckVersion calls the Neo4j discovery endpoint and returns a *VersionError if the server version is older than 2026.04.0. Call this after NewClient when you want to validate the connected server before executing queries.
client, err := query.NewClient(query.WithBasicAuth("neo4j", "password"))
if err != nil {
log.Fatal(err)
}
defer client.Close()
if err := client.CheckVersion(ctx); err != nil {
var verErr *query.VersionError
if errors.As(err, &verErr) {
log.Fatalf("server too old: got %s, need %s", verErr.Got, verErr.Required)
}
log.Fatal(err)
}
func (*QueryAPIClient) Close ¶
func (c *QueryAPIClient) Close()
Close drains idle HTTP connections held by the underlying transport. It should be called via defer when the client is no longer needed to avoid leaking file descriptors.
client, err := query.NewClient(query.WithBasicAuth("neo4j", "password"))
if err != nil {
log.Fatal(err)
}
defer client.Close()
type QueryError ¶
type QueryError = decode.QueryError
QueryError is a single Neo4j error within a QueryErrors batch. Use Classification(), Category(), and Title() to branch on the error code.
type QueryErrors ¶
type QueryErrors = decode.QueryErrors
QueryErrors is returned when Neo4j responds with one or more query errors. Inspect with errors.As:
var qErr *query.QueryErrors
if errors.As(err, &qErr) {
for _, e := range qErr.Errors {
log.Printf("[%s] %s", e.Title(), e.Message)
}
}
type QueryService ¶
type QueryService interface {
// Execute runs a Cypher statement and returns the raw decoded response.
// Use WithTransformer to map the result to a typed value.
Execute(ctx context.Context, qry string, qryParams map[string]any) (*Response, error)
// ExecuteStream runs a Cypher statement and returns a StreamResult that
// decodes records incrementally as they arrive over the wire, instead of
// buffering the entire response. Requires the client to be constructed
// with WithStreamingSupport(true).
ExecuteStream(ctx context.Context, qry string, qryParams map[string]any) (*StreamResult, error)
}
QueryService defines operations for using the Query API
type Record ¶
type Record struct {
// contains filtered or unexported fields
}
Record represents a single row in a query result with named field access. It mirrors neo4j.Record in the Go driver for a consistent developer experience.
func (*Record) Get ¶
Get returns the value for the named field and whether the field exists. A field that is present but Null returns (nil, true). The returned value is one of the types documented on decode.DecodeValue.
func (*Record) GetRelationship ¶
func (r *Record) GetRelationship(field string) (*decode.Relationship, bool)
func (*Record) IsNull ¶
IsNull reports whether the named field exists and has a Null value. Use this to distinguish "field is null" from "field not in result".
type Relationship ¶
type Relationship = decode.Relationship
Relationship represents a Neo4j RELATIONSHIP value.
type Response ¶
Response is the decoded result of a Cypher query execution. Fields holds the ordered column names; Rows holds one []any per row where each element is a fully decoded Go value (see DecodeValue for the type mapping).
type ResultTransformer ¶
ResultTransformer converts a raw *decode.Response into a typed result T. Mirrors the transformer pattern in the Neo4j Go driver:
neo4j.ExecuteQuery(ctx, driver, cypher, params, neo4j.EagerResultTransformer, ...)
Usage with this SDK:
result, err := query.WithTransformer(svc, ctx, cypher, params, query.EagerResultTransformer)
var EagerResultTransformer ResultTransformer[*EagerResult] = func(resp *decode.Response) (*EagerResult, error) { records := make([]*Record, len(resp.Rows)) for i, row := range resp.Rows { records[i] = newRecord(resp.Fields, row) } return &EagerResult{ Keys: resp.Fields, Records: records, Notifications: resp.Notifications, QueryPlan: resp.QueryPlan, Bookmarks: resp.Bookmarks, QueryType: resp.QueryType, ResultAvailableAfter: resp.ResultAvailableAfter, ResultConsumedAfter: resp.ResultConsumedAfter, }, nil }
EagerResultTransformer collects all rows into an EagerResult. Use for typical queries where the full result set fits comfortably in memory.
result, err := query.WithTransformer(svc, ctx, cypher, params, query.EagerResultTransformer)
for _, rec := range result.Records {
name, _ := rec.GetString("p.name")
}
func Collect ¶
func Collect[T any](fn func(*Record) (T, error)) ResultTransformer[[]T]
Collect returns a ResultTransformer that maps each Record to a value of type T using fn, collecting the results into []T.
type Actor struct {
Name string
Roles []string
}
actors, err := query.WithTransformer(svc, ctx, cypher, params,
query.Collect(func(rec *query.Record) (Actor, error) {
name, _ := rec.GetString("p.name")
raw, _ := rec.GetList("a.roles")
roles, _ := query.StringList(raw)
return Actor{Name: name, Roles: roles}, nil
}),
)
func Single ¶
func Single[T any](fn func(*Record) (T, error)) ResultTransformer[T]
Single returns a ResultTransformer that expects exactly one row and maps it to T using fn. Returns an error if the result has zero or more than one row.
movie, err := query.WithTransformer(svc, ctx, cypher, params,
query.Single(func(rec *query.Record) (Movie, error) {
title, _ := rec.GetString("m.title")
released, _ := rec.GetInt64("m.released")
return Movie{Title: title, Released: int(released)}, nil
}),
)
type StreamResult ¶ added in v0.5.0
type StreamResult struct {
// contains filtered or unexported fields
}
StreamResult represents an in-progress streamed query result, obtained from QueryService.ExecuteStream. Records are decoded incrementally as they arrive over the wire instead of being buffered up front.
Records() must be consumed to completion (or the caller must call Close) to release the underlying HTTP connection; ranging over Records() with a `break` still releases it, since the iterator closes the stream on early return. Call Records() at most once per StreamResult.
func (*StreamResult) Close ¶ added in v0.5.0
func (s *StreamResult) Close() error
Close releases the underlying HTTP connection. Safe to call multiple times and after Records() has already drained the stream (no-op in that case).
func (*StreamResult) Fields ¶ added in v0.5.0
func (s *StreamResult) Fields() []string
Fields returns the ordered column names for this result, available immediately after ExecuteStream returns (decoded from the stream's leading Header event).
func (*StreamResult) Records ¶ added in v0.5.0
func (s *StreamResult) Records() iter.Seq2[*Record, error]
Records returns an iterator over the result rows, for use with:
for rec, err := range result.Records() {
if err != nil {
return err
}
// use rec
}
Iteration stops after the first error — a transport/decode error, or a *QueryErrors surfaced by a mid-stream Error event — or once the terminating Summary event has been consumed. The underlying HTTP connection is released when iteration ends for any reason, including an early `break`.
func (*StreamResult) Summary ¶ added in v0.5.0
func (s *StreamResult) Summary() *StreamSummary
Summary returns the execution metadata delivered by the stream's Summary event. It returns nil until Records() has been fully drained, and remains nil if the stream ended in error instead of a Summary event.
type StreamSummary ¶ added in v0.5.0
type StreamSummary = decode.StreamSummary
StreamSummary is the execution metadata delivered once a streamed query result completes successfully. Available from StreamResult.Summary() only after Records() has been fully drained (naturally or via early return).
type VersionError ¶
type VersionError struct {
// Required is the minimum acceptable CalVer version (e.g. "2026.04.0").
Required string
// Got is the version reported by the connected server.
Got string
}
VersionError is returned by CheckVersion when the connected Neo4j server is older than the minimum supported version.
func (*VersionError) Error ¶
func (e *VersionError) Error() string
Source Files
¶
Directories
¶
| Path | Synopsis |
|---|---|
|
examples
|
|
|
basicQuery
command
Package main demonstrates using the Neo4j Query API Go SDK.
|
Package main demonstrates using the Neo4j Query API Go SDK. |
|
streamingQuery
command
Package main demonstrates streaming query results with the Neo4j Query API Go SDK.
|
Package main demonstrates streaming query results with the Neo4j Query API Go SDK. |
|
internal
|
|
|
api
Package api implements the authenticated HTTP request layer for the Neo4j Query API.
|
Package api implements the authenticated HTTP request layer for the Neo4j Query API. |
|
decode
Package decode handles decoding of Neo4j Query API typed JSON responses.
|
Package decode handles decoding of Neo4j Query API typed JSON responses. |
|
httpclient
Package httpclient provides a low-level HTTP client with configurable retry behaviour.
|
Package httpclient provides a low-level HTTP client with configurable retry behaviour. |
|
testutil
Package testutil provides mock implementations for use in tests across the query-go-sdk module.
|
Package testutil provides mock implementations for use in tests across the query-go-sdk module. |
|
utils
Package utils provides shared internal helpers for the query-go-sdk module.
|
Package utils provides shared internal helpers for the query-go-sdk module. |