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

More support for props and/or extensibility #537

Open
simonpetty opened this issue Jun 27, 2023 · 0 comments
Open

More support for props and/or extensibility #537

simonpetty opened this issue Jun 27, 2023 · 0 comments

Comments

@simonpetty
Copy link

simonpetty commented Jun 27, 2023

Hi

I've been looking into making use of additional JSON properties to document extra validation that Avro doesn't support out of the box. I was particularly inspired to look into this by AsyncAPI.

Confluent recently introduced a set of features in this space, but we aren't using Confluent, and these rules are defined alongside rather than within the schema.

The idea is to eventually build up more of a data contract between consumers and producers - but it's early stages, and we've hit a roadblock trying to do this with Vulcan.

Adding props is relatively easy against records or fields in a record, as we can use these methods:

final def record[A](
    name: String,
    namespace: String,
    doc: Option[String] = None,
    aliases: Seq[String] = Seq.empty,
    props: Props = Props.empty
)

and

sealed abstract class FieldBuilder[A] {
    def apply[B](
      name: String,
      access: A => B,
      doc: Option[String] = None,
      default: Option[B] = None,
      order: Option[Schema.Field.Order] = None,
      aliases: Seq[String] = Seq.empty,
      props: Props = Props.empty
    )(implicit codec: Codec[B]): FreeApplicative[Field[A, *], B]
}

However...

Quite often we use value classes that wrap primitive types, and we'd like to be able to extend the schema for primitive types to add these props in one place, rather than repeated against each record they are a part of.

Also, it's not possible for us to retrieve the props from the writer schema, which would be useful to ensure the consumer/producer are aligned. Originally I thought we could use imap or imapError, but this only allows us to translate the encoded values, without passing through the schema.

Ultimately, I think the only way of doing what we want is to use this deprecated method:

instance[AvroType0, A](
    schema: Either[AvroError, Schema],
    encode: A => Either[AvroError, AvroType0],
    decode: (Any, Schema) => Either[AvroError, A]
)

I can see a similar issue was raised here: #504 which they resolved by adding something to the library.

I had a very brief look into scodec and their API isn't similarly sealed, so I'd be curious to understand more of the rational, or if you would be open to changing this? Maybe the only solution here is to try and build something into the library, or find an alternative?

Thanks

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

No branches or pull requests

1 participant