Move properties on the WebformElement interface

Created on 5 February 2025, about 1 month ago

Problem/Motivation

The webform element types we are exposing introduce many duplicated fields in the schema. We can alleviate this by moving them in the WebformElement interface.

Steps to reproduce

Currently the generated schema duplicates the following common properties for all webform elements:

  • description
  • key
  • multiple
  • type
  • required
  • title

Proposed resolution

Move the common properties to the shared WebformElement interface.

✨ Feature request
Status

Active

Version

2.0

Component

Code

Created by

🇧🇬Bulgaria pfrenssen Sofia

Live updates comments and jobs are added and updated live.
Sign in to follow issues

Merge Requests

Comments & Activities

  • Issue created by @pfrenssen
  • 🇧🇬Bulgaria pfrenssen Sofia

    Starting on this.

  • 🇧🇬Bulgaria pfrenssen Sofia

    The GraphQL specification actually required fields defined on an interface to be duplicated across all the types that implement the interface.

    I mistakenly thought we could generate a schema like this:

    interface WebformElement {
      key: String!
      title: String
      description: String
      multiple: Int
      required: WebformRequiredElement
      type: String!
    }
    
    interface WebformElementMultipleValuesBase {
      multipleValues: WebformElementMultipleValues
    }
    
    type WebformElementAddress implements WebformElement & WebformElementMultipleValuesBase {
    }
    
    type WebformElementCaptcha implements WebformElement {
    }
    

    But the GraphQL interface specification actually _requires_ the fields to be duplicated on the implementors, with the motivation that this makes it easier to declare covariant types.

    So it quickly becomes bloated like this:

    interface WebformElement {
      key: String!
      title: String
      description: String
      multiple: Int
      required: WebformRequiredElement
      type: String!
    }
    
    interface WebformElementMultipleValuesBase {
      multipleValues: WebformElementMultipleValues
    }
    
    type WebformElementAddress implements WebformElement & WebformElementMultipleValuesBase {
      key: String!
      title: String
      description: String
      multiple: Int
      required: WebformRequiredElement
      type: String!
      multipleValues: WebformElementMultipleValues
    }
    
    type WebformElementCaptcha implements WebformElement {
      key: String!
      title: String
      description: String
      multiple: Int
      required: WebformRequiredElement
      type: String!
    }
    

    Since we are still building out the schema it is easy to see how this can bloat the schema exponentially.

    A good solution to limit this could be to define only a single element on an interface, for example:

    interface WebformElement {
      metadata: WebformElementMetadata!
    }
    
    interface WebformElementMultipleValuesBase {
      multipleValues: WebformElementMultipleValues
    }
    
    type WebformElementMetadata {
      key: String!
      title: String
      description: String
      multiple: Int
      required: WebformRequiredElement
      type: String!
    }
    
    type WebformElementAddress implements WebformElement & WebformElementMultipleValuesBase {
      metadata: WebformElementMetadata!
      multipleValues: WebformElementMultipleValues
    }
    
    type WebformElementCaptcha implements WebformElement {
      metadata: WebformElementMetadata!
      type: String!
    }
    

    Which is incidentally how it was in version 2.x-alpha1, but this got flattened out as part of the change request ✨ Remove Metadata subfields Fixed .

    It is probably a good idea to revisit this, and to reconsider adding back the metadata field to limit schema bloat.

    We should also take other measures to limit the size of the schema. For example we should not expose all field types by default.

  • 🇧🇬Bulgaria pfrenssen Sofia
  • 🇧🇬Bulgaria pfrenssen Sofia

    Unassigning, let's first figure out the best way to approach this.

  • 🇨🇭Switzerland dulnan

    I would also appreciate to have a reduced schema, having a field for "common" element fields would indeed reduce the schema significantly and make it easier to add new custom fields for all elements. Possible frontend implementations might also "work" in this way: The common fields (such as label, description, help, states, required, etc.) are usually rendered the same (as label tags, help texts below the actual input), no matter what the element type is. And since these are available on all webform element plugins, it makes sense to group them into a separate type.

  • 🇧🇬Bulgaria pfrenssen Sofia

    Thanks for the feedback @dulnan! I will implement this.

  • 🇧🇬Bulgaria pfrenssen Sofia
  • Pipeline finished with Skipped
    about 1 month ago
    #421198
  • 🇧🇬Bulgaria pfrenssen Sofia

    Thanks!

  • Automatically closed - issue fixed for 2 weeks with no activity.

Production build 0.71.5 2024