golang实现JSON文档任意转换的插件库kazaam的使用

Golang实现JSON文档任意转换的插件库kazaam的使用

简介

Kazaam是一个用于支持Golang中简单快速转换JSON数据的库。它提供了一种简单机制,可以将中间JSON消息表示转换为任意第三方API所需的格式。

Kazaam受到Jolt的启发,支持通过JSON定义的"规范"进行JSON到JSON的转换。一个规范由一个或多个"操作"组成。

特性

Kazaam主要设计用作转换任意JSON的库,它内置了六种转换类型:

  1. shift - 用于字段重映射
  2. concat - 组合字段和字面字符串
  3. coalesce - 检查多个可能的键以找到所需值
  4. extract - 选择子对象作为顶级对象
  5. timestamp - 解析和格式化时间字符串
  6. uuid - 生成UUID
  7. default - 显式设置键值
  8. delete - 删除键
  9. pass - 传递输入数据不变

安装

go get gopkg.in/qntfy/kazaam.v3

使用示例

基本使用

package main

import (
	"fmt"
	"log"

	"gopkg.in/qntfy/kazaam.v3"
)

func main() {
	// 输入JSON
	inputJSON := `{
		"doc": {
			"uid": 12345,
			"guid": ["guid0", "guid2", "guid4"],
			"guidObjects": [{"id": "guid0"}, {"id": "guid2"}, {"id": "guid4"}]
		}
	}`

	// 转换规范
	spec := `{
		"operation": "shift",
		"spec": {
			"object.id": "doc.uid",
			"gid2": "doc.guid[1]",
			"allGuids": "doc.guidObjects[*].id"
		}
	}`

	// 创建kazaam转换器
	k, err := kazaam.NewKazaam(spec)
	if err != nil {
		log.Fatal("Error creating kazaam instance:", err)
	}

	// 执行转换
	outputJSON, err := k.TransformJSONStringToString(inputJSON)
	if err != nil {
		log.Fatal("Error transforming JSON:", err)
	}

	fmt.Println(outputJSON)
}

Shift操作示例

// 输入JSON
input := `{
	"doc": {
		"uid": 12345,
		"guid": ["guid0", "guid2", "guid4"],
		"guidObjects": [{"id": "guid0"}, {"id": "guid2"}, {"id": "guid4"}]
	}
}`

// 转换规范
spec := `{
	"operation": "shift",
	"spec": {
		"object.id": "doc.uid",
		"gid2": "doc.guid[1]",
		"allGuids": "doc.guidObjects[*].id"
	}
}`

// 转换结果
output := `{
	"object": {
		"id": 12345
	},
	"gid2": "guid2",
	"allGuids": ["guid0", "guid2", "guid4"]
}`

Concat操作示例

// 输入JSON
input := `{
	"a": {
		"timestamp": 1481305274
	}
}`

// 转换规范
spec := `{
	"operation": "concat",
	"spec": {
		"sources": [{
			"value": "TEST"
		}, {
			"path": "a.timestamp"
		}],
		"targetPath": "a.timestamp",
		"delim": ","
	}
}`

// 转换结果
output := `{
	"a": {
		"timestamp": "TEST,1481305274"
	}
}`

UUID操作示例

// 输入JSON
input := `{
	"doc": {
		"author_id": 11122112,
		"document_id": 223323,
		"meta": {
			"id": 23
		}
	}
}`

// 转换规范
spec := `{
	"operation": "uuid",
	"spec": {
		"doc.uuid": {
			"version": 4
		}
	}
}`

// 转换结果
output := `{
	"doc": {
		"author_id": 11122112,
		"document_id": 223323,
		"meta": {
			"id": 23
		},
		"uuid": "f03bacc1-f4e0-4371-a5c5-e8160d3d6c0c"
	}
}`

多个操作组合

// 输入JSON
input := `{
	"user": {
		"id": 123,
		"name": "John Doe",
		"created_at": "Mon Jan 2 15:04:05 -0700 2006"
	}
}`

