Where communities thrive


  • Join over 1.5M+ people
  • Join over 100K+ communities
  • Free without limits
  • Create your own community
People
Repo info
Activity
  • Oct 26 22:01
    tomasherman commented #1526
  • Oct 26 21:59
    tomasherman synchronize #1526
  • Oct 26 21:41
    tomasherman commented #1526
  • Oct 26 21:34
    tomasherman synchronize #1526
  • Oct 26 13:55
    adamw commented #1167
  • Oct 26 13:45
    adamw commented #1167
  • Oct 26 13:16

    adamw on master

    Fix link to the schema derivati… Fix link to the schema derivati… Regenerate site docs and 1 more (compare)

  • Oct 26 13:16
    adamw closed #1556
  • Oct 26 13:16
    adamw commented #1556
  • Oct 26 13:09
    danicheg opened #1556
  • Oct 26 09:41
    micossow synchronize #1508
  • Oct 26 09:41

    micossow on CVE-2021-41084-test

    Vertx - use their own logging A… (compare)

  • Oct 26 08:48
    micossow opened #1555
  • Oct 26 08:43

    micossow on part-option-doc

    document how to use Part[Option… (compare)

  • Oct 26 07:51
    micossow synchronize #1508
  • Oct 26 07:51

    micossow on CVE-2021-41084-test

    Vertx - fail future instead of … Netty - add logging (compare)

  • Oct 26 06:33

    mergify[bot] on gzip-file-handling

    (compare)

  • Oct 26 06:32

    adamw on master

    Added test for handling gzipped… First try to implement gzipped … Added more test around gzipeped… and 6 more (compare)

  • Oct 26 06:32
    adamw closed #1542
  • Oct 26 06:32
    adamw closed #1434
Gwenael Cholet
@gwenaelcholet
Which librairy is supposed to bring it?
tolikbotov
@tolikbotov

Hello. I have server http4s , tapir as api description and zio as server interpreter.

I want to log user id after auth.bearer[String]() passed. But i log incoming request in http4s.

Is there any example, how can i log request with authorization?

4 replies
Daria
@brainsap

Hi, guys! I have a question about openapi yaml generation -
I've changed one of my case class fields in api response from Map[String, MyClass] to a List[MyClass], and now it is not marked as a required property (as Map object was).
For example, this:

case class MyResponse(
      @description("String field") myString: String = "Hello",
      @description("List field") myList: List[String] = Nil
)

Leads to the result -

MyResponse:
    required:
    - myString
    type: object
    properties:
      MyList:
        type: array

It seems like an array type fields are not marked by Tapir as required properties by default, is this true?
If so, is there an easy (or the preferred = ) way to do this?)
Thanks!

8 replies
vonchav
@voonchav_gitlab
Hi @adamw, it doesn't seem like tapir-swagger-ui-zio-http_2.13:0.19.0-M7 is published.
2 replies
heksesang
@heksenlied:matrix.org
[m]
I was just about to say the same – tried to upgrade, but ran into that issue.
1 reply
allawala
@allawala
hey guys, is this "com.softwaremill.sttp.tapir" %% "tapir-json-zio" % "0.19.0-M7" not available for scala 3? It cant seem to download it.
luping.qiu
@lupingqiu
I use play framework, is there a way to get the play Route documentation? or is there an easy way to build the documentation?
1 reply
Anton Solovyev
@Rosteelton
Hi! Is there some implementations for micrometer or some plans? (like, tapir-prometheus-metrics)
1 reply
Gwenael Cholet
@gwenaelcholet

Dear @Adamw, I am trying the following example to expose a route to serve svg file content:

import akka.http.scaladsl.server.Route
import sttp.tapir._
import sttp.tapir.server.akkahttp.AkkaHttpServerInterpreter

import scala.concurrent.Future

val filesRoute: Route = AkkaHttpServerInterpreter().toRoute(
filesServerEndpointFuture("/home/static/data")
)

Despite I have tapir-core i am unable to import filesServerEndpoint. Always unknow.
Also how can I add a route to render the file name. Thanks in advance for you answer.

