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]

Reply via email to