// 转换规范
spec := `[
	{
		"operation": "shift",
		"spec": {
			"userId": "user.id",
			"userName": "user.name",
			"timestamp": "user.created_at"
		}
	},
	{
		"operation": "timestamp",
		"timestamp": {
			"inputFormat": "Mon Jan _2 15:04:05 -0700 2006",
			"outputFormat": "2006-01-02T15:04:05-0700"
		}
	}
]`

// 转换结果
output := `{
	"userId": 123,
	"userName": "John Doe",
	"timestamp": "2006-01-02T15:04:05-0700"
}`

高级用法

自定义转换

Kazaam支持实现自定义转换类型。可以通过实现Transform接口并注册新类型来扩展功能。

type CustomTransform struct{}

func (t *CustomTransform) Transform(data []byte) ([]byte, error) {
	// 自定义转换逻辑
	return data, nil
}

func init() {
	kazaam.RegisterTransform("custom", &CustomTransform{})
}

错误处理

Kazaam提供了详细的错误处理机制,可以捕获转换过程中的各种错误:

output, err := k.TransformJSONStringToString(input)
if err != nil {
	switch e := err.(type) {
	case *kazaam.JSONPathError:
		fmt.Println("JSON路径错误:", e)
	case *kazaam.SpecError:
		fmt.Println("规范错误:", e)
	default:
		fmt.Println("未知错误:", e)
	}
}

Kazaam是一个功能强大的JSON转换库,特别适合需要将JSON数据从一种格式转换为另一种格式的场景。它的灵活性和可扩展性使其成为处理复杂JSON转换任务的理想选择。


更多关于golang实现JSON文档任意转换的插件库kazaam的使用的实战教程也可以访问 https://www.itying.com/category-94-b0.html

1 回复

更多关于golang实现JSON文档任意转换的插件库kazaam的使用的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


Kazaam - Golang JSON文档转换插件库

Kazaam是一个强大的Golang库,专门用于JSON文档的转换和操作。它允许你通过简单的配置来转换JSON结构,非常适合数据格式转换、API响应处理等场景。

安装Kazaam

go get github.com/qntfy/kazaam

基本使用

1. 简单字段转换

package main

import (
	"fmt"
	"log"

	"github.com/qntfy/kazaam"
)

func main() {
	// 原始JSON
	inputJSON := `{"user": {"name": "Alice", "age": 30}}`

	// 转换规则:将user.name提取到顶层username字段
	spec := `[{"operation": "shift", "spec": {"username": "user.name"}}]`

	// 创建Kazaam转换器
	k, err := kazaam.NewKazaam(spec)
	if err != nil {
		log.Fatal("Error creating Kazaam instance:", err)
	}

	// 执行转换
	outputJSON, err := k.TransformJSONStringToString(inputJSON)
	if err != nil {
		log.Fatal("Error transforming JSON:", err)
	}

	fmt.Println("Output JSON:", outputJSON)
	// 输出: {"username":"Alice"}
}

2. 复杂转换示例

package main

import (
	"fmt"
	"log"

	"github.com/qntfy/kazaam"
)

func main() {
	input := `{
		"user": {
			"id": 123,
			"name": "Bob",
			"contact": {
				"email": "bob@example.com",
				"phone": "123-456-7890"
			},
			"orders": [
				{"id": 1, "amount": 100},
				{"id": 2, "amount": 200}
			]
		}
	}`

	spec := `[
		{
			"operation": "shift",
			"spec": {
				"userId": "user.id",
				"userName": "user.name",
				"email": "user.contact.email",
				"phoneNumber": "user.contact.phone",
				"orderCount": {
					"operation": "size",
					"spec": "user.orders"
				},
				"totalSpent": {
					"operation": "sum",
					"spec": "user.orders[*].amount"
				}
			}
		}
	]`

	k, err := kazaam.NewKazaam(spec)
	if err != nil {
		log.Fatal(err)
	}

	output, err := k.TransformJSONStringToString(input)
	if err != nil {
		log.Fatal(err)
	}

	fmt.Println(output)
	/* 输出:
	{
		"userId": 123,
		"userName": "Bob",
		"email": "bob@example.com",
		"phoneNumber": "123-456-7890",
		"orderCount": 2,
		"totalSpent": 300
	}
	*/
}

