jsonextracter

package
v0.5.3-beta.0 Latest Latest
Warning

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

Go to latest
Published: Sep 12, 2024 License: Apache-2.0 Imports: 5 Imported by: 0

README

JSON Extracter

Extract specific field from JSON and output not only the field value but also its upstream structure.

A typical use case is to trim k8s objects in TransformingInformer to save informer memory.

Please refer to JSONPath Support to see JSONPath usage.

Example

Code:

package main

import (
	"encoding/json"
	"fmt"

	"kusionstack.io/kube-utils/jsonextracter"
)

var pod = []byte(`{
    "apiVersion": "v1",
    "kind": "Pod",
    "metadata": {
        "labels": {
            "name": "pause",
            "app": "pause"
        },
        "name": "pause",
        "namespace": "default"
    },
    "spec": {
        "containers": [
            {
                "image": "registry.k8s.io/pause:3.8",
                "imagePullPolicy": "IfNotPresent",
                "name": "pause1"
            },
            {
                "image": "registry.k8s.io/pause:3.8",
                "imagePullPolicy": "IfNotPresent",
                "name": "pause2"
            }
        ]
    }
}`)

func printJSON(data interface{}) {
	bytes, _ := json.Marshal(data)
	fmt.Println(string(bytes))
}

func main() {
	var podData map[string]interface{}
	json.Unmarshal(pod, &podData)

	kindPath := "{.kind}"
	kindExtracter, _ := jsonextracter.BuildExtracter(kindPath, false)

	kind, _ := kindExtracter.Extract(podData)
	printJSON(kind)

	nameImagePath := "{.spec.containers[*]['name', 'image']}"
	nameImageExtracter, _ := jsonextracter.BuildExtracter(nameImagePath, false)

	nameImage, _ := nameImageExtracter.Extract(podData)
	printJSON(nameImage)

	merged, _ := jsonextracter.Merge([]jsonextracter.Extracter{kindExtracter, nameImageExtracter}, podData)
	printJSON(merged)
}

Output:

{"kind":"Pod"}
{"spec":{"containers":[{"image":"registry.k8s.io/pause:3.8","name":"pause1"},{"image":"registry.k8s.io/pause:3.8","name":"pause2"}]}}
{"kind":"Pod","spec":{"containers":[{"image":"registry.k8s.io/pause:3.8","name":"pause1"},{"image":"registry.k8s.io/pause:3.8","name":"pause2"}]}}

Note

The merge behavior of the jsonextracter.Merge on the list is replacing. Therefore, if you retrieve the container name and image separately and merge them, the resulting output will not contain the image.

Code:

    ...
	namePath := "{.spec.containers[*].name}"
	nameExtracter, _ := jsonextracter.BuildExtracter(namePath, false)

	imagePath := "{.spec.containers[*].image}"
	imageExtracter, _ := jsonextracter.BuildExtracter(imagePath, false)

	merged, _ = jsonextracter.Merge([]jsonextracter.Extracter{imageExtracter, nameExtracter}, podData)
	printJSON(merged)
    ...

Output:

{"spec":{"containers":[{"name":"pause1"},{"name":"pause2"}]}}

Documentation

Index

Constants

This section is empty.

Variables

View Source
var Parse = jsonpath.Parse

Functions

func Merge

func Merge(extracters []Extracter, input map[string]interface{}) (map[string]interface{}, error)

Merge is a helper function that calls all extracters and merges their outputs by calling MergeFields.

func MergeFields

func MergeFields(dst, src map[string]interface{}) map[string]interface{}

MergeFields merges src into dst.

Note: the merge operation on two nested list is replacing.

func NestedFieldNoCopy

func NestedFieldNoCopy(data map[string]interface{}, allowMissingKeys bool, fields ...string) (map[string]interface{}, error)

NestedFieldNoCopy is similar to JSONPath.Extract. The difference is that it can only operate on map and does not support list, but has better performance.

Types

type ArrayNode

type ArrayNode = jsonpath.ArrayNode

type BoolNode

type BoolNode = jsonpath.BoolNode

type Extracter

type Extracter interface {
	Extract(data map[string]interface{}) (map[string]interface{}, error)
}

func BuildExtracter

func BuildExtracter(jsonPath string, allowMissingKeys bool) (Extracter, error)

BuildExtracter automatically determines whether to use FieldPathExtracter or JSONPathExtracter. If the input jsonPath only involves map operations, it will return FieldPathExtracter, as it has better performance.

type FieldNode

type FieldNode = jsonpath.FieldNode

type FilterNode

type FilterNode = jsonpath.FilterNode

type FloatNode

type FloatNode = jsonpath.FloatNode

type IdentifierNode

type IdentifierNode = jsonpath.IdentifierNode

type IntNode

type IntNode = jsonpath.IntNode

type JSONPath

type JSONPath struct {
	// contains filtered or unexported fields
}

func New

func New(name string) *JSONPath

New creates a new JSONPath with the given name.

func (*JSONPath) AllowMissingKeys

func (j *JSONPath) AllowMissingKeys(allow bool) *JSONPath

AllowMissingKeys allows a caller to specify whether they want an error if a field or map key cannot be located, or simply an empty result. The receiver is returned for chaining.

func (*JSONPath) Extract

func (j *JSONPath) Extract(data map[string]interface{}) (map[string]interface{}, error)

Extract outputs the field specified by JSONPath. The output contains not only the field value, but also its upstream structure.

The data structure of the extracted field must be of type `map[string]interface{}`, and `struct` is not supported (an error will be returned).

func (*JSONPath) FindResults

func (j *JSONPath) FindResults(data interface{}, setFn setFieldFunc) ([][]reflect.Value, error)

func (*JSONPath) Parse

func (j *JSONPath) Parse(text string) error

Parse parses the given template and returns an error.

type ListNode

type ListNode = jsonpath.ListNode

type NestedFieldPath

type NestedFieldPath struct {
	// contains filtered or unexported fields
}

NestedFieldPath is used to wrap NestedFieldNoCopy function as an Extracter.

func NewNestedFieldPath

func NewNestedFieldPath(nestedField []string, allowMissingKeys bool) *NestedFieldPath

NewNestedFieldPath constructs a FieldPathExtracter.

func (*NestedFieldPath) Extract

func (f *NestedFieldPath) Extract(data map[string]interface{}) (map[string]interface{}, error)

Extract outputs the nestedField's value and its upstream structure.

type Node

type Node = jsonpath.Node

type Parser

type Parser = jsonpath.Parser

type RecursiveNode

type RecursiveNode = jsonpath.RecursiveNode

type TextNode

type TextNode = jsonpath.TextNode

type UnionNode

type UnionNode = jsonpath.UnionNode

type WildcardNode

type WildcardNode = jsonpath.WildcardNode

Jump to

Keyboard shortcuts

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