openwallet-foundation / credo-ts

Typescript framework for building decentralized identity and verifiable credential solutions
https://credo.js.org
Apache License 2.0
275 stars 202 forks source link

Migrating away from `class-transformer` and `class-validator` #1489

Open berendsliedrecht opened 1 year ago

berendsliedrecht commented 1 year ago

Currently, class-transformer and class-validator are being used for transforming between classes and JSON and validation respectively. Both of these packages are maintained by the same party as a side project related issue. class-transformer has not seen an update within the last 2 years and class-validator has not seen an update within the last 6 months. Now, this does not mean that these packages are full of bugs, but the combination makes it a less than desirable dependency to have in AFJ. These packages are also used, not a 100% sure if it is required, by the custom modules that will be created for the core repository and by consumers. A combination of these factors, and the fact that once before a deadline they pushed a breaking change to a patch version..., makes me want to reconsider the validation / transformation libraries we use.

My initial proposal is to use zod. From the description, Zod is a "TypeScript-first schema validation with static type inference". Zod allows us to validate incoming JSON objects in a very intuitive and descriptive manner and it also allows us to transform these JSON instances into classes. The pattern for this is different from class-transformer and class-validator though. We need to create a schema which would contain the validation for the object. These schemes would then be, for us, tightly coupled to a class. Making this coupling might require some design work but I think it can be a way better experience for the creators of custom modules and for us as maintainers / consumers.

If there are other validation / transformation libraries it would definitely be good to list them here and consider those as well.

If I have some time in the near future I will try to create a validation and transformation abstraction and use it inside a module.

TimoGlastra commented 1 year ago

Duplicate of https://github.com/hyperledger/aries-framework-javascript/issues/749.

I'll close that one.

TimoGlastra commented 1 year ago

From issue #749 that @TimoGlastra opened:

Although class-transformer and class-validator do a lot of heavy lifting in terms of (de)seralization and validation the libraries are largely unmaintained and have issues when dealing with complexer types. This issue is to create a list of alternative to these libraries so we can make a decicision whether it is worth it to change the library to something else.

Cons:

  • Libraries are mostly unmaintained
  • We need an if (options) in the constructor of each class
  • A lot of times there's no need for a class instance, an interface that could be validated would be sufficient
  • ValidateNested doesn't work nicely, especially if you have arrays of mixed types with primitive types
  • The created schemas don't always reflect the correct type which results in a half-typed rest api

Options: (https://www.typescriptneedstypes.com/)

TimoGlastra commented 1 year ago

I 100% agree with this change! :)

My initial proposal is to use zod

I've seen ArkType, which is more aligned with TS types, and also mentions it is faster that Zod. https://arktype.io/

Just trhowing it out here, I think we should pick a soution that will be well-maintained for the long run

TimoGlastra commented 1 year ago

Of course there's also the Deepkit types library, but I'm not too keen on having a custom typescript compiler plugin (makes extension harder) and it's maintained by a single person. https://deepkit.io/library/type