Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

json_en.md

maoxiaoyue edited this page May 14, 2026 · 1 revision

JSON Package (pkg/json)

The json package provides advanced JSON processing capabilities for HypGo. Built on encoding/json, it integrates go-playground/validator/v10 for data validation during serialization and deserialization, and provides map/JSON conversion utilities and input sanitization functions.

Key Features

  • Powerful Struct Validation: Integrates validator within ValidatedUnmarshal, completing validation during parsing.
  • JSON Schema Support: Provides JSON Schema-like property validation (ValidateWithSchema), including required fields, length, regular expressions, and enum restrictions.
  • Typed Unmarshal: Provides TypedUnmarshal for automatic type-safe conversion to match the target struct's fields.
  • Unified Error Format: Automatically organizes validator.ValidationErrors into structured ValidationError, making it easy for APIs to return clear error messages to the frontend.
  • Custom Validation: Provides RegisterValidation for custom tags, allowing developers to easily extend validation logic.
  • Convert Utilities: Bidirectional map ↔ JSON conversion (string, bytes, formatted indent).
  • Input Utilities: Built-in Email / Phone format validation and HTML input sanitization.

Validator

Struct Validation Parsing

Create a Validator to validate required fields, email format, and more via struct tags (validate:"...") during JSON parsing:

import hypjson "github.com/maoxiaoyue/hypgo/pkg/json"
type UserRequest struct {
 Name string `json:"name" validate:"required"`
 Email string `json:"email" validate:"required,email"`
 Age int `json:"age" validate:"min=18"`
}
v := hypjson.NewValidator()
data := []byte(`{"name": "Alice", "email": "alice@example", "age": 16}`)
var req UserRequest
err := v.ValidatedUnmarshal(data, &req)
if err != nil {
 errs := v.FormatErrors(err)
 for _, e := range errs {
 fmt.Printf("Field %s error: %s\n", e.Field, e.Message)
 }
}

TypedUnmarshal

Parses JSON with automatic type conversion based on the target struct's field types. Returns a clear error if types are incompatible:

type Config struct {
 Port int `json:"port"`
 Timeout float64 `json:"timeout"`
 Debug bool `json:"debug"`
}
data := []byte(`{"port": 8080, "timeout": 30.5, "debug": true}`)
var cfg Config
if err := hypjson.TypedUnmarshal(data, &cfg); err != nil {
 log.Fatal(err)
}
// cfg.Port = 8080, cfg.Timeout = 30.5, cfg.Debug = true

The difference from ValidatedUnmarshal: TypedUnmarshal does not execute validate tag checks — it focuses solely on type conversion safety.

Validation Error Format

FormatErrors converts validator.ValidationErrors into a structured []ValidationError, where each error contains the field name, validation rule, original value, and a human-readable message:

type ValidationError struct {
 Field string
 Tag string
 Value interface{}
 Message string
}
errs := v.FormatErrors(err)
for _, e := range errs {
 // e.Field -> "email"
 // e.Tag -> "email"
 // e.Message -> "email must be a valid email address"
 fmt.Printf("[%s] %s\n", e.Field, e.Message)
}

Built-in message mappings:

Tag Message Format
required {field} is required
email {field} must be a valid email address
min {field} must be at least {param}
max {field} must not exceed {param}
others {field} failed {tag} validation

Custom Validation Rules

v := hypjson.NewValidator()
// Custom "taiwan_phone" validation rule
v.RegisterValidation("taiwan_phone", func(fl validator.FieldLevel) bool {
 phone := fl.Field().String()
 return strings.HasPrefix(phone, "09") && len(phone) == 10
})
type ContactForm struct {
 Phone string `json:"phone" validate:"required,taiwan_phone"`
}

JSON Schema Validation

Apply a Schema definition to dynamic or non-Go-struct-defined JSON data:

minLen := 3
maxLen := 20
schema := hypjson.Schema{
 Type: "object",
 Required: []string{"username"},
 Properties: map[string]hypjson.Property{
 "username": {
 Type: "string",
 MinLength: &minLen,
 MaxLength: &maxLen,
 },
 "age": {
 Type: "number",
 Minimum: func() *float64 { v := 0.0; return &v }(),
 Maximum: func() *float64 { v := 150.0; return &v }(),
 },
 "status": {
 Type: "string",
 Enum: []string{"active", "inactive", "pending"},
 },
 "email": {
 Type: "string",
 Pattern: `^[^@]+@[^@]+\.[^@]+$`,
 },
 },
}
data := []byte(`{"username": "Al", "status": "unknown"}`)
if err := hypjson.ValidateWithSchema(data, schema); err != nil {
 log.Println("Schema validation failed:", err)
}

Supported Property fields:

Field Type Description
Type string "string", "number", "integer", "boolean", "array", "object"
MinLength *int Minimum string length
MaxLength *int Maximum string length
Minimum *float64 Numeric lower bound
Maximum *float64 Numeric upper bound
Pattern string Regular expression
Enum []string Allowed values
Format string Format hint (documentation only, no validation)

Marshal / MarshalCompact

