michael-s-molina commented on PR #38376:
URL: https://github.com/apache/superset/pull/38376#issuecomment-4039062759
Thanks @betodealmeida @villebro for your comments. I did a session with AI
discussing the existing patterns and providing your comments as input and
here's the output:
## The Core Question
The tension is between **developer experience** (DX) and **flexibility**.
The three reviewers in the PR each represent a different priority. This
document maps out what each architectural option actually means.
---
## Why Using Existing `views` Is the Wrong Fit
The existing `views` contribution type provides a React element at a named
location, and Superset renders it without further involvement. A configuration
form is fundamentally different — not because views can't have internal state
(they can), but because **Superset needs to coordinate the state** in a form:
- It has **input**: the current saved configuration that Superset must inject
- It has **output**: the submitted values that Superset must collect and
persist
- It has a **lifecycle**: Superset owns the Save/Cancel buttons and must be
able to trigger submission and receive the result
- It has **size constraints**: it renders inside a modal Superset controls
If you use `views`, extension developers would need to invent their own
conventions for all of this: "how do I get the current values into my view?",
"how does the modal's Save button trigger my form's submit?", "how do I
communicate validation errors back to the modal footer?". Every semantic layer
extension would solve this differently — a Redux action here, a ref callback
there — which is exactly the kind of fragmentation that contribution types are
supposed to prevent.
**The `views` contract is: here's a slot, fill it with a React element,
Superset won't touch your state. The forms contract needs to be: here's data
owned by Superset, transform it and hand it back.**
---
## The Three Real Options
### Option 1: Keep JSON Forms as the Only Path (Status Quo)
The Pydantic schema IS the UI. Extension devs only write Python.
**Strengths:**
- Unbeatable DX for the common case — one Pydantic class drives the API
schema, the DB schema, validation, and the form
- Single source of truth: add a field to Pydantic, everything updates
- Zero frontend knowledge required
**Weaknesses:**
- No escape hatch for complex UIs (multi-step wizards, OAuth flows, OAuth
popups, connection test buttons with live feedback)
- JSON Forms has limits: complex conditional logic, custom interactive
controls, and pixel-perfect layouts are painful to express in JSON Schema
### Option 2: Replace with a `views` + JSON Forms Optional Pattern
Extension devs register a view for their semantic layer config. They can use
JSON Forms internally or not.
**Strengths:**
- Maximum flexibility
- Reuses existing infrastructure
**Weaknesses:**
- Complete loss of the DX advantage (now every extension must know React)
- No standard form contract means inconsistent UX across semantic layers
- Superset loses ability to control the modal shell, validation feedback,
loading states
### Option 3: Hybrid — JSON Forms as Default, `forms` Contribution as
Override
This is the strongest option. The key insight: **JSON Forms IS the 95% case
implementation, but it shouldn't be the only path.**
---
## Recommended Architecture: Two-Layer Hybrid
**Layer 1 — The default: Pydantic + JSON Forms pipeline stays exactly as
is.**
This covers the vast majority of semantic layer extensions. The developer
defines a Pydantic model and gets a complete UI for free. The progressive
schema enrichment (connecting to Snowflake to populate database dropdowns
dynamically) is a genuinely elegant feature worth preserving.
**Layer 2 — Optional override via a new `forms` contribution type.**
When an extension needs a complex UI, it can declare a frontend form
component ID on the `SemanticLayer` class and register it as a `forms`
contribution:
```python
# Python side: declare the override
class MySemanticLayer(SemanticLayer[MyConfig, MySemanticView]):
frontend_form_id = "my-org.my-extension.snowflake-config"
# get_configuration_schema() still used for API validation
# but not for rendering the form
```
```typescript
// Frontend side: register the custom form body
import { forms } from '@apache-superset/core';
forms.registerForm(
'my-org.my-extension.snowflake-config',
SnowflakeConfigForm,
);
// The typed contract (Superset owns the modal shell)
interface FormBodyProps {
values: Record<string, unknown>;
onChange: (values: Record<string, unknown>) => void;
isSubmitting: boolean;
schema?: Record<string, unknown>; // available if they want to use JSON
Forms internally
}
```
**Superset still owns the modal frame** (title, Save/Cancel buttons, loading
overlay, error banner). The custom component only provides the body — exactly
like the explore control panel does today. This ensures consistent UX across
all semantic layer forms regardless of who built them.
---
## Why a New `forms` Type Over Extending `views`
| | `views` | `forms` |
|---|---|---|
| Data contract | None — just a slot | Typed `values` in, `onChange` out |
| Modal shell ownership | Extension | Superset |
| Lifecycle (submit/cancel) | Convention | Explicit interface |
| Validation feedback | Ad-hoc | Standard via modal |
| Use cases | Panels, sidebars | Configuration dialogs |
The `forms` type is also broadly reusable beyond semantic layers — database
connection forms, alert config dialogs, and other modal-driven configurations
would benefit from the same pattern.
---
@betodealmeida @villebro Based on this analysis and your feedback, I propose
that we go with the hybrid approach but DO NOT introduce the new `forms`
contribution yet. Given that the automatic UI generation covers the majority of
use cases, I think it would be interesting to dive deeper into the Explore use
cases related to forms before defining the new `forms` contribution type.
Thoughts?
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]