2 replies
filesServerEndpoint[Future]
is used
with ("site" / "static")("/home/static/data")
Gwenael Cholet
@gwenaelcholet
How can we make a swagger UI route def for filesServerEndpoint?
Christopher London
@chrisjl154

Does anyone know how I can make a query param of Option[List[A]] work? I keep getting Codec errors?

[error] Did you define a codec for: Option[List[String]]? [error] Did you import the codecs for: sttp.tapir.CodecFormat.TextPlain? [error] query[Option[List[String]]]("id_types")

4 replies
tolikbotov
@tolikbotov
Hello. Can i exclude some header("x-id") from openApi documentation?
Maybe there is .ignore method?
2 replies
Gwenael Cholet
@gwenaelcholet
Does someone knows how to use the very useful method getFromFile within tapir route/endpoint system? Thanks in advance
Gwenael Cholet
@gwenaelcholet
For example if I want to download any file - xlsx, xml, xtx - and to answer it as byte array$
2 replies
Gwenael Cholet
@gwenaelcholet
I am also trying the example MultipartFormUploadAkkaServer with object case class UserProfile(name: String, hobby: Option[String], age: Int, photo: Part[File])
2 replies
But I cannot find codec for the Part[File]
could not find implicit value for evidence parameter of type Titi.this.JF[sttp.model.Part[java.io.File]]
implicit val tt: JsonFormat[UserProfile] = jsonFormat4(UserProfile.apply)
Uwe Reimann
@shagoon
Hi. I'm trying to use a base endpoint for authorization. The base endpoint set E to ErrorInfo as described in https://tapir.softwaremill.com/en/latest/endpoint/statuscodes.html. Is it possible to provide additional error mappings in the secured endpoint (like ValidationError), or do I have to provide the error mappings of any specific (secured) endpoint in the base endpoint?
2 replies
Bill Frasure
@swoogles
Hi, I've got a list of ServerEndpoints in my ApplicationLoader, and my colleague is asking for a basic list of all the corresponding URLs.
Any tips for how to get only the hard String values and pathParam values?
The closest I've come so far is serverEndpoint.info.show, but that includes QueryParams, POST payloads, etc
Bill Frasure
@swoogles
Okay I figured it out. Wasn't too hard, but it does rely on internal methods-
import sttp.tapir.EndpointInput.{FixedPath, PathCapture}
import sttp.tapir.internal.RichEndpointInput

serverEndpoint.input.traverseInputs {
        case path: FixedPath[_] => Vector(path.s)
        case pathCapture: PathCapture[_] => Vector (pathCapture.name.map("$" + _) .getOrElse("$unnamedPathVariable") )
      }
1 reply
heksesang
@heksenlied:matrix.org
[m]
@adamw I am trying to derive a Schema[Map[User.Id, User]] where User.Id is defined as a newtype (using zio.prelude) with java.util.UUID as the underlying type and I have mapped the Schema[UUID] instance to define the Schema[User.Id] instance. When I use Schema.schemaForMap[User.Id, User] the name of the component in the OpenAPI documentation becomes Map_<refinement>_User. Is there anything I can do to make the macro use a proper name for the newtype? Where would the macro be getting the name <refinement> from in this case?
2 replies
sebarys
@sebarys

hello,
Is it possible to define endpoint that return Seq[T] and response status code different than default?
I would like in case of processing request success return 201 Created together with Seq[MyCustomType] MyCustomType has circe Encoder/Decoder and Schema

Still I'm not able to define it because of type erasure, in docu I see an exaple with Either, but I'm not able to align it for Seq[T] https://tapir.softwaremill.com/en/latest/endpoint/statuscodes.html

6 replies
Thanks in advance for any suggestions :)
basically in case of success I have one scenario: return 201 Created together with Seq[MyCustomType] - is it simple way to express it?
tolikbotov
@tolikbotov

Hello. Is there any way to describe in docs parameters of SeeOther.
I return this:

.out(oneOf(
        oneOfMapping(
          SeeOther,
          header[String]("Location")
            .description("Redirect address \n params: `status` - success or fail")
        )
      ))

I want to write in docs queryParameter status.