type Response struct {
 ID int `json:"id"`
 Name string `json:"name"`
}
resp := Response{ID: 1, Name: "Alice"}
// With indentation (human-readable)
b, _ := hypjson.Marshal(resp)
fmt.Println(string(b))
// {
// "id": 1,
// "name": "Alice"
// }
// Compact format (for transport)
b, _ = hypjson.MarshalCompact(resp)
fmt.Println(string(b))
// {"id":1,"name":"Alice"}

Convert

convert.go provides bidirectional map ↔ JSON conversion with five functions. A nil map always returns "null"; empty input returns an error.

Map → JSON

m := map[string]interface{}{
 "name": "Alice",
 "age": 30,
 "tags": []string{"admin", "user"},
}
// Compact string
s, err := hypjson.Map2JSON(m)
// -> {"age":30,"name":"Alice","tags":["admin","user"]}
// Formatted string (prefix="", indent=" ")
s, err = hypjson.Map2JSONIndent(m, "", " ")
// -> {
// "age": 30,
// "name": "Alice",
// "tags": ["admin","user"]
// }
// Compact bytes (for direct use in HTTP responses)
b, err := hypjson.Map2JSONBytes(m)

Nil map behavior:

s, _ := hypjson.Map2JSON(nil) // -> "null"
b, _ := hypjson.Map2JSONBytes(nil) // -> []byte("null")

JSON → Map

// Parse from string
m, err := hypjson.JSON2Map(`{"name":"Alice","age":30}`)
// m["name"] == "Alice", m["age"] == float64(30)
// Parse from bytes
b := []byte(`{"key":"value"}`)
m, err = hypjson.JSON2MapBytes(b)

Note: numeric types are uniformly float64 after JSON parsing (standard encoding/json behavior).

Full Conversion Flow Example

// Scenario: receive JSON request -> modify field -> return JSON
raw := []byte(`{"user":"alice","score":100}`)
m, err := hypjson.JSON2MapBytes(raw)
if err != nil {
 return err
}
m["score"] = m["score"].(float64) + 10 // score + 10
result, err := hypjson.Map2JSON(m)
// -> {"score":110,"user":"alice"}

Input

input.go provides input format validation and XSS protection sanitization.

ValidateEmail

Validates email format using a regular expression (^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$):

hypjson.ValidateEmail("alice@example.com") // -> true
hypjson.ValidateEmail("alice@example") // -> false
hypjson.ValidateEmail("not-an-email") // -> false

ValidatePhone

Validates phone numbers in E.164 format (^\+?[1-9]\d{1,14}$):

hypjson.ValidatePhone("+886912345678") // -> true
hypjson.ValidatePhone("0912345678") // -> false (E.164 format required)
hypjson.ValidatePhone("+1-800-555") // -> false

SanitizeInput

Converts HTML special characters to HTML entities to prevent XSS injection:

raw := `<script>alert("xss")</script>`
safe := hypjson.SanitizeInput(raw)
// -> &lt;script&gt;alert(&quot;xss&quot;)&lt;/script&gt;

Conversion table:

Character Converted To
< &lt;
> &gt;
" &quot;
' &#x27;

Combined usage example (sanitize JSON input before storing):

type CommentRequest struct {
 Content string `json:"content" validate:"required,max=500"`
}
v := hypjson.NewValidator()
var req CommentRequest
if err := v.ValidatedUnmarshal(data, &req); err != nil {
 return err
}
// Sanitize user input before storing to database
req.Content = hypjson.SanitizeInput(req.Content)

Quick Reference

Validator

Function / Method Description
NewValidator() Create a Validator (auto uses json tag as field name)
v.ValidatedUnmarshal(data, dest) Parse JSON and run validate tag checks
TypedUnmarshal(data, dest) Parse JSON with type-safe conversion (no validation)
ValidateWithSchema(data, schema) Validate raw JSON against a Schema definition
v.FormatErrors(err) Convert validation errors to []ValidationError
v.RegisterValidation(tag, fn) Register a custom validation rule
Marshal(v) Serialize with indentation
MarshalCompact(v) Serialize compact (no indentation)

Convert

Function Description
Map2JSON(m) map → JSON string (compact)
Map2JSONIndent(m, prefix, indent) map → JSON string (formatted)
Map2JSONBytes(m) map → JSON bytes (compact)
JSON2Map(s) JSON string → map
JSON2MapBytes(b) JSON bytes → map

Input

Function Description
ValidateEmail(email) Validate email format, returns bool
ValidatePhone(phone) Validate E.164 phone format, returns bool
SanitizeInput(input) Escape HTML special characters (XSS protection)

File Structure

pkg/json/
├── validator.go # Validator, ValidatedUnmarshal, TypedUnmarshal,
│ # ValidateWithSchema, Marshal, FormatErrors, RegisterValidation
├── convert.go # Map2JSON, Map2JSONIndent, Map2JSONBytes, JSON2Map, JSON2MapBytes
├── input.go # ValidateEmail, ValidatePhone, SanitizeInput
├── validator_test.go
└── convert_test.go

HypGo

繁體中文 | English


中文文件

設計文件

套件

AI 協作工具鏈

CLI 命令


English Docs

Design Docs

Packages

AI Collaboration Toolchain

CLI Commands

Clone this wiki locally

AltStyle によって変換されたページ (->オリジナル) /