Documentation
¶
Overview ¶
Package jsonpatch provides comprehensive JSON Patch operations with generic type support.
Implements JSON mutation operations including:
- JSON Patch (RFC 6902): Standard operations (add, remove, replace, move, copy, test) https://tools.ietf.org/html/rfc6902
- JSON Predicate: Test operations (contains, defined, type, less, more, etc.) https://tools.ietf.org/id/draft-snell-json-test-01.html
- Extended operations: Additional operations (flip, inc, str_ins, str_del, split, merge)
Core API Functions:
- ApplyOp: Apply a single operation
- ApplyOps: Apply multiple operations
- ApplyPatch: Apply a JSON Patch to a document (main generic API)
- ValidateOperations: Validate an array of operations
- ValidateOperation: Validate a single operation
Basic usage:
doc := map[string]any{"name": "John", "age": 30} patch := []Operation{ {"op": "replace", "path": "/name", "value": "Jane"}, {"op": "add", "path": "/email", "value": "jane@example.com"}, } result, err := ApplyPatch(doc, patch, WithMutate(false))
The library provides type-safe operations for any supported document type.
Example ¶
Example demonstrates basic JSON Patch operations
package main import ( "encoding/json" "fmt" "github.com/kaptinlin/jsonpatch" ) func main() { // Original document doc := map[string]interface{}{ "user": map[string]interface{}{ "name": "Alice", "email": "alice@example.com", "age": 25, }, "settings": map[string]interface{}{ "theme": "dark", }, } // Create patch operations patch := []jsonpatch.Operation{ // Add a new field map[string]interface{}{ "op": "add", "path": "/user/active", "value": true, }, // Update existing field map[string]interface{}{ "op": "replace", "path": "/user/age", "value": 26, }, // Add to settings map[string]interface{}{ "op": "add", "path": "/settings/notifications", "value": true, }, } // Apply patch result, err := jsonpatch.ApplyPatch(doc, patch) if err != nil { fmt.Printf("Error: %v\n", err) return } // Print result resultJSON, _ := json.MarshalIndent(result.Doc, "", " ") fmt.Println(string(resultJSON)) }
Output: { "settings": { "notifications": true, "theme": "dark" }, "user": { "active": true, "age": 26, "email": "alice@example.com", "name": "Alice" } }
Index ¶
- Constants
- Variables
- func ApplyOp[T internal.Document](doc T, operation internal.Op, opts ...internal.Option) (*internal.OpResult[T], error)
- func ApplyOpDirect(operation internal.Op, doc interface{}) (internal.OpResult[any], error)
- func ApplyOps[T internal.Document](doc T, operations []internal.Op, opts ...internal.Option) (*internal.PatchResult[T], error)
- func ApplyPatch[T internal.Document](doc T, patch []internal.Operation, opts ...internal.Option) (*internal.PatchResult[T], error)
- func DefaultOptions() *internal.Options
- func GetOpCode(operation internal.Op) int
- func GetOpPath(operation internal.Op) []string
- func GetOpType(operation internal.Op) internal.OpType
- func GetSecondOrderOps(predicate internal.SecondOrderPredicateOp) []internal.PredicateOp
- func IsNotPredicate(predicate internal.PredicateOp) bool
- func TestPredicate(predicate internal.PredicateOp, doc interface{}) (bool, error)
- func ToCompact(operation internal.Op) (internal.CompactOperation, error)
- func ToJSON(operation internal.Op) (internal.Operation, error)
- func ValidateOp(operation internal.Op) error
- func ValidateOperation(operation Operation, allowMatchesOp bool) error
- func ValidateOperations(ops []Operation, allowMatchesOp bool) error
- type Document
- type JsonPatchOptions
- type JsonPatchTypes
- type Op
- type OpResult
- type OpType
- type Operation
- type Option
- type Options
- type PatchResult
- type RegexMatcher
Examples ¶
Constants ¶
const ( // JSON Patch (RFC 6902) operations OpAddType = internal.OpAddType OpRemoveType = internal.OpRemoveType OpReplaceType = internal.OpReplaceType OpMoveType = internal.OpMoveType OpCopyType = internal.OpCopyType OpTestType = internal.OpTestType // JSON Predicate operations OpContainsType = internal.OpContainsType OpDefinedType = internal.OpDefinedType OpUndefinedType = internal.OpUndefinedType OpTypeType = internal.OpTypeType OpTestTypeType = internal.OpTestTypeType OpTestStringType = internal.OpTestStringType OpTestStringLenType = internal.OpTestStringLenType OpEndsType = internal.OpEndsType OpStartsType = internal.OpStartsType OpInType = internal.OpInType OpLessType = internal.OpLessType OpMoreType = internal.OpMoreType OpMatchesType = internal.OpMatchesType // Composite operations OpAndType = internal.OpAndType OpOrType = internal.OpOrType OpNotType = internal.OpNotType // Extended operations OpFlipType = internal.OpFlipType OpIncType = internal.OpIncType OpStrInsType = internal.OpStrInsType OpStrDelType = internal.OpStrDelType OpSplitType = internal.OpSplitType OpMergeType = internal.OpMergeType OpExtendType = internal.OpExtendType )
Operation type constants (string constants)
const ( // JSON Patch (RFC 6902) operations OpAddCode = internal.OpAddCode OpRemoveCode = internal.OpRemoveCode OpReplaceCode = internal.OpReplaceCode OpCopyCode = internal.OpCopyCode OpMoveCode = internal.OpMoveCode OpTestCode = internal.OpTestCode // String editing OpStrInsCode = internal.OpStrInsCode OpStrDelCode = internal.OpStrDelCode // Extra OpFlipCode = internal.OpFlipCode OpIncCode = internal.OpIncCode // Slate.js OpSplitCode = internal.OpSplitCode OpMergeCode = internal.OpMergeCode OpExtendCode = internal.OpExtendCode // JSON Predicate OpContainsCode = internal.OpContainsCode OpDefinedCode = internal.OpDefinedCode OpEndsCode = internal.OpEndsCode OpInCode = internal.OpInCode OpLessCode = internal.OpLessCode OpMatchesCode = internal.OpMatchesCode OpMoreCode = internal.OpMoreCode OpStartsCode = internal.OpStartsCode OpUndefinedCode = internal.OpUndefinedCode OpTestTypeCode = internal.OpTestTypeCode OpTestStringCode = internal.OpTestStringCode OpTestStringLenCode = internal.OpTestStringLenCode OpTypeCode = internal.OpTypeCode OpAndCode = internal.OpAndCode OpNotCode = internal.OpNotCode OpOrCode = internal.OpOrCode )
Operation code constants (numeric constants)
const ( JsonPatchTypeString = internal.JsonPatchTypeString JsonPatchTypeNumber = internal.JsonPatchTypeNumber JsonPatchTypeBoolean = internal.JsonPatchTypeBoolean JsonPatchTypeObject = internal.JsonPatchTypeObject JsonPatchTypeInteger = internal.JsonPatchTypeInteger JsonPatchTypeArray = internal.JsonPatchTypeArray JsonPatchTypeNull = internal.JsonPatchTypeNull )
Variables ¶
var ( IsValidJsonPatchType = internal.IsValidJsonPatchType GetJsonPatchType = internal.GetJsonPatchType // Operation type checking functions IsJsonPatchOperation = internal.IsJsonPatchOperation IsPredicateOperation = internal.IsPredicateOperation IsFirstOrderPredicateOperation = internal.IsFirstOrderPredicateOperation IsSecondOrderPredicateOperation = internal.IsSecondOrderPredicateOperation IsJsonPatchExtendedOperation = internal.IsJsonPatchExtendedOperation )
Re-export functions
var ( ErrNoOperationDecoded = errors.New("no operation decoded") ErrInvalidDocumentType = errors.New("invalid document type") ErrConversionFailed = errors.New("failed to convert result back to original type") ErrNoOperationResult = errors.New("no operation result") ErrUnnecessaryConversion = errors.New("unnecessary type conversion") )
Operation application errors
var ( ErrNotArray = errors.New("not an array") ErrEmptyPatch = errors.New("empty operation patch") ErrInvalidOperation = errors.New("invalid operation") ErrMissingPath = errors.New("missing required field 'path'") ErrMissingOp = errors.New("missing required field 'op'") ErrMissingValue = errors.New("missing required field 'value'") ErrMissingFrom = errors.New("missing required field 'from'") ErrInvalidPath = errors.New("field 'path' must be a string") ErrInvalidOp = errors.New("field 'op' must be a string") ErrInvalidFrom = errors.New("field 'from' must be a string") ErrInvalidJSONPointer = errors.New("invalid JSON pointer") ErrInvalidOldValue = errors.New("invalid oldValue") ErrCannotMoveToChildren = errors.New("cannot move into own children") ErrInvalidIncValue = errors.New("invalid inc value") ErrExpectedStringField = errors.New("expected string field") ErrExpectedBooleanField = errors.New("expected field to be boolean") ErrExpectedIntegerField = errors.New("not an integer") ErrNegativeNumber = errors.New("number is negative") ErrInvalidProps = errors.New("invalid props field") ErrInvalidTypeField = errors.New("invalid type field") ErrEmptyTypeList = errors.New("empty type list") ErrInvalidType = errors.New("invalid type") ErrValueMustBeString = errors.New("value must be a string") ErrValueMustBeNumber = errors.New("value must be a number") ErrValueMustBeArray = errors.New("value must be an array") ErrValueTooLong = errors.New("value too long") ErrInvalidNotModifier = errors.New("invalid not modifier") ErrMatchesNotAllowed = errors.New("matches operation not allowed") ErrMustBeArray = errors.New("must be an array") ErrEmptyPredicateList = errors.New("predicate list is empty") ErrEitherStrOrLen = errors.New("either str or len must be set") ErrPosGreaterThanZero = errors.New("expected pos field to be greater than 0") // Additional static errors for err113 compliance ErrInOperationValueMustBeArray = errors.New("in operation value must be an array") ErrExpectedValueToBeString = errors.New("expected value to be string") ErrExpectedIgnoreCaseBoolean = errors.New("expected ignore_case to be boolean") ErrExpectedFieldString = errors.New("expected field to be string") )
Base validation errors - define clearly and concisely
var WithMatcher = internal.WithMatcher
var WithMutate = internal.WithMutate
Functions ¶
func ApplyOp ¶
func ApplyOp[T internal.Document](doc T, operation internal.Op, opts ...internal.Option) (*internal.OpResult[T], error)
ApplyOp applies a single operation to a document with generic type support. It automatically detects the document type and applies the appropriate strategy. Returns an OpResult containing the patched document and old value.
Example usage:
// Struct user := User{Name: "John", Age: 30} result, err := ApplyOp(user, operation, WithMutate(false)) if err == nil { patchedUser := result.Doc // Type: User oldValue := result.Old // Previous value } // Map doc := map[string]any{"name": "John", "age": 30} result, err := ApplyOp(doc, operation, WithMutate(true))
The function preserves the input type: struct input returns struct output, map input returns map output, etc.
func ApplyOpDirect ¶
ApplyOpDirect applies an operation directly using the Op interface.
func ApplyOps ¶
func ApplyOps[T internal.Document](doc T, operations []internal.Op, opts ...internal.Option) (*internal.PatchResult[T], error)
ApplyOps applies multiple operations to a document with generic type support. It automatically detects the document type and applies the appropriate strategy. Returns a PatchResult containing the patched document and operation results.
Example usage:
// Struct user := User{Name: "John", Age: 30} result, err := ApplyOps(user, operations, WithMutate(false)) if err == nil { patchedUser := result.Doc // Type: User opResults := result.Res // Operation results } // Map doc := map[string]any{"name": "John", "age": 30} result, err := ApplyOps(doc, operations, WithMutate(true))
The function preserves the input type: struct input returns struct output, map input returns map output, etc.
func ApplyPatch ¶
func ApplyPatch[T internal.Document](doc T, patch []internal.Operation, opts ...internal.Option) (*internal.PatchResult[T], error)
ApplyPatch applies a JSON Patch to any supported document type. It automatically detects the document type and applies the appropriate strategy. Returns a PatchResult containing the patched document and operation results.
Supported document types:
- struct: Converted via JSON marshaling/unmarshaling
- map[string]any: Applied directly using existing implementation
- []byte: Parsed as JSON, patched, and re-encoded
- string: Parsed as JSON string, patched, and re-encoded
Example usage:
// Struct user := User{Name: "John", Age: 30} result, err := ApplyPatch(user, patch) if err == nil { patchedUser := result.Doc // Type: User operations := result.Res // Operation results } // Map doc := map[string]any{"name": "John", "age": 30} result, err := ApplyPatch(doc, patch) if err == nil { patchedDoc := result.Doc // Type: map[string]any } // JSON bytes data := []byte(`{"name":"John","age":30}`) result, err := ApplyPatch(data, patch) if err == nil { patchedData := result.Doc // Type: []byte }
The function preserves the input type: struct input returns struct output, map input returns map output, etc.
func DefaultOptions ¶ added in v0.2.0
DefaultOptions returns the default configuration for patch operations.
func GetSecondOrderOps ¶
func GetSecondOrderOps(predicate internal.SecondOrderPredicateOp) []internal.PredicateOp
GetSecondOrderOps returns sub-operations from a second-order predicate using the SecondOrderPredicateOp interface.
func IsNotPredicate ¶
func IsNotPredicate(predicate internal.PredicateOp) bool
IsNotPredicate checks if a predicate is negated using the PredicateOp interface.
func TestPredicate ¶
func TestPredicate(predicate internal.PredicateOp, doc interface{}) (bool, error)
TestPredicate tests a predicate operation using the PredicateOp interface.
func ToCompact ¶
func ToCompact(operation internal.Op) (internal.CompactOperation, error)
ToCompact converts an operation to compact format using the Op interface.
func ValidateOp ¶
ValidateOp validates an operation using the Op interface.
func ValidateOperation ¶
ValidateOperation validates a single JSON Patch operation.
func ValidateOperations ¶
ValidateOperations validates an array of JSON Patch operations.
Types ¶
type PatchResult ¶
type PatchResult[T Document] = internal.PatchResult[T]
type RegexMatcher ¶
type RegexMatcher = internal.RegexMatcher
JSON Patch types
func CreateMatcherDefault ¶
func CreateMatcherDefault(pattern string, ignoreCase bool) RegexMatcher
CreateMatcherDefault creates a default regular expression matcher.
Directories
¶
Path | Synopsis |
---|---|
codec
|
|
compact
Package compact implements a compact array-based codec for JSON Patch operations.
|
Package compact implements a compact array-based codec for JSON Patch operations. |
json
Package json implements JSON codec for JSON Patch operations.
|
Package json implements JSON codec for JSON Patch operations. |
examples
|
|
compact-codec
Package main demonstrates the compact codec functionality.
|
Package main demonstrates the compact codec functionality. |
pkg
|
|
tests
|
|