CINXE.COM

JSON Schema

<!DOCTYPE html><html lang="en"><head><meta charSet="utf-8"/><link rel="icon" type="image/svg+xml" href="/favicon.ico" id="light-scheme-icon"/><title>JSON Schema</title><meta name="description" content="JSON Schema"/><meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1"/><meta name="next-head-count" content="5"/><link rel="preconnect" href="https://fonts.googleapis.com"/><link rel="preconnect" href="https://fonts.gstatic.com" crossorigin=""/><link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@docsearch/css@3"/><link rel="preconnect" href="https://fonts.gstatic.com" crossorigin /><link rel="preload" href="/_next/static/css/34913bc405145d4b.css" as="style"/><link rel="stylesheet" href="/_next/static/css/34913bc405145d4b.css" data-n-g=""/><noscript data-n-css=""></noscript><script defer="" nomodule="" src="/_next/static/chunks/polyfills-42372ed130431b0a.js"></script><script src="/_next/static/chunks/webpack-cefddfb7403e4fd5.js" defer=""></script><script src="/_next/static/chunks/framework-945b357d4a851f4b.js" defer=""></script><script src="/_next/static/chunks/main-569bf1064c37a2fd.js" defer=""></script><script src="/_next/static/chunks/pages/_app-a37fb3b7de047120.js" defer=""></script><script src="/_next/static/chunks/7705-ef012549a553fce5.js" defer=""></script><script src="/_next/static/chunks/8764-fb7e4b7b8d2adabd.js" defer=""></script><script src="/_next/static/chunks/5843-480b1c85882ef888.js" defer=""></script><script src="/_next/static/chunks/9162-89a298199367bf04.js" defer=""></script><script src="/_next/static/chunks/4954-921a08b3498ccd83.js" defer=""></script><script src="/_next/static/chunks/pages/index-0c3b6b15496c5e41.js" defer=""></script><script src="/_next/static/prM2jgCA24QEAGPj8U6zr/_buildManifest.js" defer=""></script><script src="/_next/static/prM2jgCA24QEAGPj8U6zr/_ssgManifest.js" defer=""></script><style data-href="https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700;900&family=JetBrains+Mono:wght@300;400&display=swap">@font-face{font-family:'Inter';font-style:normal;font-weight:300;font-display:swap;src:url(https://fonts.gstatic.com/s/inter/v18/UcCO3FwrK3iLTeHuS_nVMrMxCp50SjIw2boKoduKmMEVuOKfMZs.woff) format('woff')}@font-face{font-family:'Inter';font-style:normal;font-weight:400;font-display:swap;src:url(https://fonts.gstatic.com/s/inter/v18/UcCO3FwrK3iLTeHuS_nVMrMxCp50SjIw2boKoduKmMEVuLyfMZs.woff) format('woff')}@font-face{font-family:'Inter';font-style:normal;font-weight:500;font-display:swap;src:url(https://fonts.gstatic.com/s/inter/v18/UcCO3FwrK3iLTeHuS_nVMrMxCp50SjIw2boKoduKmMEVuI6fMZs.woff) format('woff')}@font-face{font-family:'Inter';font-style:normal;font-weight:600;font-display:swap;src:url(https://fonts.gstatic.com/s/inter/v18/UcCO3FwrK3iLTeHuS_nVMrMxCp50SjIw2boKoduKmMEVuGKYMZs.woff) format('woff')}@font-face{font-family:'Inter';font-style:normal;font-weight:700;font-display:swap;src:url(https://fonts.gstatic.com/s/inter/v18/UcCO3FwrK3iLTeHuS_nVMrMxCp50SjIw2boKoduKmMEVuFuYMZs.woff) format('woff')}@font-face{font-family:'Inter';font-style:normal;font-weight:900;font-display:swap;src:url(https://fonts.gstatic.com/s/inter/v18/UcCO3FwrK3iLTeHuS_nVMrMxCp50SjIw2boKoduKmMEVuBWYMZs.woff) format('woff')}@font-face{font-family:'JetBrains Mono';font-style:normal;font-weight:300;font-display:swap;src:url(https://fonts.gstatic.com/s/jetbrainsmono/v20/tDbY2o-flEEny0FZhsfKu5WU4zr3E_BX0PnT8RD8lqxjPg.woff) format('woff')}@font-face{font-family:'JetBrains Mono';font-style:normal;font-weight:400;font-display:swap;src:url(https://fonts.gstatic.com/s/jetbrainsmono/v20/tDbY2o-flEEny0FZhsfKu5WU4zr3E_BX0PnT8RD8yKxjPg.woff) format('woff')}@font-face{font-family:'Inter';font-style:normal;font-weight:300;font-display:swap;src:url(https://fonts.gstatic.com/s/inter/v18/UcC73FwrK3iLTeHuS_nVMrMxCp50SjIa2JL7W0Q5n-wU.woff2) format('woff2');unicode-range:U+0460-052F,U+1C80-1C8A,U+20B4,U+2DE0-2DFF,U+A640-A69F,U+FE2E-FE2F}@font-face{font-family:'Inter';font-style:normal;font-weight:300;font-display:swap;src:url(https://fonts.gstatic.com/s/inter/v18/UcC73FwrK3iLTeHuS_nVMrMxCp50SjIa0ZL7W0Q5n-wU.woff2) format('woff2');unicode-range:U+0301,U+0400-045F,U+0490-0491,U+04B0-04B1,U+2116}@font-face{font-family:'Inter';font-style:normal;font-weight:300;font-display:swap;src:url(https://fonts.gstatic.com/s/inter/v18/UcC73FwrK3iLTeHuS_nVMrMxCp50SjIa2ZL7W0Q5n-wU.woff2) format('woff2');unicode-range:U+1F00-1FFF}@font-face{font-family:'Inter';font-style:normal;font-weight:300;font-display:swap;src:url(https://fonts.gstatic.com/s/inter/v18/UcC73FwrK3iLTeHuS_nVMrMxCp50SjIa1pL7W0Q5n-wU.woff2) format('woff2');unicode-range:U+0370-0377,U+037A-037F,U+0384-038A,U+038C,U+038E-03A1,U+03A3-03FF}@font-face{font-family:'Inter';font-style:normal;font-weight:300;font-display:swap;src:url(https://fonts.gstatic.com/s/inter/v18/UcC73FwrK3iLTeHuS_nVMrMxCp50SjIa2pL7W0Q5n-wU.woff2) format('woff2');unicode-range:U+0102-0103,U+0110-0111,U+0128-0129,U+0168-0169,U+01A0-01A1,U+01AF-01B0,U+0300-0301,U+0303-0304,U+0308-0309,U+0323,U+0329,U+1EA0-1EF9,U+20AB}@font-face{font-family:'Inter';font-style:normal;font-weight:300;font-display:swap;src:url(https://fonts.gstatic.com/s/inter/v18/UcC73FwrK3iLTeHuS_nVMrMxCp50SjIa25L7W0Q5n-wU.woff2) format('woff2');unicode-range:U+0100-02BA,U+02BD-02C5,U+02C7-02CC,U+02CE-02D7,U+02DD-02FF,U+0304,U+0308,U+0329,U+1D00-1DBF,U+1E00-1E9F,U+1EF2-1EFF,U+2020,U+20A0-20AB,U+20AD-20C0,U+2113,U+2C60-2C7F,U+A720-A7FF}@font-face{font-family:'Inter';font-style:normal;font-weight:300;font-display:swap;src:url(https://fonts.gstatic.com/s/inter/v18/UcC73FwrK3iLTeHuS_nVMrMxCp50SjIa1ZL7W0Q5nw.woff2) format('woff2');unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD}@font-face{font-family:'Inter';font-style:normal;font-weight:400;font-display:swap;src:url(https://fonts.gstatic.com/s/inter/v18/UcC73FwrK3iLTeHuS_nVMrMxCp50SjIa2JL7W0Q5n-wU.woff2) format('woff2');unicode-range:U+0460-052F,U+1C80-1C8A,U+20B4,U+2DE0-2DFF,U+A640-A69F,U+FE2E-FE2F}@font-face{font-family:'Inter';font-style:normal;font-weight:400;font-display:swap;src:url(https://fonts.gstatic.com/s/inter/v18/UcC73FwrK3iLTeHuS_nVMrMxCp50SjIa0ZL7W0Q5n-wU.woff2) format('woff2');unicode-range:U+0301,U+0400-045F,U+0490-0491,U+04B0-04B1,U+2116}@font-face{font-family:'Inter';font-style:normal;font-weight:400;font-display:swap;src:url(https://fonts.gstatic.com/s/inter/v18/UcC73FwrK3iLTeHuS_nVMrMxCp50SjIa2ZL7W0Q5n-wU.woff2) format('woff2');unicode-range:U+1F00-1FFF}@font-face{font-family:'Inter';font-style:normal;font-weight:400;font-display:swap;src:url(https://fonts.gstatic.com/s/inter/v18/UcC73FwrK3iLTeHuS_nVMrMxCp50SjIa1pL7W0Q5n-wU.woff2) format('woff2');unicode-range:U+0370-0377,U+037A-037F,U+0384-038A,U+038C,U+038E-03A1,U+03A3-03FF}@font-face{font-family:'Inter';font-style:normal;font-weight:400;font-display:swap;src:url(https://fonts.gstatic.com/s/inter/v18/UcC73FwrK3iLTeHuS_nVMrMxCp50SjIa2pL7W0Q5n-wU.woff2) format('woff2');unicode-range:U+0102-0103,U+0110-0111,U+0128-0129,U+0168-0169,U+01A0-01A1,U+01AF-01B0,U+0300-0301,U+0303-0304,U+0308-0309,U+0323,U+0329,U+1EA0-1EF9,U+20AB}@font-face{font-family:'Inter';font-style:normal;font-weight:400;font-display:swap;src:url(https://fonts.gstatic.com/s/inter/v18/UcC73FwrK3iLTeHuS_nVMrMxCp50SjIa25L7W0Q5n-wU.woff2) format('woff2');unicode-range:U+0100-02BA,U+02BD-02C5,U+02C7-02CC,U+02CE-02D7,U+02DD-02FF,U+0304,U+0308,U+0329,U+1D00-1DBF,U+1E00-1E9F,U+1EF2-1EFF,U+2020,U+20A0-20AB,U+20AD-20C0,U+2113,U+2C60-2C7F,U+A720-A7FF}@font-face{font-family:'Inter';font-style:normal;font-weight:400;font-display:swap;src:url(https://fonts.gstatic.com/s/inter/v18/UcC73FwrK3iLTeHuS_nVMrMxCp50SjIa1ZL7W0Q5nw.woff2) format('woff2');unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD}@font-face{font-family:'Inter';font-style:normal;font-weight:500;font-display:swap;src:url(https://fonts.gstatic.com/s/inter/v18/UcC73FwrK3iLTeHuS_nVMrMxCp50SjIa2JL7W0Q5n-wU.woff2) format('woff2');unicode-range:U+0460-052F,U+1C80-1C8A,U+20B4,U+2DE0-2DFF,U+A640-A69F,U+FE2E-FE2F}@font-face{font-family:'Inter';font-style:normal;font-weight:500;font-display:swap;src:url(https://fonts.gstatic.com/s/inter/v18/UcC73FwrK3iLTeHuS_nVMrMxCp50SjIa0ZL7W0Q5n-wU.woff2) format('woff2');unicode-range:U+0301,U+0400-045F,U+0490-0491,U+04B0-04B1,U+2116}@font-face{font-family:'Inter';font-style:normal;font-weight:500;font-display:swap;src:url(https://fonts.gstatic.com/s/inter/v18/UcC73FwrK3iLTeHuS_nVMrMxCp50SjIa2ZL7W0Q5n-wU.woff2) format('woff2');unicode-range:U+1F00-1FFF}@font-face{font-family:'Inter';font-style:normal;font-weight:500;font-display:swap;src:url(https://fonts.gstatic.com/s/inter/v18/UcC73FwrK3iLTeHuS_nVMrMxCp50SjIa1pL7W0Q5n-wU.woff2) format('woff2');unicode-range:U+0370-0377,U+037A-037F,U+0384-038A,U+038C,U+038E-03A1,U+03A3-03FF}@font-face{font-family:'Inter';font-style:normal;font-weight:500;font-display:swap;src:url(https://fonts.gstatic.com/s/inter/v18/UcC73FwrK3iLTeHuS_nVMrMxCp50SjIa2pL7W0Q5n-wU.woff2) format('woff2');unicode-range:U+0102-0103,U+0110-0111,U+0128-0129,U+0168-0169,U+01A0-01A1,U+01AF-01B0,U+0300-0301,U+0303-0304,U+0308-0309,U+0323,U+0329,U+1EA0-1EF9,U+20AB}@font-face{font-family:'Inter';font-style:normal;font-weight:500;font-display:swap;src:url(https://fonts.gstatic.com/s/inter/v18/UcC73FwrK3iLTeHuS_nVMrMxCp50SjIa25L7W0Q5n-wU.woff2) format('woff2');unicode-range:U+0100-02BA,U+02BD-02C5,U+02C7-02CC,U+02CE-02D7,U+02DD-02FF,U+0304,U+0308,U+0329,U+1D00-1DBF,U+1E00-1E9F,U+1EF2-1EFF,U+2020,U+20A0-20AB,U+20AD-20C0,U+2113,U+2C60-2C7F,U+A720-A7FF}@font-face{font-family:'Inter';font-style:normal;font-weight:500;font-display:swap;src:url(https://fonts.gstatic.com/s/inter/v18/UcC73FwrK3iLTeHuS_nVMrMxCp50SjIa1ZL7W0Q5nw.woff2) format('woff2');unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD}@font-face{font-family:'Inter';font-style:normal;font-weight:600;font-display:swap;src:url(https://fonts.gstatic.com/s/inter/v18/UcC73FwrK3iLTeHuS_nVMrMxCp50SjIa2JL7W0Q5n-wU.woff2) format('woff2');unicode-range:U+0460-052F,U+1C80-1C8A,U+20B4,U+2DE0-2DFF,U+A640-A69F,U+FE2E-FE2F}@font-face{font-family:'Inter';font-style:normal;font-weight:600;font-display:swap;src:url(https://fonts.gstatic.com/s/inter/v18/UcC73FwrK3iLTeHuS_nVMrMxCp50SjIa0ZL7W0Q5n-wU.woff2) format('woff2');unicode-range:U+0301,U+0400-045F,U+0490-0491,U+04B0-04B1,U+2116}@font-face{font-family:'Inter';font-style:normal;font-weight:600;font-display:swap;src:url(https://fonts.gstatic.com/s/inter/v18/UcC73FwrK3iLTeHuS_nVMrMxCp50SjIa2ZL7W0Q5n-wU.woff2) format('woff2');unicode-range:U+1F00-1FFF}@font-face{font-family:'Inter';font-style:normal;font-weight:600;font-display:swap;src:url(https://fonts.gstatic.com/s/inter/v18/UcC73FwrK3iLTeHuS_nVMrMxCp50SjIa1pL7W0Q5n-wU.woff2) format('woff2');unicode-range:U+0370-0377,U+037A-037F,U+0384-038A,U+038C,U+038E-03A1,U+03A3-03FF}@font-face{font-family:'Inter';font-style:normal;font-weight:600;font-display:swap;src:url(https://fonts.gstatic.com/s/inter/v18/UcC73FwrK3iLTeHuS_nVMrMxCp50SjIa2pL7W0Q5n-wU.woff2) format('woff2');unicode-range:U+0102-0103,U+0110-0111,U+0128-0129,U+0168-0169,U+01A0-01A1,U+01AF-01B0,U+0300-0301,U+0303-0304,U+0308-0309,U+0323,U+0329,U+1EA0-1EF9,U+20AB}@font-face{font-family:'Inter';font-style:normal;font-weight:600;font-display:swap;src:url(https://fonts.gstatic.com/s/inter/v18/UcC73FwrK3iLTeHuS_nVMrMxCp50SjIa25L7W0Q5n-wU.woff2) format('woff2');unicode-range:U+0100-02BA,U+02BD-02C5,U+02C7-02CC,U+02CE-02D7,U+02DD-02FF,U+0304,U+0308,U+0329,U+1D00-1DBF,U+1E00-1E9F,U+1EF2-1EFF,U+2020,U+20A0-20AB,U+20AD-20C0,U+2113,U+2C60-2C7F,U+A720-A7FF}@font-face{font-family:'Inter';font-style:normal;font-weight:600;font-display:swap;src:url(https://fonts.gstatic.com/s/inter/v18/UcC73FwrK3iLTeHuS_nVMrMxCp50SjIa1ZL7W0Q5nw.woff2) format('woff2');unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD}@font-face{font-family:'Inter';font-style:normal;font-weight:700;font-display:swap;src:url(https://fonts.gstatic.com/s/inter/v18/UcC73FwrK3iLTeHuS_nVMrMxCp50SjIa2JL7W0Q5n-wU.woff2) format('woff2');unicode-range:U+0460-052F,U+1C80-1C8A,U+20B4,U+2DE0-2DFF,U+A640-A69F,U+FE2E-FE2F}@font-face{font-family:'Inter';font-style:normal;font-weight:700;font-display:swap;src:url(https://fonts.gstatic.com/s/inter/v18/UcC73FwrK3iLTeHuS_nVMrMxCp50SjIa0ZL7W0Q5n-wU.woff2) format('woff2');unicode-range:U+0301,U+0400-045F,U+0490-0491,U+04B0-04B1,U+2116}@font-face{font-family:'Inter';font-style:normal;font-weight:700;font-display:swap;src:url(https://fonts.gstatic.com/s/inter/v18/UcC73FwrK3iLTeHuS_nVMrMxCp50SjIa2ZL7W0Q5n-wU.woff2) format('woff2');unicode-range:U+1F00-1FFF}@font-face{font-family:'Inter';font-style:normal;font-weight:700;font-display:swap;src:url(https://fonts.gstatic.com/s/inter/v18/UcC73FwrK3iLTeHuS_nVMrMxCp50SjIa1pL7W0Q5n-wU.woff2) format('woff2');unicode-range:U+0370-0377,U+037A-037F,U+0384-038A,U+038C,U+038E-03A1,U+03A3-03FF}@font-face{font-family:'Inter';font-style:normal;font-weight:700;font-display:swap;src:url(https://fonts.gstatic.com/s/inter/v18/UcC73FwrK3iLTeHuS_nVMrMxCp50SjIa2pL7W0Q5n-wU.woff2) format('woff2');unicode-range:U+0102-0103,U+0110-0111,U+0128-0129,U+0168-0169,U+01A0-01A1,U+01AF-01B0,U+0300-0301,U+0303-0304,U+0308-0309,U+0323,U+0329,U+1EA0-1EF9,U+20AB}@font-face{font-family:'Inter';font-style:normal;font-weight:700;font-display:swap;src:url(https://fonts.gstatic.com/s/inter/v18/UcC73FwrK3iLTeHuS_nVMrMxCp50SjIa25L7W0Q5n-wU.woff2) format('woff2');unicode-range:U+0100-02BA,U+02BD-02C5,U+02C7-02CC,U+02CE-02D7,U+02DD-02FF,U+0304,U+0308,U+0329,U+1D00-1DBF,U+1E00-1E9F,U+1EF2-1EFF,U+2020,U+20A0-20AB,U+20AD-20C0,U+2113,U+2C60-2C7F,U+A720-A7FF}@font-face{font-family:'Inter';font-style:normal;font-weight:700;font-display:swap;src:url(https://fonts.gstatic.com/s/inter/v18/UcC73FwrK3iLTeHuS_nVMrMxCp50SjIa1ZL7W0Q5nw.woff2) format('woff2');unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD}@font-face{font-family:'Inter';font-style:normal;font-weight:900;font-display:swap;src:url(https://fonts.gstatic.com/s/inter/v18/UcC73FwrK3iLTeHuS_nVMrMxCp50SjIa2JL7W0Q5n-wU.woff2) format('woff2');unicode-range:U+0460-052F,U+1C80-1C8A,U+20B4,U+2DE0-2DFF,U+A640-A69F,U+FE2E-FE2F}@font-face{font-family:'Inter';font-style:normal;font-weight:900;font-display:swap;src:url(https://fonts.gstatic.com/s/inter/v18/UcC73FwrK3iLTeHuS_nVMrMxCp50SjIa0ZL7W0Q5n-wU.woff2) format('woff2');unicode-range:U+0301,U+0400-045F,U+0490-0491,U+04B0-04B1,U+2116}@font-face{font-family:'Inter';font-style:normal;font-weight:900;font-display:swap;src:url(https://fonts.gstatic.com/s/inter/v18/UcC73FwrK3iLTeHuS_nVMrMxCp50SjIa2ZL7W0Q5n-wU.woff2) format('woff2');unicode-range:U+1F00-1FFF}@font-face{font-family:'Inter';font-style:normal;font-weight:900;font-display:swap;src:url(https://fonts.gstatic.com/s/inter/v18/UcC73FwrK3iLTeHuS_nVMrMxCp50SjIa1pL7W0Q5n-wU.woff2) format('woff2');unicode-range:U+0370-0377,U+037A-037F,U+0384-038A,U+038C,U+038E-03A1,U+03A3-03FF}@font-face{font-family:'Inter';font-style:normal;font-weight:900;font-display:swap;src:url(https://fonts.gstatic.com/s/inter/v18/UcC73FwrK3iLTeHuS_nVMrMxCp50SjIa2pL7W0Q5n-wU.woff2) format('woff2');unicode-range:U+0102-0103,U+0110-0111,U+0128-0129,U+0168-0169,U+01A0-01A1,U+01AF-01B0,U+0300-0301,U+0303-0304,U+0308-0309,U+0323,U+0329,U+1EA0-1EF9,U+20AB}@font-face{font-family:'Inter';font-style:normal;font-weight:900;font-display:swap;src:url(https://fonts.gstatic.com/s/inter/v18/UcC73FwrK3iLTeHuS_nVMrMxCp50SjIa25L7W0Q5n-wU.woff2) format('woff2');unicode-range:U+0100-02BA,U+02BD-02C5,U+02C7-02CC,U+02CE-02D7,U+02DD-02FF,U+0304,U+0308,U+0329,U+1D00-1DBF,U+1E00-1E9F,U+1EF2-1EFF,U+2020,U+20A0-20AB,U+20AD-20C0,U+2113,U+2C60-2C7F,U+A720-A7FF}@font-face{font-family:'Inter';font-style:normal;font-weight:900;font-display:swap;src:url(https://fonts.gstatic.com/s/inter/v18/UcC73FwrK3iLTeHuS_nVMrMxCp50SjIa1ZL7W0Q5nw.woff2) format('woff2');unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD}@font-face{font-family:'JetBrains Mono';font-style:normal;font-weight:300;font-display:swap;src:url(https://fonts.gstatic.com/s/jetbrainsmono/v20/tDbv2o-flEEny0FZhsfKu5WU4zr3E_BX0PnT8RD8yK0BNntkaToggR7BYZbNPx3cwgknk-6nFg.woff2) format('woff2');unicode-range:U+0460-052F,U+1C80-1C8A,U+20B4,U+2DE0-2DFF,U+A640-A69F,U+FE2E-FE2F}@font-face{font-family:'JetBrains Mono';font-style:normal;font-weight:300;font-display:swap;src:url(https://fonts.gstatic.com/s/jetbrainsmono/v20/tDbv2o-flEEny0FZhsfKu5WU4zr3E_BX0PnT8RD8yK0BNntkaToggR7BYZbNPxTcwgknk-6nFg.woff2) format('woff2');unicode-range:U+0301,U+0400-045F,U+0490-0491,U+04B0-04B1,U+2116}@font-face{font-family:'JetBrains Mono';font-style:normal;font-weight:300;font-display:swap;src:url(https://fonts.gstatic.com/s/jetbrainsmono/v20/tDbv2o-flEEny0FZhsfKu5WU4zr3E_BX0PnT8RD8yK0BNntkaToggR7BYZbNPxPcwgknk-6nFg.woff2) format('woff2');unicode-range:U+0370-0377,U+037A-037F,U+0384-038A,U+038C,U+038E-03A1,U+03A3-03FF}@font-face{font-family:'JetBrains Mono';font-style:normal;font-weight:300;font-display:swap;src:url(https://fonts.gstatic.com/s/jetbrainsmono/v20/tDbv2o-flEEny0FZhsfKu5WU4zr3E_BX0PnT8RD8yK0BNntkaToggR7BYZbNPx_cwgknk-6nFg.woff2) format('woff2');unicode-range:U+0102-0103,U+0110-0111,U+0128-0129,U+0168-0169,U+01A0-01A1,U+01AF-01B0,U+0300-0301,U+0303-0304,U+0308-0309,U+0323,U+0329,U+1EA0-1EF9,U+20AB}@font-face{font-family:'JetBrains Mono';font-style:normal;font-weight:300;font-display:swap;src:url(https://fonts.gstatic.com/s/jetbrainsmono/v20/tDbv2o-flEEny0FZhsfKu5WU4zr3E_BX0PnT8RD8yK0BNntkaToggR7BYZbNPx7cwgknk-6nFg.woff2) format('woff2');unicode-range:U+0100-02BA,U+02BD-02C5,U+02C7-02CC,U+02CE-02D7,U+02DD-02FF,U+0304,U+0308,U+0329,U+1D00-1DBF,U+1E00-1E9F,U+1EF2-1EFF,U+2020,U+20A0-20AB,U+20AD-20C0,U+2113,U+2C60-2C7F,U+A720-A7FF}@font-face{font-family:'JetBrains Mono';font-style:normal;font-weight:300;font-display:swap;src:url(https://fonts.gstatic.com/s/jetbrainsmono/v20/tDbv2o-flEEny0FZhsfKu5WU4zr3E_BX0PnT8RD8yK0BNntkaToggR7BYZbNPxDcwgknk-4.woff2) format('woff2');unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD}@font-face{font-family:'JetBrains Mono';font-style:normal;font-weight:400;font-display:swap;src:url(https://fonts.gstatic.com/s/jetbrainsmono/v20/tDbv2o-flEEny0FZhsfKu5WU4zr3E_BX0PnT8RD8yK0BNntkaToggR7BYZbNPx3cwgknk-6nFg.woff2) format('woff2');unicode-range:U+0460-052F,U+1C80-1C8A,U+20B4,U+2DE0-2DFF,U+A640-A69F,U+FE2E-FE2F}@font-face{font-family:'JetBrains Mono';font-style:normal;font-weight:400;font-display:swap;src:url(https://fonts.gstatic.com/s/jetbrainsmono/v20/tDbv2o-flEEny0FZhsfKu5WU4zr3E_BX0PnT8RD8yK0BNntkaToggR7BYZbNPxTcwgknk-6nFg.woff2) format('woff2');unicode-range:U+0301,U+0400-045F,U+0490-0491,U+04B0-04B1,U+2116}@font-face{font-family:'JetBrains Mono';font-style:normal;font-weight:400;font-display:swap;src:url(https://fonts.gstatic.com/s/jetbrainsmono/v20/tDbv2o-flEEny0FZhsfKu5WU4zr3E_BX0PnT8RD8yK0BNntkaToggR7BYZbNPxPcwgknk-6nFg.woff2) format('woff2');unicode-range:U+0370-0377,U+037A-037F,U+0384-038A,U+038C,U+038E-03A1,U+03A3-03FF}@font-face{font-family:'JetBrains Mono';font-style:normal;font-weight:400;font-display:swap;src:url(https://fonts.gstatic.com/s/jetbrainsmono/v20/tDbv2o-flEEny0FZhsfKu5WU4zr3E_BX0PnT8RD8yK0BNntkaToggR7BYZbNPx_cwgknk-6nFg.woff2) format('woff2');unicode-range:U+0102-0103,U+0110-0111,U+0128-0129,U+0168-0169,U+01A0-01A1,U+01AF-01B0,U+0300-0301,U+0303-0304,U+0308-0309,U+0323,U+0329,U+1EA0-1EF9,U+20AB}@font-face{font-family:'JetBrains Mono';font-style:normal;font-weight:400;font-display:swap;src:url(https://fonts.gstatic.com/s/jetbrainsmono/v20/tDbv2o-flEEny0FZhsfKu5WU4zr3E_BX0PnT8RD8yK0BNntkaToggR7BYZbNPx7cwgknk-6nFg.woff2) format('woff2');unicode-range:U+0100-02BA,U+02BD-02C5,U+02C7-02CC,U+02CE-02D7,U+02DD-02FF,U+0304,U+0308,U+0329,U+1D00-1DBF,U+1E00-1E9F,U+1EF2-1EFF,U+2020,U+20A0-20AB,U+20AD-20C0,U+2113,U+2C60-2C7F,U+A720-A7FF}@font-face{font-family:'JetBrains Mono';font-style:normal;font-weight:400;font-display:swap;src:url(https://fonts.gstatic.com/s/jetbrainsmono/v20/tDbv2o-flEEny0FZhsfKu5WU4zr3E_BX0PnT8RD8yK0BNntkaToggR7BYZbNPxDcwgknk-4.woff2) format('woff2');unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD}</style></head><body class="relative"><div id="__next"><script>((e,r,s,u,d,m,l,h)=>{let c=document.documentElement,v=["light","dark"];function p(i){(Array.isArray(e)?e:[e]).forEach(y=>{let k=y==="class",S=k&&m?d.map(f=>m[f]||f):d;k?(c.classList.remove(...S),c.classList.add(i)):c.setAttribute(y,i)}),R(i)}function R(i){h&&v.includes(i)&&(c.style.colorScheme=i)}function a(){return window.matchMedia("(prefers-color-scheme: dark)").matches?"dark":"light"}if(u)p(u);else try{let i=localStorage.getItem(r)||s,y=l&&i==="system"?a():i;p(y)}catch(i){}})("class","theme","system",null,["light","dark"],null,true,true)</script><div class="min-h-screen relative flex flex-col justify-between "><script defer="" data-domain="json-schema.org" src="https://plausible.io/js/script.tagged-events.js"></script><div class=""><main class="z-10 h-screen xl:rounded-xl pt-4 mx-auto"><header class="w-full bg-white dark:bg-slate-800 fixed top-0 z-[170] shadow-xl drop-shadow-lg"><div class="flex w-full md:justify-between items-center ml-8 2xl:px-12 py-4"><div><a class="" href="/"><img alt="Dynamic image" loading="lazy" width="170" height="48" decoding="async" data-nimg="1" class="mr-2" style="color:transparent" src="/img/logos/logo-blue.svg"/></a></div><div class="flex justify-end md:mr-8 w-full "><a class="hidden lg:block hover:underline font-semibold p-2 md:p-4 text-slate-600 dark:text-white hover:text-primary dark:hover:underline" href="/specification">Specification</a><a class="hidden lg:block hover:underline font-semibold p-2 md:p-4 text-slate-600 dark:text-white hover:text-primary dark:hover:underline" href="/docs">Docs</a><a class="hidden lg:block hover:underline font-semibold p-2 md:p-4 text-slate-600 dark:text-white hover:text-primary dark:hover:underline" href="/tools?query=&amp;sortBy=name&amp;sortOrder=ascending&amp;groupBy=toolingTypes&amp;licenses=&amp;languages=&amp;drafts=&amp;toolingTypes=&amp;environments=">Tools</a><a class="hidden lg:block hover:underline font-semibold p-2 md:p-4 text-slate-600 dark:text-white hover:text-primary dark:hover:underline" href="/blog">Blog</a><a class="hidden lg:block hover:underline font-semibold p-2 md:p-4 text-slate-600 dark:text-white hover:text-primary dark:hover:underline" href="/community">Community</a><div class="flex items-center max-sm:ml-4 mr-8 gap-6 md:gap-4 dark:bg-slate-800"><div class="rounded-md dark:hover:bg-gray-700 hover:bg-gray-100 focus:bg-gray-100 focus:outline-none transition duration-150 md:block border-gray-100 ml-0 "><button type="button" class="DocSearch DocSearch-Button" aria-label="Search (Command+K)"><span class="DocSearch-Button-Container"><svg width="20" height="20" class="DocSearch-Search-Icon" viewBox="0 0 20 20" aria-hidden="true"><path d="M14.386 14.386l4.0877 4.0877-4.0877-4.0877c-2.9418 2.9419-7.7115 2.9419-10.6533 0-2.9419-2.9418-2.9419-7.7115 0-10.6533 2.9418-2.9419 7.7115-2.9419 10.6533 0 2.9419 2.9418 2.9419 7.7115 0 10.6533z" stroke="currentColor" fill="none" fill-rule="evenodd" stroke-linecap="round" stroke-linejoin="round"></path></svg><span class="DocSearch-Button-Placeholder">Search</span></span><span class="DocSearch-Button-Keys"></span></button></div><div class="relative w-10 h-10 dark-mode-toggle-container"><button class="dark-mode-toggle rounded-md dark:hover:bg-gray-700 p-1.5 hover:bg-gray-100 transition duration-150 " data-test="dark-mode-toggle"><img alt="Dark Mode" data-test="theme-icon" loading="lazy" width="25" height="25" decoding="async" data-nimg="1" style="color:transparent;filter:invert(0)" src="/icons/theme-switch.svg"/></button><div class="absolute right-0 p-2 bg-white dark:bg-gray-800 rounded-lg border dark:border-gray-700 z-10 w-max" style="display:none" tabindex="0" data-test="theme-dropdown"><div class="p-2 hover:bg-gray-200 dark:hover:bg-gray-700 cursor-pointer rounded-md transition duration-150 flex row gap-2 w-full text-sm" data-test="select-system-theme"><img alt="System theme" loading="lazy" width="18" height="18" decoding="async" data-nimg="1" style="color:transparent;filter:invert(0)" src="/icons/theme-switch.svg"/>System</div><div class="p-2 hover:bg-gray-200 dark:hover:bg-gray-700 cursor-pointer rounded-md transition duration-150 flex row gap-2 w-full text-sm" data-test="select-light-theme"><img alt="System theme" loading="lazy" width="18" height="18" decoding="async" data-nimg="1" style="color:transparent;filter:invert(0)" src="/icons/sun.svg"/>Light</div><div class="p-2 hover:bg-gray-200 dark:hover:bg-gray-700 cursor-pointer rounded-md transition duration-150 flex row gap-2 w-full text-sm" data-test="select-dark-theme"><img alt="System theme" loading="lazy" width="18" height="18" decoding="async" data-nimg="1" style="color:transparent;filter:invert(0)" src="/icons/moon.svg"/>Dark</div></div></div><div><div class="block lg:hidden space-y-2 items-center"><div class="w-6 h-1 bg-black rounded"></div><div class="w-6 h-1 bg-black rounded"></div><div class="w-6 h-1 bg-black rounded"></div></div></div></div><div class="flex items-center justify-end mr-8"><a data-testid="Button-link" target="_blank" rel="noopener noreferrer" class="cursor-pointer hidden lg:flex bg-primary hover:bg-blue-700 text-white transition-all duration-500 ease-in-out rounded-md px-3 text-sm font-medium tracking-heading py-2.5 ml-2" href="https://github.com/json-schema-org/json-schema-spec"><span class="inline-block mr-2"><svg class="inline-block -mt-1 w-6 h-6" fill="currentColor" viewBox="0 0 24 24"><path fill-rule="evenodd" d="M12 2C6.477 2 2 6.484 2 12.017c0 4.425 2.865 8.18 6.839 9.504.5.092.682-.217.682-.483 0-.237-.008-.868-.013-1.703-2.782.605-3.369-1.343-3.369-1.343-.454-1.158-1.11-1.466-1.11-1.466-.908-.62.069-.608.069-.608 1.003.07 1.531 1.032 1.531 1.032.892 1.53 2.341 1.088 2.91.832.092-.647.35-1.088.636-1.338-2.22-.253-4.555-1.113-4.555-4.951 0-1.093.39-1.988 1.029-2.688-.103-.253-.446-1.272.098-2.65 0 0 .84-.27 2.75 1.026A9.564 9.564 0 0112 6.844c.85.004 1.705.115 2.504.337 1.909-1.296 2.747-1.027 2.747-1.027.546 1.379.202 2.398.1 2.651.64.7 1.028 1.595 1.028 2.688 0 3.848-2.339 4.695-4.566 4.943.359.309.678.92.678 1.855 0 1.338-.012 2.419-.012 2.747 0 .268.18.58.688.482A10.019 10.019 0 0022 12.017C22 6.484 17.522 2 12 2z" clip-rule="evenodd"></path></svg></span><span class="inline-block">Star on GitHub</span></a></div></div></div></header><div><div><div class="flex flex-col items-center"><section class="bg-[linear-gradient(72.68deg,_#002CC4_28.97%,_#5468FF_145.47%)] clip-bottom w-full dark:bg-[linear-gradient(72.68deg,_#002C34_28.97%,_#5468FF_145.47%)]"><div class="max-w-[1400px] text-center mx-auto mt-24 lg:mt-40"><h1 class="lg:leading-header text-h1mobile lg:text-h1 font-semibold text-white text-center px-1 md:px-0 dark:text-slate-200">Build more. Break less. Empower others.</h1><h2 class="lg:leading-6 text-center text-h5mobile md:text-h5 text-white mt-4 dark:text-slate-300">JSON Schema enables the confident and reliable use of the JSON data format.</h2><div class="lg:w-[650px] mx-auto my-10 grid grid-cols-1 lg:grid-cols-3 gap-8 justify-items-center "><a class="flex items-center justify-center rounded border-2 border-white dark:border-none hover:bg-blue-700 transition-all duration-300 ease-in-out text-white w-[194px] h-[40px] font-semibold bg-primary dark:shadow-2xl" href="/learn">Getting started</a><a class="flex items-center justify-center rounded border-2 border-white dark:border-none hover:bg-blue-700 transition-all duration-300 ease-in-out text-white w-[194px] h-[40px] font-semibold bg-primary dark:shadow-2xl" href="/slack">Join Slack</a><div class="flex herobtn items-center justify-center font-semibold w-[194px] h-[40px] rounded border-2 border-white dark:border-none hover:bg-blue-700 transition-all duration-300 ease-in-out text-white bg-primary mx-auto dark:shadow-2xl cursor-pointer"><div class="flex flex-row justify-center items-center mr-4"><button type="button" class="DocSearch DocSearch-Button" aria-label="Search (Command+K)"><span class="DocSearch-Button-Container"><svg width="20" height="20" class="DocSearch-Search-Icon" viewBox="0 0 20 20" aria-hidden="true"><path d="M14.386 14.386l4.0877 4.0877-4.0877-4.0877c-2.9418 2.9419-7.7115 2.9419-10.6533 0-2.9419-2.9418-2.9419-7.7115 0-10.6533 2.9418-2.9419 7.7115-2.9419 10.6533 0 2.9419 2.9418 2.9419 7.7115 0 10.6533z" stroke="currentColor" fill="none" fill-rule="evenodd" stroke-linecap="round" stroke-linejoin="round"></path></svg><span class="DocSearch-Button-Placeholder">Search</span></span><span class="DocSearch-Button-Keys"></span></button>Search</div></div></div><div class="mb-16 md:mb-36 mx-auto w-full md:w-5/6 lg:w-full"><h3 class="text-white text-xl mb-4">Used by</h3><div class="grid md:grid-cols-2 lg:grid-cols-4 gap-6 mx-auto items-center w-1/3 md:w-100 text-center"></div><p class="text-white mx-4 my-5 dark:text-slate-400">Please visit the JSON Schema<!-- --> <a class="underline" href="https://landscape.json-schema.org/">Landscape</a> <!-- -->and discover more companies using JSON Schema.</p></div></div></section><section class="max-w-[1400px] mt-12 lg:mt-[80px]"><div class="w-5/6 md:w-1/2 text-center mb-6 mx-auto "><h2 class="text-h3mobile md:text-h3 font-bold mb-6 dark:text-slate-200">Why JSON Schema?</h2><p class="mb-6 text-h5mobile md:text-h5 leading-7 dark:text-slate-300">While JSON is probably the most popular format for exchanging data, JSON Schema is the vocabulary that enables JSON data consistency, validity, and interoperability at scale.</p></div><div class="w-5/6 lg:w-3/5 grid grid-cols-1 md:grid-cols-2 gap-6 my-[85px] mx-auto "><div class="w-full shadow-3xl rounded-[10px] p-[20px] dark:shadow-slate-700"><h3 class="text-h5mobile md:text-h5 font-semibold mb-6 dark:text-slate-200">Streamline testing and validation</h3><p class="dark:text-slate-300">Simplify your validation logic to reduce your code’s complexity and save time on development. Define constraints for your data structures to catch and prevent errors, inconsistencies, and invalid data.</p></div><div class="w-full shadow-3xl rounded-[10px] p-[20px] dark:shadow-slate-700"><h3 class="text-h5mobile md:text-h5 font-semibold mb-6 dark:text-slate-200">Exchange data seamlessly</h3><p class="dark:text-slate-300">Establish a common language for data exchange, no matter the scale or complexity of your project. Define precise validation rules for your data structures to create shared understanding and increase interoperability across different systems and platforms.</p></div><div class="w-full shadow-3xl rounded-[10px] p-[20px] dark:shadow-slate-700"><h3 class="text-h5mobile md:text-h5 font-semibold mb-6 dark:text-slate-200 ">Document your data</h3><p class="dark:text-slate-300">Create a clear, standardized representation of your data to improve understanding and collaboration among developers, stakeholders, and collaborators.</p></div><div class="w-full shadow-3xl rounded-[10px] p-[20px] dark:shadow-slate-700"><h3 class="text-h5mobile md:text-h5 font-semibold mb-6 dark:text-slate-200">Vibrant tooling ecosystem</h3><p class="dark:text-slate-300">Adopt JSON Schema with an expansive range of community-driven tools, libraries, and frameworks across many programming languages.</p></div></div></section><section class="w-full h-[300px] lg:h-[367px] bg-gradient-to-r from-primary from-1.95% to-endBlue clip-both dark:from-[#002C34] dark:to-[#023e8a] grid items-center"><div class="lg:w-full mx-auto text-center "><h2 class="text-h3mobile lg:text-h3 text-white mb-6">Start learning JSON Schema</h2><button class="w-[170px] h-[45px] mx-auto hover:bg-blue-700 transition-all duration-300 ease-in-out rounded border-2 bg-primary text-white font-semibold dark:border-none"><a href="/docs ">Read the docs</a></button></div></section><section class="max-w-[1400px] w-full lg:flex lg:gap-20 my-16 "><div class="w-5/6 md:w-3/5 mx-auto mt-12"><h3 class=" text-center lg:text-left text-h3mobile md:text-h3 font-semibold mb-4 dark:text-slate-200">Explore the JSON Schema Ecosystem</h3><p class="lg:pr-8 mb-4 text-center lg:text-left dark:text-slate-300">Discover JSON Schema tooling to help your organization leverage the benefits of JSON Schema. Because JSON Schema is much more than a Specification, it is a vibrant ecosystem of Validators, Generators, Linters, and other JSON Schema Utilities made by this amazing Community.</p><button class="w-full md:w-1/2 md:ml-28 lg:ml-0 mx-auto hover:bg-blue-700 transition-all duration-300 ease-in-out h-[45px] rounded border-2 bg-primary text-white dark:border-none"><a href="/tools/">Explore</a></button></div></section><h2 class="anchor"><span id="community"></span></h2><section class="lg:my-12 max-w-[1400px]"><div class="mb-12 md:w-3/4 mx-auto text-center"><h2 class="text-h3mobile md:text-h3 font-semibold mb-2 dark:text-slate-200">Welcome to the JSON Schema Community</h2><p class="mx-6 md:w-3/4 md:mx-auto lg:text-h5 dark:text-slate-300">With over 60 million weekly downloads, JSON Schema has a large and active developer community across the world. Join the Community to learn, share ideas, ask questions, develop JSON Schema tooling and build new connections.</p></div><div class="grid grid-cols-1 lg:grid-cols-3 gap-6 mb-12 mx-auto w-5/6 md:w-3/5 lg:w-5/6"><div class="p-4 w-full mb-6 dark:shadow-2xl"><a href="https://json-schema.org/slack"><h3 class="mb-4 font-semibold flex items-center dark:text-slate-200">Join the JSON Schema Slack Workspace!</h3><p class="mb-4 dark:text-slate-300">Join our Slack to ask questions, get feedback on your projects, and connect with +5000 practitioners and experts.</p></a><button class="w-full lg:w-1/2 rounded border-2 bg-primary hover:bg-blue-700 transition-all duration-300 ease-in-out text-white h-[40px] flex items-center justify-center mx-auto dark:border-none"><a href="https://json-schema.org/slack" class="flex items-center ">Join Slack</a></button></div><div class="p-4 w-full mb-6 dark:shadow-2xl"><a href="/blog/posts/oracle-case-study"><h3 class="mb-5 font-semibold pt-1 dark:text-slate-200">The JSON Schema Blog</h3><h3 class="mb-4 font-semibold dark:text-slate-300"> <!-- -->How Oracle is Bridging the Gap Between JSON Schema and Relational Databases</h3><div class="mb-4"><span style="overflow:hidden"><span>As modern multi-model databases increasingly support JSON, it&#x27;s time to explore what role JSON schema will play.</span></span></div><div class="flex ml-2 mb-2 "><div class="bg-slate-50 h-[44px] w-[44px] rounded-full -ml-3 bg-cover bg-center border-2 border-white" style="background-image:url(/img/avatars/loiclefevre.webp);z-index:10"></div><div class="flex flex-col ml-2"><p class="text-sm font-semibold dark:text-slate-300"><span>Loïc Lefèvre</span></p><div class="text-slate-500 text-sm dark:text-slate-300"><span>2025-02-07<!-- --> · <!-- -->22<!-- --> <!-- -->min read</span></div></div></div></a><div><a class=" w-full lg:w-1/2 rounded border-2 bg-primary text-white hover:bg-blue-700 transition-all duration-300 ease-in-out h-[40px] text-center pt-1 semi-bold flex items-center justify-center mx-auto dark:border-none" href="/blog/posts/oracle-case-study">Read more<!-- --> </a></div></div><div><div class="p-4 md:w-full mb-6 mr-4 dark:shadow-2xl"><h3 class="mb-2 font-semibold dark:text-slate-200">JSON Schema Community Meetings &amp; Events</h3><p class="mb-4 dark:text-slate-300">We hold monthly Office Hours and Open Community Working Meetings. Office Hours are every first Tuesday of the month and by appointment. Open Community Working Meetings are every third Monday of the month at 12:00 PT.</p><div class=""><button class="max-w-[300px] w-full text-center rounded border-2 bg-primary hover:bg-blue-700 transition-all duration-300 ease-in-out text-white h-[40px] mb-4 flex items-center justify-center mx-auto dark:border-none"><a href="https://github.com/orgs/json-schema-org/discussions/35">Open Community Working Meetings</a></button><button class="max-w-[200px] w-full text-center rounded border-2 bg-primary hover:bg-blue-700 transition-all duration-300 ease-in-out text-white h-[40px] flex items-center justify-center mx-auto dark:border-none"><a href="https://github.com/orgs/json-schema-org/discussions/34/">Office Hours</a></button></div></div><div class="p-2"><div><h4 id="upcoming-events" class="group cursor-pointer hover:underline text-h4mobile dark:text-slate-200 md:text-h4 font-semibold mt-4 mb-2" data-test="headline">Upcoming events</h4><div><ul><li><div class="flex mb-4"><p class="bg-btnOrange rounded-full w-10 h-10 p-2 text-center text-white mr-2">17</p><div class="text-sm"><p>JSON Schema Open Community Working Meeting</p><p><b>February 17th 2025, 20:00</b> (<!-- -->UTC<!-- -->)</p></div></div></li><li><div class="flex mb-4"><p class="bg-btnOrange rounded-full w-10 h-10 p-2 text-center text-white mr-2">4</p><div class="text-sm"><p>JSON Schema Office Hours (APAC/Americas)</p><p><b>March 4th 2025, 23:00</b> (<!-- -->UTC<!-- -->)</p></div></div></li><li><div class="flex mb-4"><p class="bg-btnOrange rounded-full w-10 h-10 p-2 text-center text-white mr-2">17</p><div class="text-sm"><p>JSON Schema Open Community Working Meeting</p><p><b>March 17th 2025, 20:00</b> (<!-- -->UTC<!-- -->)</p></div></div></li><li><div class="flex mb-4"><p class="bg-btnOrange rounded-full w-10 h-10 p-2 text-center text-white mr-2">1</p><div class="text-sm"><p>JSON Schema Office Hours (Europe/Americas)</p><p><b>April 1st 2025, 14:00</b> (<!-- -->UTC<!-- -->)</p></div></div></li><li><div class="flex mb-4"><p class="bg-btnOrange rounded-full w-10 h-10 p-2 text-center text-white mr-2">21</p><div class="text-sm"><p>JSON Schema Open Community Working Meeting</p><p><b>April 21st 2025, 19:00</b> (<!-- -->UTC<!-- -->)</p></div></div></li><li><div class="flex mb-4"><p class="bg-btnOrange rounded-full w-10 h-10 p-2 text-center text-white mr-2">6</p><div class="text-sm"><p>JSON Schema Office Hours (APAC/Americas)</p><p><b>May 6th 2025, 21:00</b> (<!-- -->UTC<!-- -->)</p></div></div></li></ul></div></div><a href="https://calendar.google.com/calendar/embed?src=json.schema.community%40gmail.com&amp;ctz=Europe%2FLondon" class="w-full lg:w-1/2 rounded border-2 bg-primary text-white hover:bg-blue-700 transition-all duration-300 ease-in-out h-[40px] text-center flex items-center justify-center mx-auto dark:border-none" target="_blank" rel="noopener noreferrer">View Calendar</a></div></div></div></section><section class="w-full h-[300px] lg:h-[367px] bg-gradient-to-r from-primary from-1.95% to-endBlue clip-both dark:from-[#002C34] dark:to-[#023e8a] grid items-center"><div class="lg:w-full mx-auto text-center"><h2 class="text-h3mobile lg:text-h3 text-white mb-6 dark:text-slate-200">Start contributing to JSON Schema</h2><button class="w-[170px] h-[45px] mx-auto rounded border-2 bg-primary hover:bg-blue-700 transition-all duration-300 ease-in-out text-white font-semibold dark:border-none"><a href="https://github.com/json-schema-org#-contributing-to-json-schema">Contribute</a></button></div></section><section class="my-16"><div class="text-center mb-4"><h2 class="text-h3mobile md:text-h3 font-semibold mb-2 dark:text-slate-200">Sponsors</h2><p class="w-5/6 lg:w-3/5 mx-auto dark:text-slate-300">If you ❤️ JSON Schema consider becoming a<!-- --> <a href="https://json-schema.org/overview/sponsors" class="border-b border-black dark:border-white">sponsor</a>, a<!-- --> <a href="https://json-schema.org/overview/sponsors#benefits-of-being-an-individual-backer" class="border-b border-black dark:border-white">backer</a> <!-- -->or hiring our<!-- --> <a href="/pro-help" class="border-b border-black dark:border-white">pro services</a>.</p><p class="w-5/6 lg:w-3/5 mx-auto"><a href="https://opencollective.com/json-schema" class="border-b border-black dark:border-white">Support us!</a></p></div><div class=" text-center mb-12 "><h3 class="p-4 text-h4mobile md:text-h4 font-semibold my-4 dark:text-slate-200">Gold Sponsors</h3><a href="https://opencollective.com/json-schema/contribute/golden-sponsor-68354/checkout?interval=month&amp;amount=1000&amp;name=&amp;legalName=&amp;email=" target="_blank" rel="noreferrer" class="w-[310px] h-[180px] mx-auto rounded-lg bg-primary text-white font-semibold flex items-center justify-center space-x-2 cursor-pointer px-3"><svg xmlns="http://www.w3.org/2000/svg" class="h-6 w-6" fill="none" viewBox="0 0 24 24" stroke="currentColor"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 4v16m8-8H4"></path></svg><p class="block">Your logo here</p></a><h3 class="p-4 text-h4mobile md:text-h4 font-semibold my-4 dark:text-slate-200">Silver Sponsors</h3><a href="https://opencollective.com/json-schema/contribute/silver-sponsor-68353/checkout?interval=month&amp;amount=500&amp;name=&amp;legalName=&amp;email=" target="_blank" rel="noreferrer" class="w-[200px] h-[120px] mx-auto rounded-lg bg-primary text-white font-semibold flex items-center justify-center space-x-2 cursor-pointer px-3"><svg xmlns="http://www.w3.org/2000/svg" class="h-6 w-6" fill="none" viewBox="0 0 24 24" stroke="currentColor"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 4v16m8-8H4"></path></svg><p>Your logo here</p></a><h3 class="p-4 text-h4mobile md:text-h4 font-semibold my-4 dark:text-slate-200">Bronze Sponsors</h3><div class="grid grid-cols-2 md:grid-cols-3 lg:grid-cols-6 gap-12 items-center mx-auto md:mx-0 px-4 "><a href=" https://www.asyncapi.com/" target="_blank" rel="noreferrer"></a><a href="https://www.airbnb.com/" target="_blank" rel="noreferrer"></a><a href="https://www.postman.com/" target="_blank" rel="noreferrer"></a><a href="https://endjin.com/" target="_blank" rel="noreferrer"></a><a href="https://www.llc.org/" target="_blank" rel="noreferrer"></a><a href="https://www.vpsserver.com/en-us/" target="_blank" rel="noreferrer"></a><a href="https://www.itflashcards.com/" target="_blank" rel="noreferrer"></a><a href="https://www.route4me.com/" target="_blank" rel="noreferrer"></a><a href="https://n8n.io/" target="_blank" rel="noreferrer"></a><a href="https://copycopter.ai/" target="_blank" rel="noreferrer"></a><a href="https://www.octue.com/" target="_blank" rel="noreferrer"><img src="" class=" w-44"/></a><a href="https://www.apideck.com/" target="_blank" rel="noreferrer"><img src="" class=" w-44" alt="The Realtime Unified API for Accounting integrations"/></a><a href="https://rxdb.info/?utm_source=sponsor&amp;utm_medium=json-schema&amp;utm_campaign=json-schema" target="_blank" rel="noreferrer"><img src="" class=" w-44" alt="The local Database for JavaScript Applications"/></a><a href="https://topagency.webflow.io" target="_blank" rel="noreferrer"><img src="" class=" w-44" alt="best website design agencies"/></a><a href="https://opencollective.com/json-schema/contribute/sponsor-10816/checkout?interval=month&amp;amount=100&amp;name=&amp;legalName=&amp;email=" target="_blank" rel="noreferrer" class="w-[155px] md:w-[176px] h-[44px] mx-auto rounded-lg bg-primary text-white font-semibold flex items-center justify-center space-x-2 cursor-pointer px-3"><svg xmlns="http://www.w3.org/2000/svg" class="h-6 w-6" fill="none" viewBox="0 0 24 24" stroke="currentColor"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 4v16m8-8H4"></path></svg><p class="text-sm md:text-base">Your logo here</p></a></div></div></section><section class="my-20"><div class="text-center mb-12"><h2 class="text-h3mobile md:text-h3 font-semibold mb-2">Supported by</h2><p class="px-12 mx-auto">The following companies support us by letting us use their products.<br/><a href="/cdn-cgi/l/email-protection#bfd6d1d9d0ffd5ccd0d192ccdcd7dad2de91d0cdd8" class="border-b border-black dark:border-white">Email us</a> <!-- -->for more info!</p></div><div class="flex flex-col items-center md:flex-row justify-center text-center gap-x-14 gap-y-4"><a href="https://www.commonroom.io"></a><a href="https://json-schema.org/slack"></a></div> </section></div></div></div><div class="fixed bottom-14 right-4 h-16 w-12 z-40"></div><footer class="z-10 h-[350px] md:h-[300px] bg-gradient-to-r from-startBlue from-1.95% to-endBlue dark:from-[#002C34] dark:to-[#023e8a] clip-top grid items-center"><div class="max-w-[1400px] mx-auto mt-8 md:mt-4 grid grid-cols-1 md:grid-cols-2 md:w-1/2 lg:w-1/3 justify-center "><div class=" my-6 m-auto md:mt-16"><img alt="logo-white" loading="lazy" width="150" height="100" decoding="async" data-nimg="1" class="mb-6" style="color:transparent" src="/img/logos/logo-white.svg"/><div class="flex flex-col text-center sm:text-left"><a href="https://opencollective.com/json-schema" class="text-white mb-2">Open Collective</a></div><div class="flex flex-col text-center sm:text-left"><a href="/overview/code-of-conduct" class="text-white mb-2">Code of Conduct</a></div></div><div class="grid grid-cols-3 md:grid-cols-1 mx-auto md:mt-8 mb-4 md:mb-0 gap-x-4 gap-y-4 md:gap-x-0 md:gap-y-0"><div class=""><a href="https://json-schema.org/slack" class="flex items-center text-white"><img alt="Slack logo" loading="lazy" width="16" height="16" decoding="async" data-nimg="1" class=" mr-2" style="color:transparent" src="/img/logos/slack_logo_small-white.svg"/>Slack</a></div><div class=""><a href="https://x.com/jsonschema" class="flex items-center text-white"><img alt="X logo" loading="lazy" width="16" height="16" decoding="async" data-nimg="1" class=" mr-2" style="color:transparent" src="/img/logos/x-twitter.svg"/> <!-- -->X</a></div><div class=""><a href="https://linkedin.com/company/jsonschema/" class="flex items-center text-white"><img alt="LinkedIn logo" loading="lazy" width="16" height="16" decoding="async" data-nimg="1" class=" mr-2" style="color:transparent" src="/img/logos/icons8-linkedin-2.svg"/>LinkedIn</a></div><div class=""><a href="https://www.youtube.com/@JSONSchemaOrgOfficial" class="flex items-center text-white"><img alt="YouTube logo" loading="lazy" width="16" height="16" decoding="async" data-nimg="1" class="mr-2" style="color:transparent" src="/img/logos/icons8-youtube.svg"/>Youtube</a></div><div class=""><a href="https://github.com/json-schema-org" class="flex items-center text-white"><img alt="GitHub logo" loading="lazy" width="16" height="16" decoding="async" data-nimg="1" class="mr-2" style="color:transparent" src="/img/logos/github_logo-white.svg"/>GitHub</a></div></div></div><div class="text-white font-normal text-center relative m-0 ml-0 mr-1 px-4"><p>Copyright © <!-- -->2025<!-- --> JSON Schema. <span class="block sm:inline sm:mb-0">All rights reserved.</span></p></div></footer></main></div></div></div><script data-cfasync="false" src="/cdn-cgi/scripts/5c5dd728/cloudflare-static/email-decode.min.js"></script><script id="__NEXT_DATA__" type="application/json">{"props":{"pageProps":{"blogPosts":[{"slug":"oracle-case-study","frontmatter":{"title":"How Oracle is Bridging the Gap Between JSON Schema and Relational Databases","date":"2025-02-07","tags":["database","relational"],"type":"Case Study","cover":"/img/posts/2025/oracle-case-study/blog_frontpage.webp","authors":[{"name":"Loïc Lefèvre","photo":"/img/avatars/loiclefevre.webp","link":"https://www.linkedin.com/in/loiclefevre/","byline":"Oracle Database Senior Product Manager"}],"excerpt":"As modern multi-model databases increasingly support JSON, it's time to explore what role JSON schema will play."},"content":"\nAs modern multi-model databases increasingly support JSON, it's time to explore what role [JSON schema](https://json-schema.org/) will play. In this post, we'll dive into the newly developed [\"Database Vocabulary\"](https://github.com/json-schema-org/vocab-database/blob/main/database.md), a proposed extension to the official JSON schema specification, developed by Oracle (with inputs from the MySQL and PostgreSQL teams). This vocabulary addresses key database tasks, including validation, type coercion/casting, and metadata preservation, making it easier to manage JSON in databases effectively and bridging the gap with existing relational data. Regardless of whether you are a JSON developer or a relational model developer, you'll learn something reading this post!\n\nOracle Database 23ai fully implements this new vocabulary, and we'll describe not only the concepts but we'll also see real-world examples of JSON schema validation in action and how to describe database objects in JSON schema.\n\n## JSON Data Guide\n\nWith Oracle Database 12cR2 (2017), we've introduced the concept of a [JSON data guide](https://docs.oracle.com/en/database/oracle/oracle-database/23/adjsn/json-data-guide.html); that lets you **discover** information about the structure and content of *existing* JSON documents stored in JSON columns inside the database.\n\nLet's look at the following example which creates a table `blog_posts` with a column `data` of type `JSON` and inserts one JSON document:\n\n```sql\ncreate table blog_posts (\n data json -- BINARY JSON\n);\n\ninsert into blog_posts( data ) values (\n json {\n 'title': 'New Blog Post',\n 'content': 'This is the content of the blog post...',\n 'publishedDate': '2023-08-25T15:00:00Z',\n 'author': {\n 'username': 'authoruser',\n 'email': 'author@example.com'\n },\n 'tags': ['Technology', 'Programming']\n }\n);\ncommit;\n```\n\nWe can query the table and retrieve JSON values using the SQL dot notation to navigate the JSON document hierarchy. Attributes within the JSON document can simply be referenced by `.\u003cattribute name\u003e`:\n\n```sql\nselect -- field names are case sensitive\n p.data.title,\n p.data.author.username.string() as username, \n p.data.tags[1].string() as \"array_field[1]\"\n from blog_posts p;\n```\n\nThe [item method](https://docs.oracle.com/en/database/oracle/oracle-database/23/adjsn/sql-json-path-expression-item-methods.html) `string()` allows explicit casting of the JSON field value. Alongside `string()` are other casting methods like `number()`, `date()`, etc.\n\nHowever, nothing prevents us from inserting unexpected data!\n\n```sql\ninsert into blog_posts( data ) values( '{ \"garbageDocument\":true }' );\ncommit;\n\nselect data from blog_posts;\n```\nResults:\n\n| DATA |\n|-|\n| {\u003cbr/\u003e\u0026nbsp;\u0026nbsp;\"title\": \"New Blog Post\",\u003cbr/\u003e\u0026nbsp;\u0026nbsp;\"content\": \"This is the content of the blog post...\",\u003cbr/\u003e\u0026nbsp;\u0026nbsp;\"publishedDate\":\"2023-08-25T15:00:00Z\",\u003cbr/\u003e\u0026nbsp;\u0026nbsp;\"author\": {\u003cbr/\u003e\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\"username\":\"authoruser\",\u003cbr/\u003e\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\"email\":\"author@example.com\"\u003cbr/\u003e\u0026nbsp;\u0026nbsp;},\u003cbr/\u003e\u0026nbsp;\u0026nbsp;\"tags\": [ \"Technology\", \"Programming\" ]\u003cbr/\u003e} |\n| {\u003cbr/\u003e\u0026nbsp;\u0026nbsp;\"garbageDocument\":true\u003cbr/\u003e} |\n\nThis is where, JSON schemas can help, and the [`JSON_DATAGUIDE()`](https://docs.oracle.com/en/database/oracle/oracle-database/23/sqlrf/JSON_DATAGUIDE.html) function can generate one from a set of already existing JSON document(s):\n\n```sql\nselect json_dataguide(\n data, \n dbms_json.format_schema,\n dbms_json.pretty\n ) as json_schema\n from blog_posts;\n```\nResults:\n\n```json\n{\n \"type\": \"object\",\n \"o:length\": 1,\n \"properties\": {\n \"tags\": {\n \"type\": \"array\",\n \"o:length\": 1,\n \"items\": {\n \"type\": \"string\",\n \"o:length\": 16\n }\n },\n \"title\": {\n \"type\": \"string\",\n \"o:length\": 16\n },\n \"author\": {\n \"type\": \"object\",\n \"o:length\": 1,\n \"properties\": {\n \"email\": {\n \"type\": \"string\",\n \"o:length\": 32\n },\n \"username\": {\n \"type\": \"string\",\n \"o:length\": 16\n }\n }\n },\n \"content\": {\n \"type\": \"string\",\n \"o:length\": 64\n },\n \"publishedDate\": {\n \"type\": \"string\",\n \"o:length\": 32\n },\n \"garbageDocument\": {\n \"type\": \"boolean\",\n \"o:length\": 4\n }\n }\n}\n```\n\nWe can see that the `garbageDocument` field was properly detected and added to the set of accepted JSON fields for the JSON schema.\n\n## Data Validation\n\nThe most obvious use case for JSON schema is JSON data validation. The Oracle Database 23ai brings the new PL/SQL package [`DBMS_JSON_SCHEMA`](https://docs.oracle.com/en/database/oracle/oracle-database/23/arpls/DBMS_JSON_SCHEMA.html#GUID-89B9C48D-D905-482C-A78C-8DB314EDF072) which can be used to validate JSON schemas and JSON data.\n\nThe `dbms_json_schema.is_schema_valid()` function can tell us if a given JSON schema itself is valid:\n\n```sql\n-- Validate the generated JSON schema\nselect dbms_json_schema.is_schema_valid( \n (\n -- Generate JSON Data Guide/Schema from data column\n select json_dataguide(\n data,\n dbms_json.format_schema,\n dbms_json.pretty\n ) as json_schema\n from blog_posts\n ) \n) = 1 as is_schema_valid;\n```\n\nAnother function `dbms_json_schema.validate_report()` validates a JSON document against a JSON schema and generates a validation report, including validation errors, if there are any:\n\n```sql\n-- Validate current JSON data with a simple JSON schema\nselect dbms_json_schema.validate_report( \n data,\n json( '{\n \"type\": \"object\",\n \"properties\": { \n \"tags\": {\n \"type\": \"array\",\n \"items\": {\n \"type\": \"string\"\n }\n }\n }\n }' )\n ) as report\nfrom blog_posts;\n```\nResults:\n\n| REPORT |\n|------------------------------------------------------------|\n| {\u003cbr/\u003e\u0026nbsp;\u0026nbsp;\"valid\": true,\u003cbr/\u003e\u0026nbsp;\u0026nbsp;\"errors\": []\u003cbr/\u003e} |\n| {\u003cbr/\u003e\u0026nbsp;\u0026nbsp;\"valid\": true,\u003cbr/\u003e\u0026nbsp;\u0026nbsp;\"errors\": []\u003cbr/\u003e} |\n\nWith the simplistic JSON schema, no validation errors are present. Let's use a more complex JSON schema (based on the [Blog post](https://json-schema.org/learn/json-schema-examples#blog-post) example from the JSON schema website itself):\n\n```sql\nselect dbms_json_schema.validate_report( \n data,\n json('{\n \"$id\": \"https://example.com/blog-post.schema.json\",\n \"$schema\": \"https://json-schema.org/draft/2020-12/schema\",\n \"description\": \"A representation of a blog post\",\n \"type\": \"object\",\n \"required\": [\"title\", \"content\", \"author\"],\n \"properties\": {\n \"title\": {\n \"type\": \"string\"\n },\n \"content\": {\n \"type\": \"string\"\n },\n \"publishedDate\": {\n \"type\": \"string\",\n \"format\": \"date-time\"\n },\n \"author\": {\n \"$ref\": \"https://example.com/user-profile.schema.json\"\n },\n \"tags\": {\n \"type\": \"array\",\n \"items\": {\n \"type\": \"string\"\n }\n }\n },\n \"$def\": {\n \"$id\": \"https://example.com/user-profile.schema.json\",\n \"$schema\": \"https://json-schema.org/draft/2020-12/schema\",\n \"description\": \"A representation of a user profile\",\n \"type\": \"object\",\n \"required\": [\"username\", \"email\"],\n \"properties\": {\n \"username\": {\n \"type\": \"string\"\n },\n \"email\": {\n \"type\": \"string\",\n \"format\": \"email\"\n },\n \"fullName\": {\n \"type\": \"string\"\n },\n \"age\": {\n \"type\": \"integer\",\n \"minimum\": 0\n },\n \"location\": {\n \"type\": \"string\"\n },\n \"interests\": {\n \"type\": \"array\",\n \"items\": {\n \"type\": \"string\"\n }\n }\n }\n }\n }')\n) as report\nfrom blog_posts;\n```\nResults:\n\n| REPORT |\n|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|\n| { \u003cbr/\u003e\u0026nbsp;\u0026nbsp;\"valid\": true,\u003cbr/\u003e\u0026nbsp;\u0026nbsp;\"errors\": []\u003cbr/\u003e} |\n| {\u003cbr/\u003e\u0026nbsp;\u0026nbsp;\"valid\": false,\u003cbr/\u003e\u0026nbsp;\u0026nbsp;\"errors\": [\u003cbr/\u003e\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;{\u003cbr/\u003e\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\"schemaPath\": \"\\$\",\u003cbr/\u003e\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\"instancePath\": \"\\$\",\u003cbr/\u003e\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\"code\": \"JZN-00501\",\u003cbr/\u003e\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\"error\": \"JSON schema validation failed\"\u003cbr/\u003e\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;}, {\u003cbr/\u003e\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\"schemaPath\": \"\\$.required\",\u003cbr/\u003e\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\"instancePath\": \"\\$\",\u003cbr/\u003e\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\"code\": \"JZN-00515\",\u003cbr/\u003e\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\"error\": \"required properties not found: 'title', 'content', 'author'\"\u003cbr/\u003e\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;}\u003cbr/\u003e\u0026nbsp;\u0026nbsp;]\u003cbr/\u003e} |\n\nNow we can see that the second JSON document shows several validation errors, namely the missing fields `title`, `content` and `author`.\n\nIf you don't want or need to know the validation error details, you may simply use the `dbms_json_schema.is_valid()` function.\n\nFinally, you can leverage the `dbms_json_schema.describe()` function to generate JSON schemas from existing relational objects such as tables, views, and JSON Relational Duality Views (more on that later).\n\n```sql\n-- Get the JSON schema from a relational table!\nselect dbms_json_schema.describe( 'BLOG_POSTS' ) as json_schema;\n```\nResults:\n\n| JSON_SCHEMA |\n|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|\n| {\u003cbr/\u003e\u0026nbsp;\u0026nbsp;\"title\": \"BLOG_POSTS\",\u003cbr/\u003e\u0026nbsp;\u0026nbsp;\"dbObject\": \"APIDAYS.BLOG_POSTS\",\u003cbr/\u003e\u0026nbsp;\u0026nbsp;\"type\": \"object\",\u003cbr/\u003e\u0026nbsp;\u0026nbsp;\"dbObjectType\": \"table\",\u003cbr/\u003e\u0026nbsp;\u0026nbsp;\"properties\": {\u003cbr/\u003e\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\"DATA\": {}\u003cbr/\u003e\u0026nbsp;\u0026nbsp;}\u003cbr/\u003e} |\n\n### Client-side validation using JSON Schema\n\nNow that we are able to create and retrieve JSON schemas from the database, we may consider the database as a central repository for JSON schemas that can be used by clients (backends and frontends) to validate JSON data.\n\nBelow, you can see a quick overview of a demo available in this [GitHub repository](https://github.com/loiclefevre/apidays-paris-2024):\n\n![React frontend form created from the json-schema-form library.](/img/posts/2025/oracle-case-study/json-schema-form.webp)\n\nUsing [Oracle REST Data Services](https://download.oracle.com/otn_software/java/ords/ords-latest.zip), we can indeed expose a JSON schema to a frontend via REST. Below, we are using the `json-schema-form` [library](https://github.com/remoteoss/json-schema-form) to build an input form from a JSON schema where `title`, `description`, and check constraints are used to define input fields and associated validation rules. Let's drill down into this example:\n\nWe'll start by creating a basic relational table that will store products:\n\n```sql\n-- drop table if exists products purge;\n\ncreate table products (\n name varchar2(100) not null primary key\n constraint minimal_name_length check (length(name) \u003e= 3),\n price number not null \n constraint strictly_positive_price check (price \u003e 0),\n quantity number not null \n constraint non_negative_quantity check (quantity \u003e= 0)\n);\n\ninsert into products (name, price, quantity)\nvalues ('Cake mould', 9.99, 15),\n ('Wooden spatula', 4.99, 42);\ncommit;\n```\n\nThis table has 3 columns. Each column has a named check constraint ensuring inserted values are conform with business rules (strictly positive prices, etc.).\n\nIf we retrieve the JSON schema corresponding to this relational table using `dbms_json_schema.describe()`, we'll also get these check constraints *translated* into the JSON schema format:\n\n```sql\n-- JSON Schema of PRODUCTS table\n-- Contains check constraints!\nselect dbms_json_schema.describe( 'PRODUCTS' ) as json_schema;\n```\nResults:\n\n```json\n{\n \"title\": \"PRODUCTS\",\n \"dbObject\": \"APIDAYS.PRODUCTS\",\n \"type\": \"object\",\n \"dbObjectType\": \"table\",\n \"properties\": {\n \"NAME\": {\n \"type\": \"string\",\n \"extendedType\": \"string\",\n \"maxLength\": 100,\n \"allOf\": [\n {\n \"minLength\": 3\n }\n ]\n }, \n \"PRICE\": {\n \"type\": \"number\",\n \"extendedType\": \"number\",\n \"allOf\": [\n {\n \"exclusiveMinimum\": 0\n }\n ]\n },\n \"QUANTITY\": {\n \"type\": \"number\",\n \"extendedType\": \"number\",\n \"allOf\": [\n {\n \"minimum\": 0\n }\n ]\n }\n },\n \"required\": [\n \"NAME\",\n \"PRICE\",\n \"QUANTITY\"\n\t],\n \"dbPrimaryKey\": [\n \"NAME\"\n ]\n}\n```\n\nOne thing we remark is the absence of `title` and `description` attributes for our 3 columns but considering JSON schemas are also JSON documents, we may enrich the JSON schema with the missing values.\n\n#### Database Schema Annotations\n\nStarting with the Oracle Database 23ai, you can leverage [Schema Annotations](https://docs.oracle.com/en/database/oracle/oracle-database/23/adfns/registering-application-data-usage-database.html#GUID-2DAF069E-0938-40AF-B05B-75AFE71D666C) to annotate database objects (columns, tables, views, indexes, etc.).\n\nConsider the following schema annotations:\n\n```sql\nALTER TABLE products MODIFY name ANNOTATIONS (\n ADD OR REPLACE \"title\" 'Name',\n ADD OR REPLACE \"description\" 'Product name (max length: 100)',\n ADD OR REPLACE \"minLength\" '3'\n);\n\nALTER TABLE products MODIFY price ANNOTATIONS (\n ADD OR REPLACE \"title\" 'Price',\n ADD OR REPLACE \"description\" 'Product price strictly positive',\n ADD OR REPLACE \"minimum\" '0.01'\n);\n\nALTER TABLE products MODIFY quantity ANNOTATIONS (\n ADD OR REPLACE \"title\" 'Quantity',\n ADD OR REPLACE \"description\" 'Quantity of products \u003e= 0',\n ADD OR REPLACE \"minimum\" '0'\n);\n```\n\nThese schema annotations provide additional information for each relational columns. Note that the `minimum` and `minLength` ones are here to work around a current `json-schema-form` library limitation (hopefully, this [open issue](https://github.com/remoteoss/json-schema-form/issues/102) will be solved soon).\n\nThese annotations are stored inside the database dictionary and can be retrieved via the `user_annotations_usage` dictionary view:\n\n```sql\n-- View annotations\nselect column_name, annotation_name, annotation_value\n from user_annotations_usage\n where object_name='PRODUCTS'\n and object_type='TABLE'\norder by 1, 2;\n```\nResults:\n\n|COLUMN_NAME|ANNOTATION_NAME|ANNOTATION_VALUE|\n|-|-|-|\n|NAME|description|Product name (max length: 100)|\n|NAME|minLength|3|\n|NAME|title|Name|\n|PRICE|description|Product price strictly positive|\n|PRICE|minimum|0.01|\n|PRICE|title|Price|\n|QUANTITY|description|Quantity of products \u003e= 0|\n|QUANTITY|minimum|0|\n|QUANTITY|title|Quantity|\n\nTo mix both, the table JSON schema with these column level annotations, we can use the following PL/SQL function:\n\n```sql\n-- Annotate JSON Schema with column level annotations\n-- p_table_name: the table name to work on\ncreate or replace function getAnnotatedJSONSchema( p_table_name in varchar2 )\nreturn json\nas\n schema clob; -- the original JSON schema\n l_schema JSON_OBJECT_T; -- the JSON schema as DOM to modify\n l_properties JSON_OBJECT_T; -- the \"properties\" JSON object entry of the JSON schema\n l_keys JSON_KEY_LIST; -- the list of JSON field names of \"properties\" JSON object\n l_column JSON_OBJECT_T; -- the JSON object to modify (for each column of the table)\nbegin\n -- get JSON schema of table\n select json_serialize( dbms_json_schema.describe( p_table_name )\n returning clob ) into schema;\n \n -- create a DOM object\n l_schema := JSON_OBJECT_T.parse( schema );\n -- access the \"properties\" JSON schema field that lists all the table columns\n l_properties := l_schema.get_Object('properties');\n -- get all the field names of this \"properties\" DOM: the table columns\n l_keys := l_properties.get_Keys();\n\n -- loop over all the columns...\n for i in 1..l_keys.count loop\n l_column := l_properties.get_Object( l_keys(i) );\n\n -- now retrieve from the database dictionary, all the annotations\n -- associated with this table column\n for c in (select ANNOTATION_NAME, ANNOTATION_VALUE \n from user_annotations_usage\n where object_name=p_table_name \n and object_type='TABLE' \n and column_name=l_keys(i))\n loop\n -- add each annotation found as a new key/value pair to the JSON schema \n -- for that table column\n l_column.put( c.ANNOTATION_NAME, c.ANNOTATION_VALUE );\n end loop;\n end loop;\n\n -- returns the annotated JSON schema\n return l_schema.to_json;\nend;\n/\n```\n\nThen one can use the function as below:\n\n```sql\nselect getAnnotatedJSONSchema( 'PRODUCTS' );\n```\nResults:\n\n```json\n{\n \"title\": \"PRODUCTS\",\n \"dbObject\": \"APIDAYS.PRODUCTS\",\n \"type\": \"object\",\n \"dbObjectType\": \"table\",\n \"properties\": {\n \"NAME\": {\n \"type\": \"string\",\n \"extendedType\": \"string\",\n \"maxLength\": 100,\n \"allOf\": [\n {\n \"minLength\": 3\n }\n ],\n \"title\": \"Name\",\n \"description\": \"Product name (max length: 100)\",\n \"minLength\": \"3\"\n },\n \"PRICE\": {\n \"type\": \"number\",\n \"extendedType\": \"number\",\n \"allOf\": [\n {\n \"exclusiveMinimum\": 0\n }\n ],\n \"description\": \"Product price strictly positive\",\n \"minimum\": \"0.01\",\n \"title\": \"Price\"\n },\n \"QUANTITY\": {\n \"type\": \"number\",\n \"extendedType\": \"number\",\n \"allOf\": [\n {\n \"minimum\": 0\n }\n ],\n \"title\": \"Quantity\",\n \"description\": \"Quantity of products \u003e= 0\",\n \"minimum\": \"0\"\n }\n }, \n \"required\": [\n \"NAME\", \n \"PRICE\",\n \"QUANTITY\"\n ],\n \"dbPrimaryKey\": [\n \"NAME\"\n ]\n}\n```\n\n#### GET method\n\nThe previous SQL query can then be used as the parameterized template for our REST end point for the GET method:\n\n```sql\n-- Run only once:\nBEGIN\n ORDS.ENABLE_SCHEMA(\n p_enabled =\u003e TRUE,\n -- database user/schema\n p_schema =\u003e 'APIDAYS',\n p_url_mapping_type =\u003e 'BASE_PATH',\n p_url_mapping_pattern =\u003e 'apidays',\n p_auto_rest_auth =\u003e FALSE);\n \n ORDS.DEFINE_MODULE(\n p_module_name =\u003e 'apidays',\n p_base_path =\u003e '/schema_repository/',\n p_items_per_page =\u003e 25,\n p_status =\u003e 'PUBLISHED',\n p_comments =\u003e NULL);\n\n ORDS.DEFINE_TEMPLATE(\n p_module_name =\u003e 'apidays',\n p_pattern =\u003e 'products',\n p_priority =\u003e 0,\n p_etag_type =\u003e 'HASH',\n p_etag_query =\u003e NULL,\n p_comments =\u003e NULL);\n\n ORDS.DEFINE_HANDLER(\n p_module_name =\u003e 'apidays',\n p_pattern =\u003e 'products',\n p_method =\u003e 'GET',\n p_source_type =\u003e 'json/item',\n p_mimes_allowed =\u003e NULL,\n p_comments =\u003e NULL,\n p_source =\u003e \n'select getAnnotatedJSONSchema( ''PRODUCTS'' ) as schema');\n \nCOMMIT;\n\nEND;\n/\n```\n\nIn the [GitHub repositoy](https://github.com/loiclefevre/apidays-paris-2024/blob/main/src/ORDS.js), you'll find the `src/ORDS.js` module that demonstrates using this REST method:\n\n```js\nimport axios from 'axios';\n\nfunction ORDS() {}\n\nORDS.prototype.getSchema = async function() {\n return await axios.get(\n 'http://localhost/ords/apidays/schema_repository/products', \n {}\n )\n .then( res =\u003e res.data.schema )\n .catch(err =\u003e err);\n}\n\nexport default new ORDS();\n```\n\nWith all this in place, our React frontend can now create the following form:\n\n![React frontend with input form generated from an annotated Oracle Database 23ai JSON schema.](/img/posts/2025/oracle-case-study/form.webp)\n\n\u003e Interestingly, whenever you change the schema annotation in the database, it is immediately reflected inside your browser once you refreshed it. You can try with:\n\u003e ```sql\n\u003e ALTER TABLE products MODIFY name ANNOTATIONS (\n\u003e REPLACE \"title\" 'Product name'\n\u003e );\n\u003e ```\n\u003e\n\n\n#### JSON Relational Duality View\n\nOnce the new product has been validated inside the frontend, it is sent to the database for insertion into the relational table. To ease this process, we'll leverage one of the greatest 23ai new features: **JSON Relational Duality View**.\n\nThis new type of view acts as a gateway between the JSON and relational worlds. Basically, one can insert JSON documents into a JSON relational duality view and the database will automatically map the proper JSON fields to the relational columns. From a retrieval perspective, whenever a JSON relational duality view is queried, a JSON document will be constructed from the underlying relational model at runtime.\n\nConsider this *very simple* example (not even involving relationships between tables, nor flex fields, etc.):\n\n```sql\n-- GraphQL notation (SQL notation also exists)\ncreate or replace json relational duality view products_dv as\nproducts @insert {\n _id: NAME\n PRICE\n QUANTITY\n};\n```\n\nHere we ask the view to accept `INSERT` SQL statements (via `@insert`) and remap the JSON `_id` attribute (mandatory JSON unique key) to the relational column `NAME` (note that JSON fields are case-sensitive). The other two attributes are automatically mapped because the JSON attributes and relational table column names are the same.\n\nYou can find hereunder the JSON schema of this JSON relational duality view:\n\n```sql\n-- Get JSON Schema from JSON Relational Duality View\nselect dbms_json_schema.describe( 'PRODUCTS_DV' );\n```\nResults:\n\n```json\n{\n \"title\": \"PRODUCTS_DV\",\n \"dbObject\": \"APIDAYS.PRODUCTS_DV\",\n \"dbObjectType\": \"dualityView\",\n \"dbObjectProperties\": [ \"insert\", \"check\" ], \n \"type\": \"object\", \n \"properties\": {\n \"_metadata\": {\n \"etag\": {\n \"type\": \"string\",\n \"extendedType\": \"string\",\n \"maxLength\": 200\n },\n \"asof\": {\n \"type\": \"string\",\n \"extendedType\": \"string\",\n \"maxLength\": 20\n }\n },\n \"_id\": {\n \"type\": \"string\",\n \"extendedType\": \"string\",\n \"maxLength\": 100,\n \"dbFieldProperties\": [ \"check\" ]\n },\n \"PRICE\": {\n \"type\": \"number\",\n \"extendedType\": \"number\",\n \"dbFieldProperties\": [ \"check\" ]\n },\n \"QUANTITY\": {\n \"type\": \"number\",\n \"extendedType\": \"number\",\n \"dbFieldProperties\": [ \"check\" ]\n }\n },\n \"dbPrimaryKey\": [\n \"_id\"\n ],\n \"required\": [\n \"_id\",\n \"PRICE\",\n \"QUANTITY\"\n ],\n \"additionalProperties\": false\n}\n```\n\nSo now we can run such an `INSERT` statement:\n\n```sql\n-- Insert JSON in a Relational table (Bridging the Gap...)\n-- by using the JSON Relational Duality View\ninsert into PRODUCTS_DV(data) values( \n json_transform( '{\n \"NAME\": \"Other nice product\", \n \"PRICE\": 5, \n \"QUANTITY\": 10\n }', \n RENAME '$.NAME' = '_id'\n )\n);\n\ncommit;\n```\n\nYou will notice that we are using the [`JSON_TRANSFORM()`](https://docs.oracle.com/en/database/oracle/oracle-database/23/adjsn/oracle-sql-function-json_transform.html) function to rename the `NAME` JSON attribute to `_id` expected by the `PRODUCTS_DV` JSON relational duality view.\n\n```sql\nselect * from products_dv;\nselect * from products;\n```\n\nRunning the 2 queries above respectively returns the data in JSON format:\n\n| DATA |\n|----------------------------------------------------------------------------------------------------------------------|\n| {\u003cbr/\u003e\u0026nbsp;\u0026nbsp;\"_id\": \"Cake mould\",\u003cbr/\u003e\u0026nbsp;\u0026nbsp;\"PRICE\": 9.99,\u003cbr/\u003e\u0026nbsp;\u0026nbsp;\"QUANTITY\": 15,\u003cbr/\u003e\u0026nbsp;\u0026nbsp;\"_metadata\": { ... }\u003cbr/\u003e} |\n| {\u003cbr/\u003e\u0026nbsp;\u0026nbsp;\"_id\": \"Wooden spatula\",\u003cbr/\u003e\u0026nbsp;\u0026nbsp;\"PRICE\": 4.99,\u003cbr/\u003e\u0026nbsp;\u0026nbsp;\"QUANTITY\": 42,\u003cbr/\u003e\u0026nbsp;\u0026nbsp;\"_metadata\": { ... }\u003cbr/\u003e} |\n| {\u003cbr/\u003e\u0026nbsp;\u0026nbsp;\"_id\": \"Other nice product\",\u003cbr/\u003e\u0026nbsp;\u0026nbsp;\"PRICE\": 5,\u003cbr/\u003e\u0026nbsp;\u0026nbsp;\"QUANTITY\": 10,\u003cbr/\u003e\u0026nbsp;\u0026nbsp;\"_metadata\": { ... }\u003cbr/\u003e} |\n\n...and relational format:\n\n|NAME|PRICE|QUANTITY|\n|-|-|-|\n|Cake mould|9.99|15|\n|Wooden spatula|4.99|42|\n|Other nice product|5|10|\n\n\u003e The `_metadata` object will contain additional information such as an `etag` that can be used for [optimistic concurrency control](https://docs.oracle.com/en/database/oracle/oracle-database/23/jsnvu/using-optimistic-concurrency-control-duality-views.html).\n\n#### POST method\n\nWith the JSON relational duality view in place, we can now implement the REST POST method by adding another ORDS handler:\n\n```sql\nBEGIN\n ORDS.DEFINE_HANDLER(\n p_module_name =\u003e 'apidays',\n p_pattern =\u003e 'products',\n p_method =\u003e 'POST',\n p_source_type =\u003e 'plsql/block',\n p_mimes_allowed =\u003e NULL,\n p_comments =\u003e NULL,\n p_source =\u003e \n'begin\n insert into PRODUCTS_DV( data ) values( json_transform(:body_text, RENAME ''$.NAME'' = ''_id'') );\n commit;\nend;');\n \nCOMMIT;\n\nEND;\n\n/\n```\n\n#### Precheck Check Constraints\n\nWith 23ai, a check constraint can now be marked as [`PRECHECK`](https://docs.oracle.com/en/database/oracle/oracle-database/23/adfns/data-integrity.html#GUID-278AD7DD-C45D-4F43-8D60-8ABA2B062296). Doing so tells the database that a relational check constraint has a corresponding JSON schema constraint that preserves the semantics of the constraint and hence the database doesn't need to verify the check again. An example of a constraint that has no corresponding JSON schema constraint could be a foreign key.\n\nOnce a check constraint is marked as `PRECHECK`, you have the choice whether or not to disable the check constraint on the table as the retrieved JSON schema with `dbms_json_schema.describe()` will contain the check constraints as well.\n\n\u003e We do **NOT** advise to disable check constraints as it would allow inserting bad data into the relational tables directly. The remark about `PRECHECK` constraints is here to provide as much information as possible.\n\n```sql\n-- Mark check constraints as PRECHECK\nalter table products modify constraint strictly_positive_price precheck;\nalter table products modify constraint non_negative_quantity precheck;\n\n-- Now disable the constraints at the database level\n-- They are checked in the clients\n--\n-- Warning: do that at your own risks!\nalter table products modify constraint strictly_positive_price disable;\nalter table products modify constraint non_negative_quantity disable;\n\n-- Check constraints still present inside the JSON Schema\nselect dbms_json_schema.describe( 'PRODUCTS' );\n\n-- but following INSERT will work and insert bad data\ninsert into products (name, price, quantity)\nvalues ('Bad product', 0, -1);\n\ncommit;\n\nselect * from products;\n```\n\n### Data Use Case Domains\n\nAnother way to validate JSON data is to associate a JSON schema with a JSON column. In 23ai, an extension of the ISO standard Domains is available: [Data Use Case Domains](https://docs.oracle.com/en/database/oracle/oracle-database/23/adfns/registering-application-data-usage-database.html#GUID-4743FDE1-7C6E-471B-BC9D-442383CCA2F9).\n\nConsider the following very simple data use case domain that could be considered as a scalar JSON data type alias:\n\n```sql\n-- Introducing Data Use Case Domains\ncreate domain if not exists jsonb as json;\n\ncreate table test ( \n data jsonb -- JSON alias\n);\n```\n\nDomains also allow for [centralizing JSON schema](https://docs.oracle.com/en/database/oracle/oracle-database/23/adjsn/json-schema.html#GUID-7D67DF73-CB21-4878-AF93-D1A213411EC0) so that they can be reused across tables and columns. The example below demonstrates how to associate a JSON schema within a data use case domain:\n\n```sql\n-- drop table if exists posts purge;\n-- drop domain if exists BlogPost;\ncreate domain if not exists BlogPost as json\nvalidate '{\n \"$id\": \"https://example.com/blog-post.schema.json\",\n \"$schema\": \"https://json-schema.org/draft/2020-12/schema\",\n \"description\": \"A representation of a blog post\",\n \"type\": \"object\",\n \"required\": [\"title\", \"content\", \"author\"],\n \"properties\": {\n \"title\": {\n \"type\": \"string\"\n },\n \"content\": {\n \"type\": \"string\"\n },\n \"publishedDate\": {\n \"type\": \"string\",\n \"format\": \"date-time\"\n },\n \"author\": {\n \"$ref\": \"https://example.com/user-profile.schema.json\"\n },\n \"tags\": {\n \"type\": \"array\",\n \"items\": {\n \"type\": \"string\"\n }\n }\n },\n \"$def\": {\n \"$id\": \"https://example.com/user-profile.schema.json\",\n \"$schema\": \"https://json-schema.org/draft/2020-12/schema\",\n \"description\": \"A representation of a user profile\",\n \"type\": \"object\",\n \"required\": [\"username\", \"email\"],\n \"properties\": {\n \"username\": {\n \"type\": \"string\"\n },\n \"email\": {\n \"type\": \"string\",\n \"format\": \"email\"\n },\n \"fullName\": {\n \"type\": \"string\"\n },\n \"age\": {\n \"type\": \"integer\",\n \"minimum\": 0\n },\n \"location\": {\n \"type\": \"string\"\n },\n \"interests\": {\n \"type\": \"array\",\n \"items\": {\n \"type\": \"string\"\n }\n }\n }\n }\n}';\n\n-- Now use the Domain as a new column data type!\ncreate table posts ( content BlogPost );\n\n-- fails\ninsert into posts values (json{ 'garbageDocument' : true });\n\n-- works\ninsert into posts values (\n json {\n 'title': 'Best brownies recipe ever!',\n 'content': 'Take chocolate...',\n 'publishedDate': '2024-12-05T13:00:00Z',\n 'author': {\n 'username': 'Bob',\n 'email': 'bob@blogs.com'\n },\n 'tags': ['Cooking', 'Chocolate', 'Cocooning']\n }\n);\n\ncommit;\n```\n\nNow let's look closer at the `publishedDate` field:\n\n```sql\nselect p.content.publishedDate \n from posts p;\n\n-- the binary encoded data type is 'string'\nselect p.content.publishedDate.type() as type \n from posts p;\n```\nResults:\n\n|TYPE|\n|-|\n|string|\n\nUsing the `type()` [item method](https://docs.oracle.com/en/database/oracle/oracle-database/23/adjsn/sql-json-path-expression-item-methods.html), we can see the date is in fact stored as a string.\n\n## Performance Improvement\n\nWith data use case domains, the Oracle Database 23ai can not only use JSON schema for JSON data validation but it can also improve performance by leveraging the [`CAST`](https://docs.oracle.com/en/database/oracle/oracle-database/23/adjsn/json-schema.html#GUID-50DD1C0D-A1C1-49BA-88A5-977EB1B734FA) functionality. Consider the following data use case domain example:\n\n```sql\ndrop table if exists posts purge;\n\ndrop domain if exists BlogPost;\n\n-- Recreate the Domain with CAST/Type coercion enabled\ncreate domain BlogPost as json\nvalidate CAST using '{\n \"$id\": \"https://example.com/blog-post.schema.json\",\n \"$schema\": \"https://json-schema.org/draft/2020-12/schema\",\n \"description\": \"A representation of a blog post\",\n \"type\": \"object\",\n \"required\": [\"title\", \"content\", \"author\"],\n \"properties\": {\n \"title\": {\n \"type\": \"string\"\n },\n \"content\": {\n \"type\": \"string\"\n },\n \"publishedDate\": {\n \"extendedType\": \"timestamp\",\n \"format\": \"date-time\"\n },\n \"author\": {\n \"$ref\": \"https://example.com/user-profile.schema.json\"\n },\n \"tags\": {\n \"type\": \"array\",\n \"items\": {\n \"type\": \"string\"\n }\n }\n },\n \"$def\": {\n \"$id\": \"https://example.com/user-profile.schema.json\",\n \"$schema\": \"https://json-schema.org/draft/2020-12/schema\",\n \"description\": \"A representation of a user profile\",\n \"type\": \"object\",\n \"required\": [\"username\", \"email\"],\n \"properties\": {\n \"username\": {\n \"type\": \"string\"\n },\n \"email\": {\n \"type\": \"string\",\n \"format\": \"email\"\n },\n \"fullName\": {\n \"type\": \"string\"\n },\n \"age\": {\n \"type\": \"integer\",\n \"minimum\": 0\n },\n \"location\": {\n \"type\": \"string\"\n },\n \"interests\": {\n \"type\": \"array\",\n \"items\": {\n \"type\": \"string\"\n }\n }\n }\n }\n}';\n\ncreate table posts ( content BlogPost );\n```\n\nBy enabling the JSON schema for type **CAST**ing, we can request the database to use the new `extendedType` during the binary JSON encoding process. In the example above, this would mean that the encoded type would be a `timestamp` and no longer a `string` resulting in less parsing overhead compared to the previous version: from `string` to `timestamp` each time we retrieve the field for SQL processing (`WHERE` clause filtering, `SELECT` projection, etc.).\n\nLet's check this:\n\n```sql\ncreate table posts ( content BlogPost );\n\n-- We can retrieve the JSON schema associated to the column\n-- via the Data Use Case Domain\nselect dbms_json_schema.describe( 'POSTS' );\n\n-- works\ninsert into posts values (\n'{\n \"title\": \"Best brownies recipe ever!\",\n \"content\": \"Take chocolate...\",\n \"publishedDate\": \"2024-12-05T13:00:00Z\",\n \"author\": {\n \"username\": \"Bob\",\n \"email\": \"bob@blogs.com\"\n },\n \"tags\": [\"Cooking\", \"Chocolate\", \"Cocooning\"]\n }'\n);\ncommit;\n\n-- Now let's look at the publishedDate field...\nselect p.content.publishedDate from posts p;\n\n-- ...its binary encoded data type is 'timestamp'\nselect p.content.publishedDate.type() from posts p;\n\n-- I can add 5 days to this date...\nselect p.content.publishedDate.timestamp() + interval '5' day \nfrom posts p;\n```\n\n\u003e We use the item method `timestamp()` in the last statement above because otherwise the SQL dot notation would return a SQL `JSON` (by default in 23ai) on which we cannot apply an interval operation. However, because the value is already stored as `TIMESTAMP` inside the binary JSON format, there will be *no conversion* from `JSON` to `timestamp` here.\n\nLast but not least, by enabling type casting, native SQL data type checks are also performed ensuring 100% fidelity between stored binary values in the encoded JSON and SQL data types. As a result, we can store not just the standard JSON data types but also the SQL data types inside the encoded binary JSON such as `NUMBER`, `DATE`, `TIMESTAMP`, `TIMESTAMP WITH TIME ZONE`, `INTERVAL`, `RAW`, `VECTOR`, etc.\n\n## Relational Model Evolution\n\nOur last use case that leverages JSON schema inside the Oracle Database is available since version 12cR2. Imagine, you are a data analyst and the only tool you have to build charts only allows you to see tables and columns. Each time a new data attribute is added, you know that it will take time before you see it appearing inside your BI tool because of the involved development processes.\n\nNow, imagine this is no more the case...\n\nLet's look at the following example:\n\n```sql\ncreate table orders ( j json );\n\ninsert into orders(j) values (\n json { 'firstName': 'Bob', 'address': 'Paris' }\n);\ncommit;\n\nselect j from orders;\n```\nResults:\n\n| J |\n|------------------------------------------------------------------------|\n| {\u003cbr/\u003e\u0026nbsp;\u0026nbsp;\"firstName\": \"Bob\",\u003cbr/\u003e\u0026nbsp;\u0026nbsp;\"address\": \"Paris\"\u003cbr/\u003e} |\n\nWe have an `orders` table with one column containing a JSON document. The JSON document itself has 2 fields and 2 values. Now, we'll create a [**JSON Search index**](https://docs.oracle.com/en/database/oracle/oracle-database/23/adjsn/json-search-index-ad-hoc-queries-and-full-text-search.html) (that can perform Full-Text search). This index can optionally maintain a JSON Data Guide in real-time, meaning the JSON schema for the JSON documents stored inside the JSON column.\n\nWith this ability comes another one: [Change Triggers For Data Guide-Enabled Search Index](https://docs.oracle.com/en/database/oracle/oracle-database/23/adjsn/change-triggers-data-guide-enabled-search-index.html#GUID-2F4C6F52-0D96-4405-8F85-CDA0B234D0D5) which, based on the maintained JSON schema, can react to any newly added JSON attributes and dynamically expose these by adding the corresponding virtual columns.\n\nThe example below demonstrates this behavior:\n\n```sql\n-- drop index s_idx force;\n\n-- Create a Full-Text Search index for JSON with Data Guide\n-- enabled and add_vc stored procedure enabled to change\n-- table structure: add virtual column for JSON fields,\n-- helpful for Analytics =\u003e you directly have the existing\n-- JSON fields listed as columns!\ncreate search index s_idx on orders(j) for json\nparameters('dataguide on change add_vc');\n\nselect * from orders;\n```\nResults:\n\n| J |J$address|J$firstName|\n|-------------------------------------------------------------------|-|-|\n| {\u003cbr/\u003e\u0026nbsp;\u0026nbsp;\"firstName\": \"Bob\",\u003cbr/\u003e\u0026nbsp;\u0026nbsp;\"address\": \"Paris\"\u003cbr/\u003e} |Paris|Bob|\n\n```sql\ninsert into orders(j) values (\n json { 'firstName': 'Bob', 'address': 'Paris', 'vat': false }\n);\ncommit;\n\nselect * from orders;\n```\nResults:\n\n| J |J$address|J$firstName|J$vat|\n|--------------------------------------------------------------------------------------|-|-|-|\n| {\u003cbr/\u003e\u0026nbsp;\u0026nbsp;\"firstName\": \"Bob\",\u003cbr/\u003e\u0026nbsp;\u0026nbsp;\"address\": \"Paris\"\u003cbr/\u003e} |Paris|Bob|null|\n| {\u003cbr/\u003e\u0026nbsp;\u0026nbsp;\"firstName\": \"Bob\",\u003cbr/\u003e\u0026nbsp;\u0026nbsp;\"address\": \"Paris\",\u003cbr/\u003e\u0026nbsp;\u0026nbsp;\"vat\": false\u003cbr/\u003e} |Paris|Bob|false|\n\n```sql\n\ninsert into orders(j) values (\n json { 'firstName': 'Bob', 'address': 'Paris', 'vat': false, 'tableEvolve': true }\n);\ncommit;\n\nselect * from orders;\n```\nResults:\n\n| J |J$address|J$firstName|J$vat|J$tableEvolve|\n|----------------------------------------------------------------------------------------------------------------------|-|-|-|-|\n| {\u003cbr/\u003e\u0026nbsp;\u0026nbsp;\"firstName\": \"Bob\",\u003cbr/\u003e\u0026nbsp;\u0026nbsp;\"address\": \"Paris\"\u003cbr/\u003e} |Paris|Bob|null|null|\n| {\u003cbr/\u003e\u0026nbsp;\u0026nbsp;\"firstName\": \"Bob\",\u003cbr/\u003e\u0026nbsp;\u0026nbsp;\"address\": \"Paris\",\u003cbr/\u003e\u0026nbsp;\u0026nbsp;\"vat\": false\u003cbr/\u003e} |Paris|Bob|false|null|\n| {\u003cbr/\u003e\u0026nbsp;\u0026nbsp;\"firstName\": \"Bob\",\u003cbr/\u003e\u0026nbsp;\u0026nbsp;\"address\": \"Paris\",\u003cbr/\u003e\u0026nbsp;\u0026nbsp;\"vat\": false,\u003cbr/\u003e\u0026nbsp;\u0026nbsp;\"tableEvolve\": true\u003cbr/\u003e} |Paris|Bob|false|true|\n\n\u003e The trigger executes asynchronously, hence not delaying DML response times, however, because of it being asynchronous, it may take a second before you will see the new virtual column.\n\n## Conclusion\n\nWe have shown lots of features inside the Oracle Database 23ai which provide powerful capabilities to have JSON data coexist with relational data, and JSON schema clearly strengthens this even more. But this is only the beginning and as you discover more and more features that work the same way regardless of the data model, or that allow going back and forth from one model to another, you'll understand the true value of a converged database which has one goal: removing barriers, simplifying architecture and making developers more productive!\n\n![Oracle Database 23ai is a converged database now supporting JSON schema.](/img/posts/2025/oracle-case-study/converged_database.webp)\n\nLean more:\n- [Oracle Database 23ai `DBMS_JSON_SCHEMA` PL/SQL package](https://docs.oracle.com/en/database/oracle/oracle-database/23/arpls/DBMS_JSON_SCHEMA.html#GUID-89B9C48D-D905-482C-A78C-8DB314EDF072)\n- [Oracle Database 23ai JSON Developer Guide](https://docs.oracle.com/en/database/oracle/oracle-database/23/adjsn/index.html)\n- [Getting started with Oracle Database 23ai](https://medium.com/db-one/oracle-database-download-install-tutorial-my-getting-started-guide-044925c10ca2)\n- [Oracle Database 23ai JSON Feature Highlights](https://www.oracle.com/database/23ai/#json)\n"},{"slug":"gsoc24-wrapup","frontmatter":{"title":"Celebrating JSON Schema’s Google Summer of Code 2024 Journey","date":"2025-01-17","tags":["News"],"type":"Community","cover":"/img/posts/2025/gsoc24/gsoc24-banner-main.png","authors":[{"name":"Onyedikachi Hope Amaechi-Okorie","photo":"/img/avatars/onyedikachi.jpg","link":"https://www.linkedin.com/in/amaechihope/","byline":"Community and Developer Relations Manager"}],"excerpt":"Discover the projects, mentors, and contributors that shaped Google Summer of Code (GSoC) 2024!"},"content":"\nLast year, JSON Schema proudly participated in Google Summer of Code (GSoC) 2024, a global program designed to bring fresh talent into open-source communities. Through this initiative, we tackled some of our most exciting projects yet, creating opportunities for contributors to make meaningful impacts while gaining valuable experience.\n\nWe’re thrilled to share the highlights of this journey and the incredible work our contributors and mentors achieved together.\n\n## A Unique Start: Setting the Stage for Success\nFor JSON Schema, GSoC 2024 wasn’t just about welcoming contributors but about setting a high standard. Before selection, applicants underwent a qualification test, allowing us to assess technical skills and alignment with project goals. This ensured each participant had the tools and mindset to thrive.\n\nHere’s what stood out in our journey:\n\n* 8 projects completed across diverse aspects of JSON Schema.\n* A record number of applicants, with a community brimming with enthusiasm.\n* Returning mentors and contributors, bringing experience and new perspectives.\n\n## Transformative Projects and Talent Contributors\n\n### 1. Bowtie-Trend: Long-Term Reporting With Bowtie\n\n* Contributor: [Adwait Godbole](https://github.com/adwait-godbole)\n* Mentors: [Julian Berman](https://github.com/Julian), [Agnivesh Chaubey](https://github.com/AgniveshChaubey)\n* [Idea on GitHub](https://github.com/json-schema-org/community/issues/607)\n\nThe project aims to enhance [Bowtie](https://github.com/bowtie-json-schema/bowtie), a meta-validator for the JSON Schema specification that coordinates the execution of validator implementations and reports their results. While Bowtie already generates compliance reports accessible [here](https://bowtie.report), this project introduces a mechanism to track compliance metrics over time. The goal is to enable graphing and querying of how test results evolve as implementations fix bugs or new tests are added. Key outcomes include a new bowtie trend command to aggregate results into trend reports and a dedicated webpage displaying graphs of failed tests over time, providing deeper insights into long-term compliance trends.\n\n### 2. Bowtie-Perf: A Performance Tester for JSON Schema Implementations\n\n* Contributor: [Dhruv Singh](https://github.com/sudo-jarvis)\n* Mentors: [Julian Berman](https://github.com/Julian), [Agnivesh Chaubey](https://github.com/AgniveshChaubey)\n* [Idea on Github](https://github.com/json-schema-org/community/issues/605)\n\nThe project enhances [Bowtie](https://github.com/bowtie-json-schema/bowtie), a meta-validator of the JSON Schema specification. Bowtie provides universal access to JSON Schema implementations, enabling users to validate instances and identify bugs or gaps in functionality. Currently, Bowtie supports validating instances against schemas and comparing implementations based on correctness. This project expands its capabilities by developing a performance tester integrated within Bowtie. This addition provides a critical dimension for performance optimization and enables more comprehensive comparisons across JSON Schema implementations.\n\n### 3. Setting up the CI/CD Pipeline for the JSON Schema Website\n\n* Contributor: [Alok Gupta](https://github.com/aialok)\n* Mentor: [Benjamin Granados](https://github.com/benjagm)\n* [Idea on Github](https://github.com/json-schema-org/community/issues/603)\n\nThe Improved CI/CD Workflow for the [website](https://github.com/json-schema-org/website) project with GitHub Actions project focuses on enhancing the existing CI/CD pipelines by adding essential features like linting, formatting, unit testing, UI testing, broken link checks, and build processes. The project involves streamlining workflows for pull requests, pushes, and issues, with special emphasis on first-time contributors. Key deliverables include creating and optimizing workflows such as PR workflows, push workflows, issue workflows, stale issue and PR reminders, unauthorized file detection, and CodeQL for security analysis. Additionally, the project aims to provide clear documentation on workflow roles and guidelines for updates, ensuring smoother community operation integration and more efficient code management.\n\n### 4. Building a New Version of the JSON Schema Tooling Page\n\n* Contributor: [DV](http://github.com/darhkvoyd)\n* Mentor: [Benjamin Granados](https://github.com/benjagm)\n* [Idea on Github](https://github.com/json-schema-org/community/issues/602)\n\nThe JSON Schema [Tooling Page](https://json-schema.org/tools) plays a vital role in helping developers explore the ecosystem of JSON Schema tools and implementations. However, its current design presents usability challenges that hinder adoption. This project aims to rebuild the tooling page using a data-driven approach while adhering to the updated UI/UX standards of the JSON Schema website. By improving accessibility, simplifying navigation, and enhancing clarity, the revamped tooling page will make JSON Schema implementations more discoverable and user-friendly, ultimately reducing friction and encouraging broader adoption within the developer community.\n\n### 5. JSON Schema Language Server Contributions\n\n* Contributor: [Diya Solanki](https://github.com/diyaayay)\n* Mentor: [Jason Desrosiers](https://github.com/jdesrosiers)\n* [Idea on Github](https://github.com/json-schema-org/community/issues/601)\n\nThe project focuses on enhancing the [Language Server Protocol (LSP)](https://github.com/hyperjump-io/json-schema-language-tools) for JSON Schema, enabling improved support for various editors and IDEs. Unlike the existing VSCode integration, which lacks support for recent JSON Schema versions and struggles with performance for large schemas, this project aims to expand functionality. Key improvements include inline diagnostics for invalid schemas, semantic highlighting for JSON Schema and deprecated keywords, support for multiple drafts (04/06/07/2019-09/2020-12), and enhanced configuration management. The project also focuses on adding code completion for $schema, making JSON Schema development more efficient and accessible across platforms.\n\n### 6. Define Upgrade/Downgrade Language-Agnostic Declarative Transformation Rules for all JSON Schema Dialects\n\n* Contributor: [Suprith KG](https://github.com/suprith-hub)\n* Mentor: [Juan Cruz Viotti](https://github.com/jviotti)\n* [Idea on Github](https://github.com/json-schema-org/community/issues/599)\n\nThe project addresses the challenges of maintaining software compatibility across different schema versions. It focuses on creating declarative, language-agnostic rules to streamline the process of [upgrading or downgrading JSON Schemas](https://github.com/json-schema-org/upgrade-downgrade-rules). This is crucial for users working with high-level languages like Python, managing large documents, or navigating diverse network communication setups such as HTTP, WebSocket, microservices, or IoT. By simplifying schema transformations and introducing standardized procedures, this project aims to save time, ensure reliability, and improve JSON Schema’s versatility across various implementations and use cases.\n\n### 7. Source Generation Analyzer Powered by Corvus.JsonSchema (.NET)\n\n* Contributor: [Pranay Joshi](https://github.com/pranayjoshi)\n* Mentors: [Matthew Adams (Endjin)](https://github.com/mwadams), [Greg Dennis](https://github.com/gregsdennis)\n* [Idea on Github](https://github.com/json-schema-org/community/issues/614)\n\nThe project focuses on creating a source generator that integrates seamlessly with [Corvus.JsonSchema](https://github.com/corvus-dotnet/corvus.jsonschema). This tool will automatically generate code from JSON Schema files within a .NET project at compile time, streamlining the development process. The ultimate goal is to foster collaboration and consistency across software development teams using diverse technology stacks by establishing JSON Schema as a unified source of truth for data modeling. This ensures that generated code adheres to a standardized data structure, improving efficiency and alignment within organizations.\n\n### 8. A Tour of JSON Schema\n\n* Contributor: [Zeel Rajodiya](https://github.com/JeelRajodiya)\n* Mentors: [Bence Eros](https://github.com/erosb), [Benjamin Granados](https://github.com/benjagm)\n* [Idea on Github](https://github.com/json-schema-org/community/issues/645)\n\nThe [Tour of JSON Schema](https://github.com/json-schema-org/tour) project is an interactive learning platform designed to help beginners quickly grasp JSON Schema concepts and best practices. Through step-by-step lessons and hands-on exercises, users can learn by doing, using a simple interface and built-in code editor. The platform provides practical examples, real-time validation of JSON Schema, and immediate feedback, making the learning process engaging and effective. By following structured lessons, users will gain the confidence to create and work with JSON Schemas independently.\n\n## Mentorship: A Two-Way Learning Process\n\nThe success of GSoC 2024 for JSON Schema wouldn’t have been possible without our dedicated mentors. They not only guided contributors but also gained fresh perspectives from working closely with emerging talent.\n\n## Watch the Journey\n\nWant to hear more about the contributors’ stories? Watch our [YouTube presentation](https://www.youtube.com/watch?v=2V9k1Hqhgnw) where contributors reflect on their challenges, successes, and learning moments.\n\n## Looking Forward\n\nGSoC 2024 has left an indelible mark on JSON Schema. From automation to tooling, each project has strengthened our ecosystem and laid a foundation for continued innovation.\nWe are excited about the future and invite developers from around the world to join us in shaping it.\n\n## Ready to contribute?\nExplore our [GitHub repository](https://github.com/json-schema-org), get involved in discussions, and be a part of the JSON Schema community!\n\nBackground photo by \u003ca href=\"https://unsplash.com/@jessbaileydesigns?utm_content=creditCopyText\u0026utm_medium=referral\u0026utm_source=unsplash\"\u003eJess Bailey\u003c/a\u003e \non \u003ca href=\"https://unsplash.com/photos/colored-pencil-lined-up-on-top-of-white-surface-l3N9Q27zULw?utm_content=creditCopyText\u0026utm_medium=referral\u0026utm_source=unsplash\"\u003eUnsplash\u003c/a\u003e\n"},{"slug":"stable-json-schema","frontmatter":{"title":"Moving Toward a Stable Spec","date":"2025-01-13","tags":["specification","stable"],"type":"Update","cover":"/img/posts/2025/stable-json-schema/mt-taranaki.webp","authors":[{"name":"Greg Dennis","photo":"/img/avatars/gregsdennis.webp","link":"https://www.linkedin.com/in/gregdennis/","byline":"Specification Author \u0026 JSON Tooling Implementer"}],"excerpt":"Amidst all of the change at JSON Schema, what's happening with the spec?"},"content":"\nMany of you may have noticed a lot of changes happening around the JSON Schema community. This website has had a facelift, we've started appearing at developer conferences, and we even participated in Google's Summer of Code \u0026 Summer of Docs programs. But many of you may be asking, \"What's happening with the spec?\"\n\nIn this post I'll be providing an update on specification development and our new publication process.\n\n## Publication Process\n\nIn a [previous post](./json-schema-joins-the-openjsf), we announced that we were no longer publishing our specifications through the IETF. At the time, the intent was to join the OpenJS Foundation, however for multiple reasons, the onboarding process was not able to be completed. As such, currently we are independent. In the future, we may again seek to join a foundation (we may even try OpenJS again), but for now, independence seems to be the best place for us.\n\nWhen we last published a specification, we used the IETF's [Internet-Draft Publication Process](https://authors.ietf.org/en/rfc-publication-process). This meant that our documents were required to retain the \"draft\" moniker, even though we considered them fully fledged and ready for use in production systems. Publishing independently, we're no longer bound by this requirement, however it does mean that we can no longer rely on the IETF document publishing infrastructure. We have to build our own.\n\nThe foundation of our publication process is built on several ideals, and I'll cover the major ones in the next few sections. By focusing on these pillars, we can ensure a safe and easy upgrade path for our users as the specification continues to evolve.\n\n### Minimize Backward-Incompatible Changes Between Releases\n\nOne of the primary complaints we received about releasing a new specification over the last few iterations, particularly between Drafts 2019-09 and 2020-12, is the lack of consideration for backward compatibility.\n\nJust to highlight a few of the breaking changes introduced with the latest version:\n\n- `$recursiveRef` / `$recursiveAnchor` became `$dynamicRef` / `$dynamicAnchor`\n- Array-form `items` became `prefixItems`\n- `additionalItems` was removed; use schema-form `items` now\n\nThese changes meant that a schema written for Draft 2019-09 could validate completely differently when processed under Draft 2020-12 rules. This creates a very poor upgrade experience.\n\nIn defending our decision to include these breaking changes, we hid behind our own advice to schema authors to include the `$schema` keyword, which identifies the dialect (specification version), instead of designing a [pit of success](https://blog.codinghorror.com/falling-into-the-pit-of-success/) that allowed them to continue their current behavior in a system that \"just works\".\n\n**_Moving forward, upgrade compatibility is our #1 concern when developing a new release._**\n\nThat doesn't mean that a breaking change will _never_ happen, but we will make every effort to ensure that it doesn't.\n\n### Maximize Forward Compatibility\n\n**_We need to protect ourselves from potential future changes that would harm or prevent backward compatibility._**\n\nIronically, this means introducing a breaking change. (I had [posted](./the-last-breaking-change) about this a couple of years ago, and the reception wasn't awesome, which led to a [follow-up post](./custom-annotations-will-continue).)\n\nIn short, to preserve future compatibility, we need to ensure that schemas can't contain extra properties which may one day be proposed as legitimate keywords. This means that extra data in schemas can no longer be acceptable. To accommodate our users' need to include meta-data and other values in their schemas, the specification will define a convention or namespace for property names that are to be ignored, and we guarantee that no future proposed keyword may follow this convention in order to keep the namespace protected.\n\nAs it stands today, the convention is that your property name should start with `x-`. If you like, you can read about alternative ideas and how we decided on this approach in [the ADR](https://github.com/json-schema-org/json-schema-spec/blob/main/adr/2023-04-sva-prefix.md).\n\n### Formally Define a Feature Proposal Process\n\nIn the past, new features would just be added to the specification and released with the next version. We held it as acceptable that a feature may not be fully finished when we released the specification. We expected to receive feedback, and the feature would be updated in the next version.\n\nHowever, this approach puts a large burden on tooling maintainers who want to support multiple versions of the specification, which is basically all of them. They'd have to support many different behaviors, sometimes for the same keyword.\n\nThe perfect example of this is Draft 2019-09's `$recursiveRef` \u0026 `$recursiveAnchor`. The idea was solid and had a lot going for it. In 2019 when we were working on it, we developed the concept as best we could, but we needed actual user feedback, so we added it to the specification, knowing that it wasn't quite complete. Prior to releasing the specification, a few of us who had implementations also added it as an optional feature to let our users try it out. But after the specification was released, we found that many users were confused as to how it should work, and we identified several ways that we could make it better. Those improvements became `$dynamicRef` \u0026 `$dynamicAnchor` in Draft 2020-12. Even though the \"recursive\" keywords weren't part of the latest specification, many implementations wanted to support Draft 2020-12 while continuing to support Draft 2019-09. Furthermore, schemas which contained the \"recursive\" keywords couldn't be processed under the Draft 2020-12 rules, which takes us back to the backward compatibiility problem.\n\n**_We need a feature proposal process that encourages tool support while also allowing continued feature development._**\n\nBy introducing a feature proposal process, all tooling maintainers can add support as they elect to do so. And because these proposals aren't considered a hard requirement of the specification, we can continue to iterate on them (including breaking changes). Finally, by actively encouraging tooling support, we can obtain the real-world feedback that we need to ensure that the feature is the best it can be before we officially integrate it into the specification.\n\n## Compatibility with Draft 2020-12\n\nTo close this out, and with all of the above in mind, I want to cover what the upcoming release will entail as it stands now.\n\nFirst, the incompatibilities:\n\n- As mentioned before, we won't be supporting arbitrary properties anymore. Any extra data you wish to include will need to use the `x-` property name convention.\n- The `$dynamicRef` / `$dynamicAnchor` referencing system will be completely disjoint from the `$ref` / `$id` / `$anchor` system. In Draft 2020-12, `$dynamicRef` could sometimes fall back to a normal `$ref` behavior. This has been very confusing, so we've just isolated the two referencing systems. This is _technically_ a breaking change, but we're pretty certain no one ever used `$dynamicRef` expecting it to work like `$ref`.\n- `format` will validate by default. There was a lot of [discussion](https://github.com/json-schema-org/json-schema-spec/issues/1520) on this topic, but the deciding factor was that users generally expect it to validate, and we wanted to meet that expectation.\n- Vocabularies are being demoted to a feature proposal. This was one of those ideas that wasn't completely finished when it was added to the spec in Draft 2019-09. It's likely that this feature will change substantially before being merged back into the specification. As a proposal, the feature can still be supported as development continues, but it's not a hard requirement.\n\nAdditionally, but not breaking:\n\n- The recommended output format introduced in Draft 2019-09 has been extracted to its own specification. The two driving factors for this decision were that different output formats could be more beneficial to different consumers and having the output versioned separately from the specification would more easily allow them to evolve independently.\n- Many keyword interaction behaviors were defined by the annotations that were produced at various levels of evaluation. This led to some confusion and unnecessary requirements, so we've loosened the language around this to allow tooling to figure out how they want to implement the behavior rather than prescribing a particular approach.\n- General clean-up and clarifications to more accurately define behavior.\n\nBeyond that, we still have a lot to do, but not nearly as much as we had this time last year, and we still have to figure out the actual publication piece, i.e. how we want it on the website. We have the IETF-published documents mirrored here, and the new ones will likely go up next to those. It's just another thing we need to do. You can track our list of items on the [GitHub project board](https://github.com/orgs/json-schema-org/projects/15/views/1).\n\nIt's been four years since we published a new version, but we're getting really close, and I'm very excited. Stay tuned!\n\n_Cover image is of Mt. Taranaki in New Zealand, by [Sophie Turner](https://unsplash.com/@sophie_turner) on [Unsplash](https://unsplash.com/photos/mountain-near-body-of-water-during-daytime-LZVmvKlchM0)._\n"},{"slug":"apidays-paris-2024-recap","frontmatter":{"title":"JSON Schema conference: A milestone event at Apidays Paris 2024","date":"2024-12-19","tags":["News"],"type":"Community","cover":"/img/posts/2024/apidays-paris-2024-recap/json-schema-conference.png","authors":[{"name":"Valeria Hernandez","photo":"/img/avatars/valeria.webp","twitter":"valeriahhdez","byline":"Technical writer"}],"excerpt":"Apidays Paris 2024 was the venue for a significant milestone for our project: the first-ever JSON Schema Conference."},"content":"## Introduction\n[Apidays Paris](https://www.apidays.global/paris/), the flagship event of the apidays family, returned this year with a focus on \"The Future API Stack for Mass Innovation.\" This annual gathering of API enthusiasts, developers, and industry leaders brought together experts to discuss the latest trends and best practices in API design, API development, and API management.\n\nThis year's agenda highlighted the increasing role of AI in API development, exploring how AI can be used to automate tasks, improve API design, and enhance API performance.\nContinuing our successful partnership with [AsyncAPI](https://www.asyncapi.com/en) and [OpenAPI](https://www.openapis.org/), this year's event marked a significant milestone with the inaugural JSON Schema conference track. This dedicated track, sponsored by [Octue](https://www.octue.com/), delved deep into the world of JSON Schema, exploring its role in API design, validation, and documentation.\n\n## The first JSON Schema conference\n\nThe inaugural [JSON Schema conference track](https://conference.json-schema.org/) at apidays Paris 2024 was a resounding success. As part of the larger conference theme \"The Future API Stack for Mass Innovation,\" the track showcased JSON Schema's crucial role in modern API development and data contract design. \n\n\u003cfigure className='flex flex-wrap justify-center items-center gap-4 w-full'\u003e\n \u003cimg className='max-w-400 px-20' src='/img/posts/2024/apidays-paris-2024-recap/json-schema-team.jpg' alt=\"Five people standing at a booth labeled 'Standards'. They are smiling and looking at the camera. From left to right, their names are Benjamin Granados, Thomas Clark, Andreas Eberhart, Juan Cruz Viotti, and Ben Hutton.\"/\u003e\n \u003cfigcaption class=\"text-center text-gray-600 text-sm\"\u003eCommunity members at the standards booth shared with AsyncAPI, OpenAPI, and GraphQL. From left to right: Benjamin Granados (community manager), Thomas Clark (Octue CEO), Andreas Eberhart (JSON Schema ambassador), Juan Cruz Viotti (TSC member), and Ben Hutton (TSC member).\u003c/figcaption\u003e\n\u003c/figure\u003e\n\u003cbr\u003e\n\n[Ten comprehensive presentations](https://conference.json-schema.org/sessions/) spanned the spectrum of JSON Schema applications, from foundational concepts to cutting-edge implementations. The list of talks included:\n\n- JSON Schema for data design and contract, client and code generation by Tom Collins (DVLA, UK Gov)\n- IEC standards: Toward digital standards with JSON Schema by Thomas Clark (Octue CEO, conference sponsor)\n- Introducing Strands - a JSON Schema repository by Thomas Clark\n- JSON Schema: powering FINOS architecture as code by James Gough (Morgan Stanley)\n- Generic and extensible web of things manager using JSON Schema and AI by Andreas Eberhart (Dashjoin, JSON Schema ambassador)\n- High-performance JSON Schema validation in .NET by Matthew Adams (Endjin, TSC member)\n- JSON schema and relational databases: bridging the gap by Loic Lefèvre (Oracle)\n- Applying software engineering practices to JSON Schemas by Juan Cruz Viotti (Sourcemeta CEO, TSC member)\n- The state of JSON schema by Benjamin Granados (Celonis, TSC member)\n- Unlocking dynamic frontend development through JSON Schema by Neha Singla (Apple)\n\nThree major themes recurred throughout the track: data design and standardization, tooling infrastructure, and modern application integration. Particularly notable was the emphasis on JSON Schema's role in AI integration and automated API development, aligning perfectly with the broader conference focus on AI's increasing importance in the API landscape.\n\nOctue's sponsorship significantly bolstered the track's success, demonstrating their commitment to the JSON Schema community. This support enabled a diverse range of speakers to share their expertise and experiences.\n\nAudience engagement exceeded expectations. Attendees from various industries and organizations - such as fintech, renewable energy, IT, and government - participated in robust Q\u0026A sessions after each presentation. The discussions revealed both the growing adoption of JSON Schema across different sectors and the community's hunger for more knowledge about its practical applications.\n\n\u003cfigure className='flex flex-wrap justify-center items-center gap-4 w-full'\u003e\n \u003cimg className='max-w-400 px-20' src='/img/posts/2024/apidays-paris-2024-recap/loic-lefevre-talk.jpg' alt=\"Loic Lefevre presenting on stage at the APIDays Paris 2024 conference. The audience is seated in rows of chairs, facing the stage.\"/\u003e\n \u003cfigcaption class=\"text-center text-gray-600 text-sm\"\u003eA room full of people listening to Loïc Lefèvre’s engaging presentation on utilizing JSON schemas to manage relational databases.\u003c/figcaption\u003e\n\u003c/figure\u003e\n\u003cbr\u003e\n\nLooking ahead, this first dedicated track has laid a strong foundation for future JSON Schema events. The feedback highlighted the need to further showcase JSON Schema's versatility across different use cases, and plans are underway to expand and enhance next year's track. This successful launch not only validates JSON Schema's importance in modern API development but also signals the beginning of a new chapter in the community's growth and evolution.\n\n## Collaboration with organizations\n\nThe success of the JSON Schema track at apidays Paris 2024 highlighted the vital role of community collaboration in our growth. It also demonstrated how organizations collaborating with JSON Schema gain more than just visibility - they become part of a broader movement toward standardized, high-quality API development. \n\nHere's how your organization can benefit:\n- **Standardization \u0026 interoperability**: Ensure seamless data exchange and API integration.\n- **Improved data quality**: Minimize errors with robust data validation.\n- **Enhanced API design**: Streamline development with clear and concise schemas.\n- **Increased productivity**: Automate tasks and boost efficiency with JSON Schema tools.\n \nHere’s how you can become part of the initiative:\n- [Be an ambassador](https://github.com/json-schema-org/community/tree/main/programs/ambassadors): Share your JSON Schema expertise and champion its adoption.\n- [Become a sponsor](https://json-schema.org/overview/sponsors): Gain visibility and support the standard's growth.\n- [Contribute to the project](https://github.com/json-schema-org): Help us shape the future of JSON Schema development.\n- [Join our Slack workspace](https://json-schema.org/slack): Connect with the vibrant JSON Schema community.\n\n\nTogether, we can build a more robust and interoperable API ecosystem. \n\nA final thank you to Octue for sponsoring the conference, apidays Paris for hosting it, the organizers for their dedication and hard work, and the attendees for your valuable input and insightful questions. On behalf of JSON Schema, we look forward to seeing you again next year!\n\nAcknowledgments: The author would like to thank Onyedikachi Hope, Ben Hutton, and Benjamin Granados for their valuable feedback, which enhanced the quality of this article. \n"},{"slug":"GSOD-docs-project-2024","frontmatter":{"title":"Update from the Google Season of Docs 2024 Project","date":"2024-09-03","tags":["Google Season of Docs","Documentation","Community"],"type":"Documentation","cover":"/img/posts/2024/GSOD-docs-project-2024/duy-pham.webp","authors":[{"name":"Blessing Ene Anyebe","photo":"/img/avatars/blessing.webp","byline":"Technical Writter Google Season of Docs"},{"name":"Valeria Hernandez","photo":"/img/avatars/valeria.webp","byline":"Technical Writter Google Season of Docs"},{"name":"Dhairya Amrish Majmudar","photo":"/img/avatars/dhairya.webp","byline":"Software Engineer Google Season of Docs"},{"name":"Benjamin Granados","photo":"/img/avatars/benjagm.webp","byline":"Community Manager"}],"excerpt":"An announcement blog post to share the JSON Schema documentation efforts from the GSOD team."},"content":"\n## The JSON Schema documentation project\n\nThe main goal of JSON Schema's [documentation project](https://github.com/orgs/json-schema-org/discussions/687) is to create a scalable documentation architecture that is clear, consistent, and comprehensive. To achieve this through Google Season of Docs (GSoD), we focused on:\n\n- **[Restructuring the specification docs](https://github.com/json-schema-org/website/pull/823)**: The specification docs need a structure that helps all [personas](https://github.com/json-schema-org/community/issues/336#personas) understand how JSON Schema has evolved across different releases and the features introduced in each version.\n- **[Revamping the information architecture](https://github.com/json-schema-org/website/issues/790)**: The documentation needs a new information architecture that better aligns with the [documentation developer journey](https://www.figma.com/board/TRjQUw33K93y8RlJMSRkJs/JSON-dev-journey?node-id=0-1\u0026t=fF2pJ8IwpJvbFzDU-1) and organizes content based on the [diataxis framework](https://diataxis.fr/). The new information architecture's goal is to improve the onboarding experience and content findability.\n\n## The GSoD project accomplishments\n\nSince May, the team ([Valeria Hernandez](https://www.linkedin.com/in/valeriahhdez/), [Blessing Ene Anyebe](https://www.linkedin.com/in/anyebe-blessing-ene-kwennb/), [Dhairya Amrish Majmudar](https://www.linkedin.com/in/dhairya-majmudar/), and [Benjamin Granados](https://www.linkedin.com/in/benjagranados/)) has been working hard to achieve these goals. On the part of documentation, we have completed the following: \n\n- Conducted a thorough content audit\n- Mapped out the [developer experience journey](\u003c(https://www.figma.com/board/TRjQUw33K93y8RlJMSRkJs/JSON-dev-journey?node-id=0-1\u0026t=gYkdGtHk2sKrCQM0-0)\u003e)\n- Implemented the [keywords page](https://json-schema.org/understanding-json-schema/keywords)\n- Restructured the [specification docs](https://github.com/json-schema-org/website/pull/823)\n\nThe team has also introduced changes to the website, like a table of contents and a [Next-Previous](https://github.com/json-schema-org/website/pull/807) component that aim to improve content scannability and navigation. \n\n## The road ahead\n\nSo, what's pending? We're currently working on the [JSON Hyper-Schema](https://github.com/json-schema-org/website/issues/896) and [Migration pages](https://github.com/json-schema-org/website/issues/897), which are part of the specification docs. \n\nWe're also documenting [guidelines for docs contributions and text formatting](https://github.com/json-schema-org/website/pull/902), documenting missing keywords (see issues [951](https://github.com/json-schema-org/website/issues/951), [952](https://github.com/json-schema-org/website/issues/952), and [961](https://github.com/json-schema-org/website/issues/961)), and writing step-by-step guides (see issues [180](https://github.com/json-schema-org/website/issues/180), [950](https://github.com/json-schema-org/website/issues/950), and [954](https://github.com/json-schema-org/website/issues/954)). \n\n## Conclusion\n\nOur documentation efforts are expanding daily, and your contributions can improve them. There are several ways you can help, including:\n\n- Breaking down large documents to improve the overall structure of the documentation website\n- Creating missing documentation for the Troubleshooting and Scaling stages of the developer journey\n- Contributing to the Migration page\n\nOur docs meeting is held bi-weekly every Tuesday at 3:00 PM (UTC). You're welcome to join the #gsod24 channel in the JSON Schema [Slack workspace](https://json-schema.org/slack) and send us a message with your email address so we can add you to the meeting.\n\nWe appreciate your interest in the JSON Schema documentation project and look forward to your contributions and their benefits to the wider developer community.\n\n**The JSON Schema's Google Season of Docs Team.**\n\nPhoto by \u003ca href=\"https://unsplash.com/@miinyuii?utm_content=creditCopyText\u0026utm_medium=referral\u0026utm_source=unsplash\"\u003eDuy Pham\u003c/a\u003e on \u003ca href=\"https://unsplash.com/photos/people-holding-shoulders-sitting-on-wall-Cecb0_8Hx-o?utm_content=creditCopyText\u0026utm_medium=referral\u0026utm_source=unsplash\"\u003eUnsplash\u003c/a\u003e\n "}],"datesInfo":[{"title":"JSON Schema Open Community Working Meeting","time":"February 17th 2025, 20:00","day":"17","timezone":"UTC","parsedStartDate":"2025-02-17 20:00:00"},{"title":"JSON Schema Office Hours (APAC/Americas)","time":"March 4th 2025, 23:00","day":"4","timezone":"UTC","parsedStartDate":"2025-03-04 23:00:00"},{"title":"JSON Schema Open Community Working Meeting","time":"March 17th 2025, 20:00","day":"17","timezone":"UTC","parsedStartDate":"2025-03-17 20:00:00"},{"title":"JSON Schema Office Hours (Europe/Americas)","time":"April 1st 2025, 14:00","day":"1","timezone":"UTC","parsedStartDate":"2025-04-01 14:00:00"},{"title":"JSON Schema Open Community Working Meeting","time":"April 21st 2025, 19:00","day":"21","timezone":"UTC","parsedStartDate":"2025-04-21 19:00:00"},{"title":"JSON Schema Office Hours (APAC/Americas)","time":"May 6th 2025, 21:00","day":"6","timezone":"UTC","parsedStartDate":"2025-05-06 21:00:00"}],"fallback":false},"__N_SSG":true},"page":"/","query":{},"buildId":"prM2jgCA24QEAGPj8U6zr","isFallback":false,"gsp":true,"scriptLoader":[]}</script></body></html>

Pages: 1 2 3 4 5 6 7 8 9 10