VirtusLab / besom

Besom - a Pulumi SDK for Scala. Also, incidentally, a broom made of twigs tied round a stick. Brooms and besoms are used for protection, to ward off evil spirits, and cleansing of ritual spaces.
https://virtuslab.github.io/besom/
Apache License 2.0
113 stars 7 forks source link

Enhance Pulumi StackReference Interface with Typed Outputs #527

Open lbialy opened 4 days ago

lbialy commented 4 days ago

Description:

The current StackReference in Pulumi uses a stringly typed interface that necessitates calling getOutput(key: String) to retrieve an Output[Option[JsValue]] and requireOutput(key: String) to fetch an Output[JsValue]. Both methods demand manual type conversion from JsValue, which is error-prone.

Issue:

Develop a type-safe API that allows direct deserialization into predefined types, maintaining backward compatibility with the existing API.

Proposed Solution:

Let's assume this case class as representation of outputs of a referred stack:

case class Platform(kubeconfig: String, nodes: List[String])

Simple variant:

Implement a semiauto derivation pattern for the StackReferenceOutputs typeclass to manage serialization while allowing for customizations. Add a method to StackReference that provides typed outputs directly:

def outputs[A: StackReferenceOutputs]: Output[A]

More involved variant:

Introduce a new API for StackReference that supports typed outputs through a generic type parameter. Define a Platform case class for expected outputs like kubeconfig and nodes.

case class Platform(kubeconfig: String, nodes: List[String])

Adapt the StackReferenceFactory to use type classes for deserialization.

trait StackReferenceOutputs[A]:
  def decode(ref: StackReference): Output[TypedStackReference[A]]

trait StackReferenceFactory:
  def apply[T](using Context, StackReferenceOutputs[T])(
    name: NonEmptyString,
    args: Input.Optional[StackReferenceArgs] = None,
    opts: StackReferenceResourceOptions = StackReferenceResourceOptions()
  ): Output[TypedStackReference[T]]