Open4

V 言語で json を動的に扱いたい

zztkmzztkm

目的

vss というツールでサイトをビルドするときに microCMS などから json データでサイトのコンテンツを取得してビルド時に HTML を生成したいが、取得できる json はユーザーごとに異なる可能性が高いのでフィールド名などはプログラム外部の設定ファイルに保存しておいてビルドコマンド実行時に動的に json を解析する処理を実装したいので、実現できるか調査する

zztkmzztkm

決まった形式の json を構造体にバインドする

module main

import json
import time

struct Article {
	id         string
	created_at string [json: createdAt]
	updated_at string [json: updatedAt]
	title      string
	content    string
}

fn main() {
	data := '{ "id": "testid", "createdAt": "2022-09-24T04:45:05.593Z", "updatedAt": "2022-09-24T04:46:26.946Z", "title": "test article", "content": "<h2>test</h2>"}'
	article := json.decode(Article, data) or {
		eprintln('failed to decode json, error: $err')
		return
	}

	println(article.id)
	println(article.title)
	println(article.content)
	// refs: https://modules.vlang.io/time.html#parse_iso8601
	println(time.parse_iso8601(article.created_at)?)
	println(time.parse_iso8601(article.updated_at)?)
}

output:

v run normal.v 
testid
test article
<h2>test</h2>
2022-09-24 04:45:05
2022-09-24 04:46:26
zztkmzztkm

map[string]string につっこむ

// map[string]string に json をバインドする
module main

import json

fn main() {
	data := '{ "id": "testid", "createdAt": "2022-09-24T04:45:05.593Z", "updatedAt": "2022-09-24T04:46:26.946Z", "title": "test article", "content": "<h2>test</h2>"}'
	article := json.decode(map[string]string, data) or {
		eprintln('failed to decode json, error: $err')
		return
	}

	println(article['id'])
	println(article['title'])
	println(article['content'])
	println(article['createdAt'])
	println(article['updatedAt'])
}

output:

v run string_map.v 
testid
test article
<h2>test</h2>
2022-09-24T04:45:05.593Z
2022-09-24T04:46:26.946Z
zztkmzztkm

x.json2 を使って json を map[string]json2.Any にする

https://modules.vlang.io/x.json2.html

module main

import x.json2

fn main() {
	data := '{ "id": "testid", "createdAt": "2022-09-24T04:45:05.593Z", "updatedAt": "2022-09-24T04:46:26.946Z", "title": "test article", "content": "<h2>test</h2>"}'
	row_article := json2.raw_decode(data) or {
		eprintln('failed to decode json, error: $err')
		return
	}

	article := row_article.as_map() // map[string]json2.Any

	println(article['id'].str())
	println(article['title'].str())
	println(article['content'].str())
	println(article['createdAt'].str())
	println(article['updatedAt'].str())
}

output:

testid
test article
<h2>test</h2>
2022-09-24T04:45:05.593Z
2022-09-24T04:46:26.946Z