Skip to content

Conversation

filipgutica
Copy link
Contributor

@filipgutica filipgutica commented Aug 16, 2025

Summary

Just trying things out.

BREAKING CHANGE: new dashboard schema using zod

Why Zod over json-schema-to-ts + ajv

Runtime validation & parsing built in

  • safeParse, coercion (z.coerce.number()), defaults, transforms, sync/async refinements—no extra library.

Single source of truth

  • Define once in Zod → get both runtime behavior and static types via z.infer. With JSON Schema you generate types separately and can drift from what actually validates.

Composability

  • .extend, .merge, .pick/.omit, .partial()/deepPartial, discriminated unions, branded types—ergonomic for building large schemas.

Better error handling out of the box

  • Structured errors with paths, custom messages etc..

Transforms & preprocessing

  • Parse-time shaping is first-class (normalize input, compute derived fields) without extra steps.

Great DX

  • Autocomplete on schema builders, smaller mental model than JSON Schema’s spec.

Example of a zod error for a dashboard config with an invalid filter field. Using z.treeifyError(error).

{
  "errors": [],
  "properties": {
    "filters": {
      "errors": [],
      "items": [
        {
          "errors": [
            "Unrecognized key: \"value\"",
            "Unrecognized key: \"value\"",
            "Unrecognized key: \"value\""
          ],
          "properties": {
            "field": {
              "errors": [
                "Invalid option: expected one of \"api\"|\"api_product\"|\"api_product_version\"|\"control_plane\"|\"control_plane_group\"|\"data_plane_node\"|\"gateway_service\"|\"portal\"|\"route\"|\"status_code\"|\"status_code_grouped\"|\"application\"|\"consumer\"|\"country_code\"|\"iso_code\"|\"upstream_status_code\"|\"upstream_status_code_grouped\"|\"response_source\"|\"data_plane_node_version\"|\"realm\"",
                "Invalid option: expected one of \"api\"|\"api_product\"|\"api_product_version\"|\"control_plane\"|\"control_plane_group\"|\"data_plane_node\"|\"gateway_service\"|\"portal\"|\"route\"|\"status_code\"|\"status_code_grouped\"|\"application\"|\"consumer\"|\"country_code\"|\"iso_code\"|\"upstream_status_code\"|\"upstream_status_code_grouped\"|\"response_source\"|\"data_plane_node_version\"|\"realm\"",
                "Invalid option: expected one of \"api\"|\"api_product\"|\"api_product_version\"|\"control_plane\"|\"control_plane_group\"|\"data_plane_node\"|\"gateway_service\"|\"portal\"|\"route\"|\"status_code\"|\"status_code_grouped\"",
                "Invalid option: expected one of \"api\"|\"api_product\"|\"api_product_version\"|\"control_plane\"|\"control_plane_group\"|\"data_plane_node\"|\"gateway_service\"|\"portal\"|\"route\"|\"status_code\"|\"status_code_grouped\"",
                "Invalid option: expected one of \"control_plane\"|\"control_plane_group\"|\"gateway_service\"|\"consumer\"|\"application\"|\"route\"|\"ai_provider\"|\"ai_response_model\"|\"ai_request_model\"|\"llm_cache_status\"|\"llm_embeddings_provider\"|\"llm_embeddings_model\"|\"realm\"|\"status_code\"|\"status_code_grouped\"|\"ai_plugin\"",
                "Invalid option: expected one of \"control_plane\"|\"control_plane_group\"|\"gateway_service\"|\"consumer\"|\"application\"|\"route\"|\"ai_provider\"|\"ai_response_model\"|\"ai_request_model\"|\"llm_cache_status\"|\"llm_embeddings_provider\"|\"llm_embeddings_model\"|\"realm\"|\"status_code\"|\"status_code_grouped\"|\"ai_plugin\""
              ]
            },
            "operator": {
              "errors": [
                "Invalid option: expected one of \"empty\"|\"not_empty\"",
                "Invalid option: expected one of \"empty\"|\"not_empty\"",
                "Invalid option: expected one of \"empty\"|\"not_empty\""
              ]
            }
          }
        }
      ]
    },
    "tiles": {
      "errors": [],
      "items": [
        {
          "errors": [],
          "properties": {
            "definition": {
              "errors": [],
              "properties": {
                "query": {
                  "errors": [],
                  "properties": {
                    "datasource": {
                      "errors": [
                        "Invalid input: expected \"basic\"",
                        "Invalid input: expected \"llm_usage\""
                      ]
                    }
                  }
                }
              }
            }
          }
        }
      ]
    }
  }
}

@filipgutica filipgutica requested review from kongponents-bot and a team as code owners August 16, 2025 14:55
@filipgutica filipgutica force-pushed the feat/dashboard-schema-using-zod branch 8 times, most recently from 32c2221 to 5bc4acf Compare August 17, 2025 22:29
@adamdehaven
Copy link
Member

Do you need full Zod or could you get by with Zod mini?
https://zod.dev/v4?id=introducing-zod-mini

@filipgutica filipgutica force-pushed the feat/dashboard-schema-using-zod branch from 5bc4acf to d45305a Compare August 18, 2025 15:20
@filipgutica
Copy link
Contributor Author

Do you need full Zod or could you get by with Zod mini? https://zod.dev/v4?id=introducing-zod-mini

Can try zod mini.

I'm just trying out zod to see how it works with our schema

@filipgutica filipgutica force-pushed the feat/dashboard-schema-using-zod branch from d45305a to f88f58b Compare August 19, 2025 17:45
Copy link
Contributor

@adorack adorack left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(Moving discussion to Slack.)

@filipgutica filipgutica force-pushed the feat/dashboard-schema-using-zod branch 2 times, most recently from 35af651 to 6854ce0 Compare August 19, 2025 21:06
BREAKING CHANGE: new dashboard schema using zod
@filipgutica filipgutica force-pushed the feat/dashboard-schema-using-zod branch from 6854ce0 to 8661c5f Compare August 20, 2025 05:23
@kongponents-bot
Copy link
Collaborator

Preview components from this PR in consuming application

In consuming application project install preview versions of shared packages generated by this PR:

@kong-ui-public/analytics-utilities@pr-2346
@kong-ui-public/analytics-chart@pr-2346
@kong-ui-public/analytics-config-store@pr-2346
@kong-ui-public/analytics-geo-map@pr-2346
@kong-ui-public/portal-analytics-bridge@pr-2346
@kong-ui-public/analytics-metric-provider@pr-2346
@kong-ui-public/dashboard-renderer@pr-2346

@Justineo
Copy link
Member

We’re also considering introducing Zod for runtime schema validation in our Datakit flow editor. Should we add add it as a peer + dev dependency and mark it as external? @adamdehaven WDYT?

@adamdehaven
Copy link
Member

We’re also considering introducing Zod for runtime schema validation in our Datakit flow editor. Should we add add it as a peer + dev dependency and mark it as external? @adamdehaven WDYT?

If there aren't versioning issues, sure.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants