JSON Type Definition, aka RFC 8927, is an easy-to-learn, portable, and standardized way to describe the shape of your JSON data.
{
"properties": {
"id": { "type": "string" },
"createdAt": { "type": "timestamp" },
"karma": { "type": "int32" },
"isAdmin": { "type": "boolean" }
}
}
export interface User {
createdAt: string;
id: string;
isAdmin: boolean;
karma: number;
}
package user
import "time"
type User struct {
CreatedAt time.Time `json:"created_at"`
ID string `json:"id"`
IsAdmin bool `json:"isAdmin"`
Karma int32 `json:"karma"`
}
package com.example;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import java.time.OffsetDateTime;
@JsonSerialize
public class User {
@JsonProperty("createdAt")
private OffsetDateTime createdAt;
@JsonProperty("id")
private String id;
@JsonProperty("isAdmin")
private Boolean isAdmin;
@JsonProperty("karma")
private Integer karma;
public User() {
}
public OffsetDateTime getCreatedAt() {
return this.createdAt;
}
public void setCreatedAt(OffsetDateTime createdAt) {
this.createdAt = createdAt;
}
public String getId() {
return this.id;
}
public void setId(String id) {
this.id = id;
}
public Boolean getIsAdmin() {
return this.isAdmin;
}
public void setIsAdmin(Boolean isAdmin) {
this.isAdmin = isAdmin;
}
public Integer getKarma() {
return this.karma;
}
public void setKarma(Integer karma) {
this.karma = karma;
}
}
using System;
using System.Text.Json.Serialization;
namespace Contoso.Example
{
public class User
{
[JsonPropertyName("createdAt")]
public DateTimeOffset CreatedAt { get; set; }
[JsonPropertyName("id")]
public string Id { get; set; }
[JsonPropertyName("isAdmin")]
public bool IsAdmin { get; set; }
[JsonPropertyName("karma")]
public int Karma { get; set; }
}
}
from dataclasses import dataclass
from typing import Any, Optional, Union, get_args, get_origin
@dataclass
class User:
created_at: 'str'
id: 'str'
is_admin: 'bool'
karma: 'int'
@classmethod
def from_json(cls, data) -> "User":
"""
Construct an instance of this class from parsed JSON data.
"""
return cls(
_from_json(str, data.get("createdAt")),
_from_json(str, data.get("id")),
_from_json(bool, data.get("isAdmin")),
_from_json(int, data.get("karma")),
)
def to_json(self):
"""
Generate JSON-ready data from an instance of this class.
"""
out = {}
out["createdAt"] = _to_json(self.created_at)
out["id"] = _to_json(self.id)
out["isAdmin"] = _to_json(self.is_admin)
out["karma"] = _to_json(self.karma)
return out
def _from_json(cls, data):
if data is None or cls in [bool, int, float, str, object] or cls is Any:
return data
if get_origin(cls) is Union:
return _from_json(get_args(cls)[0], data)
if get_origin(cls) is list:
return [_from_json(get_args(cls)[0], d) for d in data]
if get_origin(cls) is dict:
return { k: _from_json(get_args(cls)[1], v) for k, v in data.items() }
return cls.from_json(data)
def _to_json(data):
if data is None or type(data) in [bool, int, float, str, object]:
return data
if type(data) is list:
return [_to_json(d) for d in data]
if type(data) is dict:
return { k: _to_json(v) for k, v in data.items() }
return data.to_json()
use chrono::{DateTime, FixedOffset};
use serde::{Deserialize, Serialize};
#[derive(Serialize, Deserialize)]
pub struct User {
#[serde(rename = "createdAt")]
pub createdAt: DateTime<FixedOffset>,
#[serde(rename = "id")]
pub id: String,
#[serde(rename = "isAdmin")]
pub isAdmin: bool,
#[serde(rename = "karma")]
pub karma: i32,
}
A better way to work with JSON
JSON Type Definition is a lightweight schema language for JSON data. Describe the shape of your data once, and get portable validators and types across many languages.
Most developers can learn the entire JSON Typedef specification in about five to ten minutes.
Specific validation errors are part of the JTD spec. Every implementation returns the same errors.
The jtd-codegen
tool can
consistently generate code in many programming
languages from any schema.
Want to add JSON Typedef to an existing system?
jtd-infer
can generate a schema from examples of your data.
Once you have a schema,
jtd-fuzz
can generate mocks of your data. Generate seed data or
load-testing workloads with ease.
JSON Typedef schemas are just plain old JSON, so you can embed them in your organization's JSON (or YAML) custom tools.