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

No way to access default, minimum, maximum on Schemas that are integer type: #1651

Open
sammy-da opened this issue Dec 8, 2022 · 4 comments

Comments

@sammy-da
Copy link

sammy-da commented Dec 8, 2022

{
  "components": {
    "schemas": {
      "TokenExpirationSeconds": {
        "type": "integer",
        "description": "The number of seconds until the generated token expires.",
        "format": "int32",
        "default": 3600,
        "example": 3600,
        "minimum": 15,
        "maximum": 86400
      },
      "PersonalAccessToken": {
        "type": "object",
        "properties": {
          "expires_in": {
            "$ref": "#/compnenets/schemas/TokenExpirationSeconds"
          }
        }
      }
    }
  }
}

All i get in the generated code is

case class PersonalAccessToken(expiresIn: Option[Int] = Option(3600))

I'd ideally be able to access these constants in some way. Only the default is present in the generated code at all.

@blast-hardcheese
Copy link
Member

Hello, please pardon the delay in response,

What's the use case for accessing these values? There's a guardrail module that does validation using the refined library in Scala, would that be sufficient?

@sammy-da
Copy link
Author

What's the use case for accessing these values?

I just want to be able to access these constant for business logic purposes. Right now I'm having to re-define them, and so the constants defined in code could get out of sync with what's defined in the api spec.

There's a guardrail module that does validation using the refined library in Scala, would that be sufficient?

you mean a request that, say, violates the minimum or maximum will get rejected? that's good, but one might still need access to them still. (e.g. default)

@blast-hardcheese
Copy link
Member

Got it. I don't have a great way to handle that at the moment, I really don't like how the default arguments are expressed today but I also don't really like the idea of defining a whole new constant object and exposing that to the caller.

Do you have an idea of what this would feel like to use? What would be the most useful and the least breaking change to the user?

@sammy-da
Copy link
Author

sammy-da commented Feb 7, 2023

If we take this generated schema for example:

package com.damlhub.openapi.definitions
import cats.syntax.either._
import io.circe.syntax._
import cats.instances.all._
import _root_.com.damlhub.openapi.Implicits._
case class Parties(result: _root_.scala.Vector[PartyDetails] = Vector.empty, status: Int = 200)
object Parties {
  implicit val encodeParties: _root_.io.circe.Encoder.AsObject[Parties] = {
    val readOnlyKeys = _root_.scala.Predef.Set[_root_.scala.Predef.String]()
    _root_.io.circe.Encoder.AsObject.instance[Parties](a => _root_.io.circe.JsonObject.fromIterable(_root_.scala.Vector(("result", a.result.asJson), ("status", a.status.asJson)))).mapJsonObject(_.filterKeys(key => !(readOnlyKeys contains key)))
  }
  implicit val decodeParties: _root_.io.circe.Decoder[Parties] = new _root_.io.circe.Decoder[Parties] { final def apply(c: _root_.io.circe.HCursor): _root_.io.circe.Decoder.Result[Parties] = for (v0 <- c.downField("result").as[_root_.scala.Vector[PartyDetails]]; v1 <- c.downField("status").as[Int]) yield Parties(v0, v1) }
}

status: Int = 200 could be accessible to users from their own code like this:
Parties.Defaults.status
(and perhaps also the generated case class Parties could reference that same constant as well instead of inlining, while we're at it)

So to do that i think we can just nest another object inside object Parties:

object Parties {
   ....
 
   object Defaults {
     val status: Int = 200
  }
}

I don't think something like this would be a breaking change?
This does not need to be exposed as a parameter or anything

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

No branches or pull requests

2 participants