Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

The $ property name prefix should be unnecessary with a well-structured schema #225

Open
justinfagnani opened this issue Jul 22, 2023 · 10 comments

Comments

@justinfagnani
Copy link

I was looking into this format recently and I came away quite confused why the $ prefix was required everywhere. The rationale pointed to in the format spec (https://design-tokens.github.io/community-group/format/#additional-group-properties) indicates that it's to differentiate between group properties and the tokens within a group.

How this is usually handled in JSON is that the key/value maps are separated from the data structurally - they don't mix in a single object. For groups, all the child tokens would be in a sub-object called children or tokens, and so could never clash with group properties like description.

So a group would look like:

{
  "Group of tokens": {
    "description": "This is an example of a group containing a nested group",
    "tokens": {
      "Subgroup of tokens": {
        "Token 1 name": {
          "value": "#aabbcc"
        },
        "Token 2 name": {
          "value": "#ddeeff"
        }
      }
    }
  }
}

Many, many JSON schemas have both defined properties and open-ended key/value maps and work just fine without prefixing every defined property name in the schema. This spec is the first I've ever seen that does it, and I think it harms the human readability of the documents. It also makes programatic handling of groups more difficult, because to get child tokens you need to filter on a group name prefix instead of just getting the keys of the children property.

@ipaintcode
Copy link

Your observations on the Design Token Schema standard are insightful. Drawing from the W3C Design Tokens standard you provided:

  1. Consistency Across the Specification: One of the key takeaways from the spec is the drive for consistency. The $ prefix consistently differentiates official properties from user-defined token names. This can help improve clarity and comprehension, especially when parsing these tokens.

  2. Collision Prevention: The $ prefix is a neat solution to avoid potential naming clashes. It ensures that as the spec evolves, new properties can be introduced without running into naming conflicts with user-defined token names.

  3. Clear Token vs. Nested Group Differentiation: The spec's use of the $ prefix also simplifies the distinction between tokens and nested groups. This clear demarcation aids in reducing the complexity of parsing logic.

However, I do resonate with your points about the inherent complexity introduced by the $ prefix. Striking the right balance between a robust standard and user-friendliness is challenging. Your feedback highlights some areas where the spec might improve to be more intuitive.

Thanks for sparking this conversation! It's discussions like these that help the community grow and refine its understanding.

@justinfagnani
Copy link
Author

I understand the goals you have for using the prefix, but the prefix really isn't necessary to reach them:

  1. Consistency Across the Specification: If you drop the $ prefix, you'll have the consistency of... not using a prefix. I don't think adding one or not creates consistency. The only inconsistency would be if you used prefixes in some places and not in other. To be clear about what I'm proposing: it's that you don't use prefixes anywhere because they're unnecessary.
  2. Collision Prevention: The standard way to avoid collisions with user-defined keys in JSON schemas is to define a separate object that's entirely user-defined - a general key/value object. As the schema evolves, it evolves within the objects that hold the schema-defined keys. The example I showed above has this quality: there is no object with both schema-defined and user-defined keys.
  3. *Clear Token vs. Nested Group Differentiation: I would argue that the current schema which has some keys belong to the schema and some to the user-defined data is less clear, and having a nested key/value object for nested tokens would be more clear.

I think the style of schema I'm advocating here is by far the more common and plain way to design a JSON schema. Again, I've never seen a schema like this one where all the keys are prefixed and I immediately found it exceedingly odd. I was thinking there had to be an exceptional reason for it, but the reason you give are all not actually problems with the more common JSON schema design.

@PavelLaptev
Copy link
Contributor

PavelLaptev commented Aug 13, 2023

I can agree with @justinfagnani

  1. There shouldn't be any case like a group with the name value. In my view, it's a wrong JSON file. I mean it's also possible if someone will call a group $value.
{
  "value": {
    "description": "This is an example of a group containing a nested group",
    "tokens": {
      "subgroup_of_tokens": {
        "token_1_name": {
          "type": "color",
          "value": "#aabbcc"
        },
        "token_2_name": {
          "type": "color",
          "value": "#ddeeff"
        }
      }
    }
  }
}
  1. even then, there shouldn't be any collisions because each token object contains a type property, so I can check if value.type exists.

It's good to add $ to each declared property name, in theory. But it would be helpful to see why it's needed on real examples.

@ddamato
Copy link

ddamato commented Aug 15, 2023

I'll mention that I appreciate the $ prefix to quickly identify the values visually, as in reading the file manually. I think all of the points above make sense for systems identifying the non-prefixed key. However for folks authoring these files by hand, the $ helps filter what needs to be changed faster while scanning the file with your eyes.

@justinfagnani
Copy link
Author

@ddamato wouldn't this be true of any JSON file format? Why don't they all use prefixes?

@ddamato
Copy link

ddamato commented Aug 15, 2023

Maybe because they aren't often authored by hand? Hard to speak on behalf of others. Like I said, I think your points are otherwise solid.

@TravisSpomer
Copy link

TravisSpomer commented Aug 15, 2023

I've always kind of assumed that "looks like existing popular token JSON formats" was an unspoken goal of this format. This is how Amazon's Style Dictionary and the Tokens Studio plugin for Figma do things (or at least did last time I looked), so that's what we started with. A reserved prefix character $ seems a lot better to me than having a random set of words like value be reserved (and not being able to extend that reserved list in the future), and for quick hand-editing, this format is pretty decent. The alternative of having every other node be tokens would be pretty obnoxious to read and type, but for sure it would make it a lot easier to code for.

(To clarify, that's my response to "why is this file format so weird." I would have personally preferred something like a tokens property myself too, but it feels way too late for that and not in line with the goals.)

@justinfagnani
Copy link
Author

There shouldn't be a set of reserved words anyway, because you shouldn't ever mix user-defined keys with schema-defined keys. And you should only need key/value objects with user-defined keys in specific places, like a group of tokens.

@PavelLaptev
Copy link
Contributor

PavelLaptev commented Aug 15, 2023

I saw a few arguments pro "hand-editing" or "manual" editing/searching.
But in my view, people don't search by the $value word (by a generic property name). If in a JSON I need to change the button-secondary-background value, I'll search button-secondary-background and then I'll look for a value property.

@ddamato
Copy link

ddamato commented Aug 15, 2023

I saw a few arguments pro "hand-editing" or "manual" editing/searching. But in my view, people don't search by the $value word (by a generic property name). If in a JSON I need to change the button-secondary-background value, I'll search button-secondary-background and then I'll look for a value property.

That's true, perhaps I'm thinking in terms of the file being overwhelming in some instances. Where if someone new needed to visit this, I could tell them: you don't need to edit anything except for entries that begin with $. Sure, they'll look for button-secondary-background but that may have additional unstructured data in there. I think the $ does a good job identifying what's important. After all, we're just trying to overload the button-secondary-background: #0000ff assignment with more data.

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

No branches or pull requests

5 participants