I am generating the Scala code shown below using the openapi-generator.
import examples.openverse.model.{InlineObject, OAuth2RegistrationSuccessful}
import examples.openverse.core.JsonSupport._
import sttp.client3._
import sttp.model.Method
object AuthTokensApi {
def apply(baseUrl: String = "https://api.openverse.engineering/v1") = new AuthTokensApi(baseUrl)
}
def registerApiOauth2(format: String, data: InlineObject
): Request[Either[ResponseException[String, Exception], OAuth2RegistrationSuccessful], Any] =
basicRequest
.method(Method.POST, uri"$baseUrl/auth_tokens/register/?format=${ format }")
.contentType("application/json")
.body(data)
.response(asJson[OAuth2RegistrationSuccessful])
Where InlineObject
and OAuth2RegistrationSuccessful
are simply case classes and JsonSupport
is the following:
object JsonSupport extends SttpJson4sApi {
def enumSerializers: Seq[Serializer[_]] = Seq[Serializer[_]]() :+
new EnumNameSerializer(AudioReportRequestEnums.Reason) :+
new EnumNameSerializer(ImageReportRequestEnums.Reason)
private class EnumNameSerializer[E <: Enumeration: ClassTag](enum: E) extends Serializer[E#Value] {
import JsonDSL._
val EnumerationClass: Class[E#Value] = classOf[E#Value]
def deserialize(implicit format: Formats): PartialFunction[(TypeInfo, JValue), E#Value] = {
case (t @ TypeInfo(EnumerationClass, _), json) if isValid(json) =>
json match {
case JString(value) => enum.withName(value)
case value => throw new MappingException(s"Can't convert $value to $EnumerationClass")
}
}
private[this] def isValid(json: JValue) = json match {
case JString(value) if enum.values.exists(_.toString == value) => true
case _ => false
}
def serialize(implicit format: Formats): PartialFunction[Any, JValue] = {
case i: E#Value => i.toString
}
}
implicit val format: Formats = DefaultFormats ++ enumSerializers ++ DateSerializers.all
implicit val serialization: org.json4s.Serialization = org.json4s.jackson.Serialization
}
To reproduce I simply call the method registerApiOauth2
with the corresponding parameters.
The problem is that the compiler crashes because of the format
parameter with the following errors:
No implicit view available from examples.openverse.model.InlineObject => sttp.client3.BasicRequestBody.
.body(data)
No org.json4s.Formats found. Try to bring an instance of org.json4s.Formats in scope or use the org.json4s.DefaultFormats.
.response(asJson[OAuth2RegistrationSuccessful])
The problems are resolved when I change format
to any other parameter, such as frmt
. However, this cannot be done because the generated query parameter must be called as such. This is the first time I came across such a problem and was hoping that there is a workaround. My hunch is that the issue stems from the JsonSupport
object.
Link to Scastie with an MCVE: https://scastie.scala-lang.org/oDmYLP8MQOCMqUYEwhJnDg
"com.softwaremill.sttp.client3" %% "json4s" % "3.8.0"
,"org.json4s" %% "json4s-jackson" % "4.0.5"
. Also I added importsorg.json4s._
,org.json4s.jackson.JsonMethods._
,scala.reflect.ClassTag
and commdented out some unresolved places: scastie.scala-lang.org/DmytroMitin/SKP8oIh0TPizhpzsv7ATOg/15 I can't see difference in behavior withformat
vs.frmt
. – Numenformat
variable. I cannot understand why because on my editor the build passes without any issue with the variable set anything butformat
. – Torque