fermyon / spin

Spin is the open source developer tool for building and running serverless applications powered by WebAssembly.
https://developer.fermyon.com/spin
Apache License 2.0
5.03k stars 242 forks source link

Enable mustache-inspired string templates for `key_value_stores` and others #2577

Open ThorstenHans opened 2 weeks ago

ThorstenHans commented 2 weeks ago

I'm building a Spin App that consists of multiple components:

# ...

[component.a]
source = "a/target/wasm32-wasi/release/a.wasm"
key_value_stores = ["data"]

[component.b]
source = "b/target/wasm32-wasi/release/b.wasm"
key_value_stores = ["data"]

# ...

Instead of providing the magic string (name of the desired key-value store) 4 times (twice as part of key_value_stores and once per component), I would want to use mustache-inspired string templates as illustrated here:

#...

[variables]
store = { default = "data" }

[component.a]
source = "a/target/wasm32-wasi/release/a.wasm"
key_value_stores = ["{{ store }}"]

[component.a.variables]
store = "{{ store }}"

[component.b]
source = "b/target/wasm32-wasi/release/b.wasm"
key_value_stores = ["{{ store }}"]

[component.b.variables]
store = "{{ store }}"

# ...
lann commented 2 weeks ago

Labels are already a sort of variable in the context of a spin manifest. Could you share more about what you're trying to do here?

ThorstenHans commented 2 weeks ago

What do you mean by labels?

What I'm trying to do here:

Comparing both variants, no. 1 looks cleaner IMO:

Variant 1

#...

[variables]
store = { default = "data" }

[component.a]
source = "a/target/wasm32-wasi/release/a.wasm"
key_value_stores = ["{{ store }}"]

[component.a.variables]
store = "{{ store }}"

[component.b]
source = "b/target/wasm32-wasi/release/b.wasm"
key_value_stores = ["{{ store }}"]

[component.b.variables]
store = "{{ store }}"

# ...

Variant 2


#...

[component.a]
source = "a/target/wasm32-wasi/release/a.wasm"
key_value_stores = ["data"]

[component.a.variables]
store = "data"

[component.b]
source = "b/target/wasm32-wasi/release/b.wasm"
key_value_stores = ["data"]

[component.b.variables]
store = "data"

# ...
lann commented 2 weeks ago

Variant 3

#...

[component.a]
source = "a/target/wasm32-wasi/release/a.wasm"
key_value_stores = ["data"]

[component.b]
source = "b/target/wasm32-wasi/release/b.wasm"
key_value_stores = ["data"]

# ...

It looks like we aren't using the term "label" consistently in documentation, but it is the term for data in this example at least internally and in spin-cloud.

This label is already a "variable" in the sense that it is a arbitrary user-defined identifier that is shared between the manifest and code.

Actually, I think we want to actively avoid the pattern of making these labels dynamic; the long term goal is to use these labels as component model import names, which need to be static.

lann commented 2 weeks ago

Prevent myself from having the actual name (magic string) of the key-value store in multiple places

You still have a magic string: "store"; it is just adding an extra layer of indirection.

ThorstenHans commented 2 weeks ago

Prevent myself from having the actual name (magic string) of the key-value store in multiple places

You still have a magic string: "store"; it is just adding an extra layer of indirection.

Yes but I need it only once 😄 which is actually the point I mentioned

rylev commented 2 weeks ago

I'm also not so sure I understand what this feature would improve.

In the example above with a store labeled as "data" and a variable named "store" that points to that label, the amount of typing/repetition is the same whether you use the variable or not. I suppose if the store label were to change, you would only need to update it in one place, but this doesn't seem like something that will happen often, so I'm not sure the complexity of supporting a templating system is worth it.