graphql

package
v1.3.0 Latest Latest
Warning

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

Go to latest
Published: Mar 6, 2026 License: AGPL-3.0, AGPL-3.0-or-later Imports: 6 Imported by: 0

Documentation

Overview

Package graphql provides lightweight GraphQL request body parsing and traffic analysis types. It extracts operation names, types, and top-level fields from GraphQL HTTP request bodies without a full AST parser.

Index

Constants

This section is empty.

Variables

View Source
var (
	// ErrEmpty indicates the request body was empty or whitespace-only.
	ErrEmpty = errors.New("graphql: empty body")

	// ErrNotGraphQL indicates the body is valid JSON but does not contain
	// a GraphQL query or operationName field.
	ErrNotGraphQL = errors.New("graphql: not a GraphQL request body")
)

Sentinel errors for parse failures.

Functions

func IsGraphQLBody

func IsGraphQLBody(body []byte) bool

IsGraphQLBody probes whether a JSON body is a GraphQL request by checking for the presence of a "query" field (string) or an array of objects with "query" fields. This is more reliable than path-based detection because GraphQL endpoints can be mounted on any path.

Returns true if the body looks like a GraphQL request, false otherwise. Does not fully parse the body — only checks structural signals.

func IsNotGraphQL

func IsNotGraphQL(err error) bool

IsNotGraphQL returns true if the error indicates the body is not GraphQL. Checks for both ErrNotGraphQL and ErrEmpty using errors.Is.

Types

type Error

type Error struct {
	Message    string `json:"message"`
	Path       []any  `json:"path,omitempty"`
	Locations  []any  `json:"locations,omitempty"`
	Extensions any    `json:"extensions,omitempty"`
}

Error represents a single GraphQL error from a response.

type ErrorGroup

type ErrorGroup struct {
	EntryID       string  `json:"entry_id"`
	OperationName string  `json:"operation_name,omitempty"`
	Errors        []Error `json:"errors,omitzero"`
	IsPartial     bool    `json:"is_partial"`      // data != null && errors present
	IsFullFailure bool    `json:"is_full_failure"` // data == null && errors present
}

ErrorGroup groups errors from a single entry.

type ErrorSummary

type ErrorSummary struct {
	EntriesChecked    int `json:"entries_checked"`
	EntriesWithErrors int `json:"entries_with_errors"`
	TotalErrors       int `json:"total_errors"`
	PartialFailures   int `json:"partial_failures"`
	FullFailures      int `json:"full_failures"`
}

ErrorSummary summarizes GraphQL errors across entries.

type FragmentCoverage

type FragmentCoverage struct {
	Fragments       []FragmentInfo  `json:"fragments,omitzero"`
	TypenamesSeen   []TypenameSeen  `json:"typenames_seen,omitzero"`
	UnmatchedTypes  []UnmatchedType `json:"unmatched_types,omitzero"`
	UnusedFragments []string        `json:"unused_fragments,omitzero"`
}

FragmentCoverage cross-references query fragments against response __typename values.

type FragmentInfo

type FragmentInfo struct {
	Name     string   `json:"name,omitempty"` // Fragment name (empty for inline fragments)
	OnType   string   `json:"on_type"`        // Type condition (e.g., "Human")
	Fields   []string `json:"fields,omitempty"`
	IsInline bool     `json:"is_inline"` // True for ... on Type { } fragments
}

FragmentInfo describes a named or inline fragment found in a GraphQL query.

func ExtractFragments

func ExtractFragments(query string) []FragmentInfo

ExtractFragments scans a GraphQL query string for named fragments (fragment Foo on Bar { ... }) and inline fragments (... on Bar { ... }), returning a list of FragmentInfo.

type FragmentWarning

type FragmentWarning struct {
	Path     string `json:"path"`     // JSON path to the object (e.g., "data.nav.items[0]")
	Typename string `json:"typename"` // The __typename value
	Message  string `json:"message"`  // Actionable guidance
}

FragmentWarning indicates a response object that likely needs a fragment spread.

type InspectedOperation

type InspectedOperation struct {
	ParsedOperation
	VariablesSchema *jsonschema.Schema `json:"variables_schema,omitempty"`
	ResponseSchema  *jsonschema.Schema `json:"response_schema,omitempty"`
	FieldStats      []js.FieldStat     `json:"field_stats,omitempty"`
}

InspectedOperation contains parsed operation details with inferred schemas.

type OperationCluster

type OperationCluster struct {
	Name            string                          `json:"name"`                       // Operation name
	Type            string                          `json:"type"`                       // query, mutation, or subscription
	Count           int                             `json:"count"`                      // Total requests
	ErrorCount      int                             `json:"error_count"`                // Requests with GraphQL errors
	Fields          []string                        `json:"fields,omitempty"`           // Union of top-level fields across samples
	HasVariables    bool                            `json:"has_variables"`              // Any sample used variables
	VariableSummary map[string]VariableDistribution `json:"variable_summary,omitempty"` // Per-variable value distribution
	EntryIDs        []string                        `json:"example_entry_ids,omitzero"` // Example entry IDs (up to 5)
}

