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 ¶
- Variables
- func IsGraphQLBody(body []byte) bool
- func IsNotGraphQL(err error) bool
- type Error
- type ErrorGroup
- type ErrorSummary
- type FragmentCoverage
- type FragmentInfo
- type FragmentWarning
- type InspectedOperation
- type OperationCluster
- type ParseError
- type ParseResult
- type ParsedOperation
- type ResponseVariants
- type TrafficSummary
- type TypenameSeen
- type UnmatchedType
- type ValueCount
- type VariableDistribution
- type Variant
Constants ¶
This section is empty.
Variables ¶
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 ¶
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 ¶
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 ¶
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.