0

I'm using tapir to define a series of endpoints, as follows:

    def thingModifyState[M: Encoder: Decoder: Schema] =
      endpoint.put
      .name(s"Modify state of a $name Thing")
      .description("Apply a modification object to a Thing")
      .in("state")
      .in(this.name.description("Type of Thing"))
      .in(
        path[String Refined And[MatchesRegex["^[a-z0-9_]+$"], MaxSize[64]]]
          .description("Name of Thing")
          .name("thing")
      )
      .in(jsonBody[M].description("Object describing modification"))
      .errorOut(
        statusCode
          .description(StatusCode(404), "Thing does not exist")
      )
      .tag(name)

thingModifyState is then used to define multiple endpoints:

blueRoutes.thingModifyState[things.models.blue.StateChange]
redRoutes.thingModifyState[things.models.red.StateChange]

The blue.StateChange object is defined like this:

object StateChange {
  implicit val config: Configuration = Configuration.default.withSnakeCaseMemberNames
  implicit val thingStateEncoder: Encoder[StateChange] = deriveEncoder(derivation.renaming.snakeCase)
  implicit val thingStateDecoder: Decoder[StateChange] = deriveDecoder(derivation.renaming.snakeCase)
  implicit val thingStateSchema: Schema[StateChange] = Schema.derived
}

/**
  * Specifies a change to the Thing's state
  *
  * @param counterChange negative or positive increment of the counter
  * @param resetTimestamp new timestamp value
  */
case class StateChange(counterChange: Long, resetTimestamp: Long)

When docs are generated (using redoc), the 'request body schema' section looks like this:

screenshot of redoc docs for 'request body schema'

The overall description ("Object describing modification") of the jsonBody is visible in the docs, but I'd like to include descriptions of the jsonBody fields (counter_change / reset_timestamp) as well as their types.

I wouldn't expect the scaladoc definitions from StateChange to get picked up, but right now I cannot figure out what to do to get descriptions of the jsonBody fields into the output documentation. Do I need to derive the Schema manually, and include the descriptions somehow?

EDIT: I suspect this: https://github.com/softwaremill/tapir/issues/247 of being relevant, but the documentation link at the end of the issue (https://tapir-scala.readthedocs.io/en/latest/endpoint/customtypes.html#customising-derived-schemas) links to an anchor that is no longer there. I haven't yet found its new location!

EDIT2: Ah, maybe the link is now here: https://tapir.softwaremill.com/en/latest/endpoint/schemas.html#customising-derived-schemas. It mentions using @description annotations, but is missing explanation/examples of where those annotations go for derived schemas.

EDIT3: I was hoping for something like this:

import sttp.tapir.EndpointIO.annotations.description

case class StateChange(
  @description("negative or positive increment of the counter") counterChange: Long, 
  @description("new timestamp value") resetTimestamp: Long
)

... but it doesn't help.

user3468054
  • 610
  • 4
  • 11

1 Answers1

0

Following the documentation here: https://tapir.softwaremill.com/en/latest/endpoint/schemas.html#customising-derived-schemas, define the case class like this:

import sttp.tapir.Schema.annotations._

case class StateChange(
                        @description("negative or positive increment of the counter") counterChange: Long,
                        @description("new value for reset timestamp") resetTimestamp: Long
                      )

Note that you need to import the annotation from sttp.tapir.Schema.annotations, not from the location referred to in my question.

user3468054
  • 610
  • 4
  • 11