mulesoft-labs / data-weave-rfc

RFC for the data weave language
13 stars 5 forks source link

Typed Metadata #57

Open machaval opened 1 year ago

machaval commented 1 year ago

Typed Metadata

Pre-read: https://github.com/mulesoft-labs/data-weave-rfc/issues/40 .

We have already talk about what metadata is, and all it uses. One problem that I still see is that though we now have a way to apply metadata without the need of doing as with a type, using the new <~ operator. We still don't have nice way to type checkit.

For example in order of CData to be applied we have to set the metadata {cdata: true}, and here we have two problems one that users need to remember the name of the keys and its value type, and second that if you did some miss spelling like {cData: true} it doesn't work, and you don't get any error or hint why not.

Solutions

Use functions to apply metadata

One option would be let's create functions that allows us to apply metadata with typed values. For example this would be

%dw 2.0
output application/xml
fun cdata<T>(a: T, cdata: Boolean) : T = do {
    a <~ {cdata: cdata}
}
---
root: "DW Rocks" cdata true

Pros

  1. Doesn't require anything new from the language
  2. Fixes both issues as it will validate the argument and the tooling will validate the parameters

Drawback Open Questions

  1. How is this going to work with type definitions
  2. Is function call the proper tool to apply metadata that is something that is not really changing the value?. Does it contaminate the script?
  3. Should we start investigating to handle types as values so we can apply functions to the types to attach metadata.

Use annotations

Use annotation to attach metadata

@Metadata()
annotation CData(cdata: Boolean = true);
---
root: @CData() "DWRocks"

With this approach we can let the engine that all the fields of the Annotation should be attached to the value as metadata values.

We can take this approach and take it to type expressions


@Metadata()
annotation ValueProvider(provider: () -> Array<String>);

type Test = {
    a: @ValueProvider(provider = myValueProvider) String
}

fun myValueProvider() = ["Hello", "ByeBye"]

Pros

  1. As they are annotations they doesn't look like it polutes the scripting looks more like a second class thing
  2. Tooling and verification are still possible

Cons

  1. Yet another way to apply metedadata