0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

GoでJsonShcemaを利用する

Posted at

はじめに

表題通り、GoでJsonShcemaを利用します。

実装

~/go/go_json_schema  $ tree 
.
├── go.mod
├── go.sum
├── schema.go
└── schema_test.go

1 directory, 4 files
schema.go
package main

import (
	"encoding/json"
)

// JSONをGoの構造体に変換するための定義
type Person struct {
	FirstName string `json:"firstName"`
	LastName  string `json:"lastName"`
	Age       int    `json:"age,omitempty"`
	Email     string `json:"email,omitempty"`
}

// JSONデータを構造体に変換する関数
func ParsePerson(data []byte) (Person, error) {
	var person Person
	err := json.Unmarshal(data, &person)
	return person, err
}
schema_test.go
package main

import (
	"encoding/json"
	"fmt"
	"strings"
	"testing"

	"github.com/santhosh-tekuri/jsonschema/v5"
)

// JSON Schemaの定義
var personSchema = []byte(`{
	"$schema": "http://json-schema.org/draft-07/schema#",
	"title": "Person",
	"type": "object",
	"properties": {
		"firstName": { "type": "string" },
		"lastName": { "type": "string" },
		"age": { 
			"type": "integer",
			"minimum": 0
		},
		"email": { 
			"type": "string",
			"format": "email"
		}
	},
	"required": ["firstName", "lastName"]
}`)

// 有効なJSONデータ
var validPersonData = []byte(`{
	"firstName": "太郎",
	"lastName": "山田",
	"age": 30,
	"email": "taro@example.com"
}`)

// 無効なJSONデータ(必須フィールドがない)
var invalidPersonData = []byte(`{
	"firstName": "太郎"
}`)

func TestPersonSchema(t *testing.T) {
	// スキーマのコンパイル
	compiler := jsonschema.NewCompiler()
	if err := compiler.AddResource("person.json", strings.NewReader(string(personSchema))); err != nil {
		t.Fatalf("スキーマの追加エラー: %v", err)
	}
	schema, err := compiler.Compile("person.json")
	if err != nil {
		t.Fatalf("スキーマのコンパイルエラー: %v", err)
	}

	// テストケース
	tests := []struct {
		name    string
		data    []byte
		isValid bool
	}{
		{
			name:    "有効なデータ",
			data:    validPersonData,
			isValid: true,
		},
		{
			name:    "無効なデータ(必須フィールドがない)",
			data:    invalidPersonData,
			isValid: false,
		},
	}

	// 各テストケースを実行
	for _, tt := range tests {
		t.Run(tt.name, func(t *testing.T) {
			// JSONをインターフェースに変換
			var personObj interface{}
			if err := json.Unmarshal(tt.data, &personObj); err != nil {
				t.Fatalf("JSONのパースエラー: %v", err)
			}

			// スキーマに対して検証
			err := schema.Validate(personObj)
			if tt.isValid && err != nil {
				t.Errorf("有効なはずのデータが無効と判定: %v", err)
			}
			if !tt.isValid && err == nil {
				t.Errorf("無効なはずのデータが有効と判定")
			}
			fmt.Println("============== personObj", personObj)

			// エラーの内容を表示(デバッグ用)
			if err != nil {
				fmt.Printf("検証エラー (%s): %v\n", tt.name, err)
			}
		})
	}
}

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?