1 reply
Stanislav Bolsun
@stanislav3316
Hello, I have tapir Schema for some type A and want to generate open-api doc for the type A only. Can I do it? (without generation whole documentation, I need only yaml with single A type description as object).
thanks!
4 replies
yurique
@yurique:nowhere.chat
[m]

hi everyone!
I've stumbled upon this: I have this in the endpoint definition:

      .in(jsonBody[List[MyData])

and in the openapi spec it generates it as optional:

"requestBody": {
  "content": {
    "application/json": {
      "schema": {
        "type": "array",
        "items": {
          "$ref": "#/components/schemas/MyData"
        }
      }
    }
  },
  "required": false
},

is there a reason for this or is it a bug? can I somehow tell tapir that it's not optional?

3 replies
yurique
@yurique:nowhere.chat
[m]

@ex0ns: hi! :)

I think the reason is that the array is required by default as it's top level, but the array might be empty

that's what I want, but "required": false says it's not even required, and openapi generator for typescript generates the body as optional

and if someone sends a POST request with body=undefined, the backend will try to parse the body as a JSON array and will fail because it will be empty (empty body)

heksesang
@heksenlied:matrix.org
[m]
@yurique Iterables are rendered as optional in the documentation because tapir has the opinion that there isn't really any difference between an empty array and an undefined array in JSON. And in most cases that's true, for example with your List[MyData] the codec should generate an empty list if there isn't defined one in the JSON which will fulfill the requirements of the spec.
ex0ns
@ex0ns
I agree with Yurique that in some condition, it does cause issue, as for the empty body instead of body with empty list

In the meantime a solution might be to have a fallback when parsing a List in the backend, where you would return an empty list in case of failure, that is far from perfect, but would not be too hard to implement (custom encoder), or you could wrap the list in an object and use it in the json body

final case class RequestBodyData(data: List[MyData])
....
.in(jsonBody[RequestBodyData])

But the resulting JSON would look like

{
  "data": [ ] 
}
yurique
@yurique:nowhere.chat
[m]
well, circe doesn't think an empty string is parseable as an empty list ;)
scala> import io.circe.parser._
import io.circe.parser._

scala> parse("")
val res0: Either[io.circe.ParsingFailure,io.circe.Json] = Left(io.circe.ParsingFailure: exhausted input)
@ex0ns: I was thinking about wrapping that list into a case class, the best I could think of

but this doesn't seem right:

tapir has the opinion that there isn't really any difference between an empty array and an undefined array

to be sure I sent an empty body to that endpoint (with http4s backend), got a Bad Request with a message from circe:
"Invalid value for: body (DecodingFailure at : C[A])"
Patrick Roemer
@sangamon
I'm trying to get a query parameter with a default value. What I have is this:
implicit val xyzSchema: Schema[XYZ] =
  Schema.string
    .validate(Validator.derivedEnumeration[XYZ].encode(_.tag))
    .default(XYZ.X, Some(XYZ.X.tag))

implicit val xyzCodec: PlainCodec[XYZ] =
  Codec.string
    .mapDecode(s => DecodeResult.fromOption(XYZ(s)))(_.tag)
    .schema(xyzSchema)