主要功能特性

  1. 字段重命名和移动:使用shift操作可以轻松移动和重命名字段
  2. 数组操作:支持对数组进行过滤、映射等操作
  3. 计算操作:支持sumcountsize等聚合计算
  4. 条件转换:可以根据条件执行不同的转换规则
  5. 多步转换:支持定义多个转换步骤按顺序执行

高级用法示例

条件转换

package main

import (
	"fmt"
	"log"

	"github.com/qntfy/kazaam"
)

func main() {
	input := `{
		"user": {
			"name": "Charlie",
			"status": "premium"
		}
	}`

	spec := `[
		{
			"operation": "default",
			"spec": {
				"user.discount": "0%"
			}
		},
		{
			"operation": "shift",
			"spec": {
				"name": "user.name",
				"discount": {
					"operation": "conditional",
					"spec": {
						"condition": {
							"operation": "equal",
							"spec": {
								"left": "user.status",
								"right": "premium"
							}
						},
						"true": "20%",
						"false": "user.discount"
					}
				}
			}
		}
	]`

	k, err := kazaam.NewKazaam(spec)
	if err != nil {
		log.Fatal(err)
	}

	output, err := k.TransformJSONStringToString(input)
	if err != nil {
		log.Fatal(err)
	}

	fmt.Println(output)
	// 输出: {"name":"Charlie","discount":"20%"}
}

数组操作

package main

import (
	"fmt"
	"log"

	"github.com/qntfy/kazaam"
)

func main() {
	input := `{
		"products": [
			{"id": 1, "name": "Laptop", "price": 999.99, "inStock": true},
			{"id": 2, "name": "Mouse", "price": 19.99, "inStock": false},
			{"id": 3, "name": "Keyboard", "price": 49.99, "inStock": true}
		]
	}`

	spec := `[
		{
			"operation": "shift",
			"spec": {
				"availableProducts": {
					"operation": "filter",
					"spec": {
						"input": "products",
						"condition": {
							"operation": "equal",
							"spec": {
								"left": "@inStock",
								"right": true
							}
						}
					}
				},
				"totalAvailable": {
					"operation": "size",
					"spec": {
						"operation": "filter",
						"spec": {
							"input": "products",
							"condition": {
								"operation": "equal",
								"spec": {
									"left": "@inStock",
									"right": true
								}
							}
						}
					}
				}
			}
		}
	]`

	k, err := kazaam.NewKazaam(spec)
	if err != nil {
		log.Fatal(err)
	}

	output, err := k.TransformJSONStringToString(input)
	if err != nil {
		log.Fatal(err)
	}

	fmt.Println(output)
	/* 输出:
	{
		"availableProducts": [
			{"id": 1, "name": "Laptop", "price": 999.99, "inStock": true},
			{"id": 3, "name": "Keyboard", "price": 49.99, "inStock": true}
		],
		"totalAvailable": 2
	}
	*/
}

性能考虑

Kazaam在性能方面表现良好,但在处理大型JSON文档或复杂转换规则时,仍需注意:

  1. 尽量合并多个转换步骤
  2. 避免不必要的深层嵌套
  3. 对于超大型文档,考虑流式处理

总结

Kazaam为Golang开发者提供了一个强大而灵活的JSON转换工具,通过简单的配置即可实现复杂的JSON结构转换。它的主要优势在于:

  • 声明式的转换规则
  • 丰富的内置操作
  • 良好的性能
  • 易于集成到现有项目中

对于需要处理不同JSON格式的微服务、API网关等场景,Kazaam是一个非常值得考虑的选择。

回到顶部