softwaremill / tapir

Rapid development of self-documenting APIs
https://tapir.softwaremill.com
Apache License 2.0
1.36k stars 411 forks source link

Introduce other common Validator #1420

Closed geirolz closed 2 years ago

geirolz commented 3 years ago

What do you think to add some new generic Validator? I have in mind these for now:

  //foldable - from cats
  def nonEmpty[F[_]: Foldable, T]: Validator[F[T]]
  def fixedSize[F[_]: Foldable, T](n: Int): Validator[F[T]]

  //strings
  def nonEmptyString[T <: String]: Validator[T]
  def fixedLength[T <: String](n: Int): Validator[T]

  //numbers
  def positive[N](implicit N: Numeric[N]): Validator[N]
  def negative[N](implicit N: Numeric[N]): Validator[N]
  def inRange[N: Numeric](min: N, max: N, minExclusive: Boolean = false, maxExclusive: Boolean = false): Validator[N]

Reasons:

Foldable

With Foldable instead of Iterable we can also support cats collections like NonEmptyList, etc... If we don't want to use Cats obliviously we can use Iterable but then creating the same validators with Foldable in the cats module.

adamw commented 3 years ago

Why not :) Some of these for sure would make sense. Thanks for the idea!

We can't depend on cats in core so this would have to be split among the two modules as you've written.

geirolz commented 3 years ago

Great if you want I can work on it, I've already have something done in my app.

Just one question, using custom validators there won't be any message on the open API doc. there is a way to customize it?

adamw commented 3 years ago

Sure, contributions welcome! :)

As for messages, you can return custom validation error messages when using Validator.Custom. Here, though, we'll probably end up with customised primitive validators which would need to return custom messages ... that's not possible currently, but if you do have some design propositions, go ahead :) All the code is in Validator

geirolz commented 3 years ago

As "message on the open API doc" I was meaning something like minimum=0 when we set a Min(0) validator for example. OpenAPI can have custom messages there ?

adamw commented 3 years ago

@geirolz yeah, this should work now. Are you not seeing this when using validators? Here's the section that generates these messages: https://github.com/softwaremill/tapir/blob/master/core/src/main/scala/sttp/tapir/server/interceptor/decodefailure/DecodeFailureHandler.scala#L176-L199

geirolz commented 3 years ago

@adamw these are the messages in case of error right? I was meaning the information message in the Open API documentation HTML page, there is a way to customize them?

Anyway, what do you think to take the validator and the message for the error case closer?

I'll open a draft PR in the next days for a design proposal. I still have some problems but in this way we can discuss the design

adamw commented 3 years ago

Ah ... I think these messages are generated by the ui, in the openapi docs you only have the metadata, e.g. minimum: 0, without any error messages. So if there's a way to customise them, it's probably in Swagger? See https://swagger.io/specification/#schema-object

adamw commented 3 years ago

The code generating this in tapir is in TSchemaToASchema

geirolz commented 3 years ago

@adamw here just a draft https://github.com/geirolz/tapir/tree/refactoring-validator

Core is fine, there are some modules with red tests to fix, I'll if you are interested in this design.

adamw commented 3 years ago

@geirolz I see you've got a bigger refactor there :) The direction looks good, maybe you can open a PR so that I could comment on individual parts? Should be easier this way

geirolz commented 3 years ago

For sure! Sorry I was in a hurry yesterday

Here is the draft PR: https://github.com/softwaremill/tapir/pull/1467