5 replies
Works, but if I pass an invalid value (that returns None from XYZ#apply()), it will be accepted and reverted to the default value X. What I'd want is that the default fallback is only applied if the query parameter isn't present at all, but a decode failure if an invalid value is given. Am I doing anything wrong and/or can this be achieved somehow?
Patrick Roemer
@sangamon
Another question: I have an endpoint that generates the same output shape for error responses in the 400s range. I came across this discussion:
softwaremill/tapir#796
The suggested #map() approach seems to work fine in general, but of course the OpenAPI doc only shows the describedStatusCode. Is there any way to get a 4XX range rendered instead? (I guess not, but perhaps I'm missing some trick.)
2 replies
Patrick Roemer
@sangamon
...and a last, rather esoteric question. In the akka-http code base I'm currently trying to switch over to Tapir, we have a couple of endpoints based on a reverse proxy route directive, i.e. these are dispatching the request to another service and return their response as is. For now, I have a Tapir description for these endpoints, but these are only used for OpenAPI generation. Is there any way to tie the Tapir spec to the native akka-http route implementation? Or is there anything else in Tapir to support reverse proxy cases? (I wouldn't even know how either of this should work at the conceptual level, but again, I might be missing something.)
8 replies
Anne
@AnneThor
Hi! I am trying to transition my http4s routes to tapir, and I am having a little trouble with one route which is translating a x-www-form-urlencoded form into a case class. Right now the case class is very basic, just holding a bunch of values that are strings. I see that I need to create a Codec[String, CaseClass, XWwwFormUrlencoded], but I am not sure how to this (do I need to do it manually? I am using circe and I have an EntityDecoder for the case class). I do not see a similar example in the docs, I am not clear on what exactly I need to implement to solve this?
5 replies
Patrick Roemer
@sangamon
I'd like an endpoint to optionally set a cookie in the response. Is there some high-level functionality that I'm missing (setCookie doesn't seem to cover the optional case) or will I need to drop to header level for this?
4 replies
bartholomews
@bartholomews:matrix.org
[m]
Hello I have replaced two query inputs with a EndpointInput.QueryParams, it works fine but in the generated swagger it now shows "No parameters", do you know if I am missing something ?
1 reply
Izmar Verhage
@izzyreal
We're trying to upgrade tapir from 0.17 to v0.18, used with Akka HTTP. For responding with a dynamic Location header that contains an URI like "/pet/{newPetID}" we used to rely on AkkaHttpServerInterpreter.toDirective, but toDirective was removed in 0.18. Any ideas how to achieve this?
13 replies
Ulyana Morozova
@ulymor

Hi! I use tapir version "0.17.9". I have endpoint with json request model with property of type AggregateFunction. Decoder looks like that:

import io.circe.{Decoder, Encoder, HCursor, Json}
import sttp.tapir.Codec.PlainCodec
import sttp.tapir.{Codec, DecodeResult}

sealed trait AggregateFunction {
  def id: Short
  def name: String
  override def toString: String = name
}

case object MinFunction     extends AggregateFunction { val name = "min";  val id = 0 }
case object MaxFunction     extends AggregateFunction { val name = "max";  val id = 1 }
case object UnknownFunction extends AggregateFunction { val name = "unknown";  val id = -1 }

object AggregateFunction {
  def apply(name: String): AggregateFunction =
    name match {
      case MinFunction.name => MinFunction
      case MaxFunction.name => MaxFunction
      case _ => UnknownFunction
    }

  def apply(id: Int): AggregateFunction =
    id match {
      case MinFunction.id => MinFunction
      case MaxFunction.id => MaxFunction
      case _ => UnknownFunction
    }

  def encode(valuesAggregator: AggregateFunction): String = valuesAggregator.name

  def decode(s: String): DecodeResult[AggregateFunction] = AggregateFunction(s) match {
    case UnknownFunction => DecodeResult.Error(s, new IllegalArgumentException("Invalid item type."))
    case v => DecodeResult.Value(v)
  }

  implicit val AggregateFunctionCodec: PlainCodec[AggregateFunction] = Codec.string
    .mapDecode(decode)(encode)

  implicit val encoder: Encoder[AggregateFunction] = (nt: AggregateFunction) => Json.fromString(nt.name)
  implicit val decoder: Decoder[AggregateFunction] = (hc: HCursor) => hc.as[String].map(apply)

}

I want to return 400 Bad request error in json format {"message": "Invalid name of aggregate function"} if users try to send wrong function name.
But now the response has string format 400 Bad request "Invalid value for: body (String at 'aggregateFunction')". How I could change error response format from String to Json?

9 replies
Giuseppe Cannella
@gekomad
Sorry for OT there is not a dedicate gitter on quicklens, the question is about Enum see here https://stackoverflow.com/questions/69195290/scala-quicklens-enumeration
1 reply
joules-o
@joules-o
I'm trying to migrate to sttp client3 / tapir 0.17.0, but my linter fails on Any. I don't want to turn this off, but I'd really rather not add ignore annotations to some 40-odd endpoints. Is there some version of a no-op stream type I can use instead of Any?