Skip to content

rogonion/go-json

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

22 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

go-json

A reflection-based library for manipulating dynamic, JSON-like data structures in Go. It provides tools for traversing, modifying, validating, and converting deeply nested objects (maps, structs, slices, arrays) using JSONPath.

Features

  • Dynamic Object Manipulation: Get, Set, Delete, and Iterate over values in deeply nested structures using JSONPath.
  • Schema Validation: Define schemas for your data and validate dynamic objects against them at runtime.
  • Type Conversion: Convert loosely typed data (e.g., map[string]any) into strongly typed Go structs, maps, and slices based on schema definitions.
  • Deserialization: Helpers for loading JSON and YAML data directly into schema-validated structures.
  • JSONPath Support: Supports dot notation, recursive descent (..), wildcards (*), unions (['a','b']), and array slicing ([start:end:step]).

Prerequisites

Tool Description Link
Go Official Website
Task

Task runner / build tool.

You can use the provided shell script taskw that automatically downloads the binary and installs it in the .task folder.

Official Website
Docker / Podman Optional container engine for isolated development environment. Docker / Podman

After building the dev container, below is a sample script that runs the container and mounts the project directory into the container:

#!/bin/bash

CONTAINER_ENGINE="podman"
CONTAINER="projects-go-json"
NETWORK="systemd-leap"
NETWORK_ALIAS="projects-go-json"
CONTAINER_UID=1000
IMAGE="localhost/projects/go-json:latest"
SSH_PORT="127.0.0.1:2200" # for local proxy vscode ssh access
PROJECT_DIRECTORY="$(pwd)"

# Check if container exists (Running or Stopped)
if $CONTAINER_ENGINE ps -a --format '{{.Names}}' | grep -q "^$CONTAINER$"; then
    echo "   Found existing container: $CONTAINER"
    # Check if it is currently running
    if $CONTAINER_ENGINE ps --format '{{.Names}}' | grep -q "^$CONTAINER$"; then
        echo "✅ Container is already running."
    else
        echo "🔄 Container stopped. Starting it..."
        $CONTAINER_ENGINE start $CONTAINER
        echo "✅ Started."
    fi
else
    # Container doesn't exist -> Create and Run it
    echo "🆕 Container not found. Creating new..."
    $CONTAINER_ENGINE run -d \
    # start container from scratch
    # `sudo` is used because systemd-leap network was created in `sudo`
    # Ensure container image exists in `sudo`
    # Not needed if target network is not in `sudo`
    sudo podman run -d \
        --name $CONTAINER \
        --network $NETWORK \
        --network-alias $NETWORK_ALIAS \
        --user $CONTAINER_UID:$CONTAINER_UID \
        -p $SSH_PORT:22 \
        -v $PROJECT_DIRECTORY:/home/dev/go-json:Z \
        $IMAGE
    echo "✅ Created and Started."
fi

Installation

go get github.com/rogonion/go-json

Environment Setup

This project uses Taskfile to manage the development environment and tasks.

Task Description Usage
env:build

Build the dev container image.

Image runs an ssh server one can connect to with vscode.

task env:build
env:info Show current environment configuration. task env:info
deps Download and tidy dependencies. task deps
test Run tests. Supports optional TARGET variable. task test
task test TARGET=./object

Modules

1. Object

The object package is the core of the library, allowing you to manipulate data structures.

Key Capabilities:

  • Get: Retrieve values.
  • Set: Update or insert values (auto-creates nested structures if schema is provided).
  • Delete: Remove values.
  • ForEach: Iterate over matches.
  • AreEqual: Deep comparison.

Example:

package main

import (
	"fmt"
	"github.com/rogonion/go-json/object"
)

func main() {
	data := map[string]any{
		"users": []any{
			map[string]any{"name": "Alice", "id": 1},
			map[string]any{"name": "Bob", "id": 2},
		},
	}

	obj := object.NewObject().WithSourceInterface(data)

	// Get
	val, _ := obj.Get("$.users[0].name")
	fmt.Println(obj.GetValueFoundInterface()) // Output: Alice

	// Set
	obj.Set("$.users[1].active", true)

	// Delete
	obj.Delete("$.users[0]")
}

2. Schema

The schema package allows you to define the expected structure of your data. This is useful for validation and conversion of dynamic data.

Example: Validation

package main

import (
	"reflect"
	"github.com/rogonion/go-json/schema"
)

func main() {
	// Define a schema
	userSchema := &schema.DynamicSchemaNode{
		Kind: reflect.Struct,
		Type: reflect.TypeOf(struct{ Name string; Age int }{}),
		ChildNodes: schema.ChildNodes{
			"Name": &schema.DynamicSchemaNode{Kind: reflect.String, Type: reflect.TypeOf("")},
			"Age":  &schema.DynamicSchemaNode{Kind: reflect.Int, Type: reflect.TypeOf(0)},
		},
	}

	validator := schema.NewValidation()
	data := map[string]any{"Name": "Alice", "Age": 30}
	
	// Validate
	ok, err := validator.ValidateData(data, userSchema)
}

Example: Conversion

package main

import (
	"reflect"
	"github.com/rogonion/go-json/schema"
)

func main() {
	// Define schema (same as above)
	// ...

	source := map[string]any{"Name": "Alice", "Age": "30"} // Age is string in source
	var dest struct{ Name string; Age int }

	converter := schema.NewConversion()
	// Converts and coerces types (string "30" -> int 30)
	err := converter.Convert(source, userSchema, &dest)
}

3. Path

The path package handles parsing of JSONPath strings. It is primarily used internally by the object package but can be used directly to inspect paths.

import "github.com/rogonion/go-json/path"

p := path.JSONPath("$.store.book[*].author")
segments := p.Parse()

Supported Data Types

The library supports reflection-based manipulation of:

  • Primitives: int (all sizes), uint (all sizes), float32/64, bool, string.
  • Collections: map, struct, slice, array.
  • Pointers: Pointers to any of the above.
  • Interfaces: any / interface{}.

About

A library for manipulating objects that resemble the structure and layout of JSON.

Resources

Stars

Watchers

Forks

Releases

Packages

Contributors

Languages