OperationCluster groups GraphQL entries by operation name and type.

type ParseError

type ParseError struct {
	// Sentinel is the category (ErrEmpty, ErrNotGraphQL, or nil for JSON errors).
	Sentinel error
	// Cause is the underlying error (e.g., json.SyntaxError).
	Cause error
	// Message provides human-readable context.
	Message string
}

ParseError wraps a parse failure with the underlying cause. Use errors.Is to check for ErrEmpty or ErrNotGraphQL, and errors.As to extract the ParseError for context.

func (*ParseError) Error

func (e *ParseError) Error() string

func (*ParseError) Is

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

Is supports errors.Is matching against sentinel errors.

func (*ParseError) Unwrap

func (e *ParseError) Unwrap() error

type ParseResult

type ParseResult struct {
	Operations []ParsedOperation `json:"operations"`
	IsBatched  bool              `json:"is_batched"` // True if the body was a JSON array
}

ParseResult contains the result of parsing a GraphQL request body.

func ParseRequestBody

func ParseRequestBody(body []byte) (*ParseResult, error)

ParseRequestBody parses a GraphQL request body (single or batched). Returns the parsed operations. For non-JSON or empty bodies, returns an error.

type ParsedOperation

type ParsedOperation struct {
	Name          string   `json:"name"`                     // Operation name ("anonymous" if unnamed)
	Type          string   `json:"type"`                     // query, mutation, or subscription
	Fields        []string `json:"fields,omitempty"`         // Top-level field selections
	RawQuery      string   `json:"raw_query,omitempty"`      // Raw query string (if include_query)
	Variables     any      `json:"variables,omitempty"`      // Variables object (raw)
	HasVariables  bool     `json:"has_variables"`            // Whether variables were present
	BatchIndex    int      `json:"batch_index,omitempty"`    // Index in batched request (0 for non-batched)
	ParseFailed   bool     `json:"parse_failed,omitempty"`   // True if query string could not be parsed
	OperationName string   `json:"operation_name,omitempty"` // Raw operationName from JSON body
}

ParsedOperation represents a single parsed GraphQL operation.

type ResponseVariants

type ResponseVariants struct {
	DiscriminatingVariable string    `json:"discriminating_variable,omitempty"` // Variable that best separates shapes
	Variants               []Variant `json:"variants,omitzero"`
}

ResponseVariants groups entries by response shape and identifies the discriminating variable. Empty when all entries have the same shape.

type TrafficSummary

type TrafficSummary struct {
	TotalRequests     int      `json:"total_requests"`
	QueryCount        int      `json:"query_count"`
	MutationCount     int      `json:"mutation_count"`
	SubscriptionCount int      `json:"subscription_count"`
	BatchedCount      int      `json:"batched_count"`   // Entries that contained batched ops
	AnonymousCount    int      `json:"anonymous_count"` // Operations without a name
	UniqueOps         int      `json:"unique_operations"`
	Hosts             []string `json:"hosts,omitzero"`
}

TrafficSummary summarizes GraphQL traffic across all entries.

type TypenameSeen

type TypenameSeen struct {
	Typename    string   `json:"typename"`
	Paths       []string `json:"paths,omitzero"` // Example paths where it appeared
	Count       int      `json:"count"`          // Total occurrences across entries
	HasFragment bool     `json:"has_fragment"`   // Whether a fragment covers this type
}

TypenameSeen records a __typename value observed in response data.

type UnmatchedType

type UnmatchedType struct {
	Typename     string   `json:"typename"`
	ExamplePaths []string `json:"example_paths,omitzero"` // Example paths where it appeared
	Message      string   `json:"message"`                // Actionable guidance
}

UnmatchedType is a __typename seen in responses with no covering fragment.

type ValueCount

type ValueCount struct {
	Value any `json:"value"`
	Count int `json:"count"`
}

ValueCount represents a value and its occurrence count.

type VariableDistribution

type VariableDistribution struct {
	Type        string       `json:"type"`                 // Inferred JSON type (string, number, boolean, object, array, null)
	TopValues   []ValueCount `json:"top_values,omitzero"`  // Most frequent values (scalars only, capped)
	UniqueCount int          `json:"unique_count"`         // Total distinct non-null values seen
	NullCount   int          `json:"null_count,omitempty"` // Entries where this variable was null
}

VariableDistribution describes the distribution of values for a single GraphQL variable.

type Variant

type Variant struct {
	VariableValues map[string]any `json:"variable_values,omitempty"` // Common variable values for this group
	EntryCount     int            `json:"entry_count"`
	ShapeKeys      []string       `json:"shape_keys,omitzero"`        // Top-level keys in .data for this shape
	ExampleEntryID string         `json:"example_entry_id,omitempty"` // Representative entry
}

Variant describes a group of entries that share the same response shape.

Jump to

Keyboard shortcuts

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