tapir icon indicating copy to clipboard operation
tapir copied to clipboard

[BUG] Open API Parameter Serialization

Open user753 opened this issue 3 years ago • 3 comments

Tapir version: 0.16.16

Scala version: 2.13.1

Describe the bug I want to use objects in query parameters

  def jsonQuery[T: Encoder : Decoder : Schema](name: String): EndpointInput.Query[T] = {
    implicit val codec = Codec.string.mapDecode(x => decode[T](x).fold(
      x => DecodeResult.Error("json parse error", x),
      x => DecodeResult.Value(x)))(_.asJson.noSpaces)
      .schema(implicitly[Schema[T]])
    query[T](name)
  }

  val foo = endpoint.in("foo")
    .in(jsonQuery[Sort]("sort")).out(jsonBody[Sort])

Tapir generate this yaml

openapi: 3.0.1
info:
  title: API
  version: '1.0'
paths:
  /foo:
    get:
      operationId: getFoo
      parameters:
      - name: sort
        in: query
        required: true
        schema:
          $ref: '#/components/schemas/Sort'
      responses:
        '200':
          description: ''
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Sort'
components:
  schemas:
    Sort:
      required:
      - field
      - order
      type: object
      properties:
        field:
          type: string
        order:
          type: string

Open Api support 3 types of object serialization in query https://swagger.io/docs/specification/serialization/#query

style:style explode:true /users?role=admin&firstName=Alex (default)
style:style explode:false  /users?id=role,admin,firstName,Alex
style:deepObject explode:true  /users?id[role]=admin&id[firstName]=Alex

Tapir doesn't add any style or explode parameters so url for endpoint should be

/foo?field=a&order=b

But such url doesn't work

Invalid value for: query parameter sort

Neither do

/foo?sort=field,a,order,b
/foo?sort[field]=a&sort[order]=b

I think Tapir should use deepObject:true in object query parameters and support urls like /foo?sort[field]=a&sort[order]=b

user753 avatar Sep 26 '20 06:09 user753

This is not a bug, it’s a feature request.

andyczerwonka avatar Oct 14 '20 01:10 andyczerwonka

@andyczerwonka I think If it would throw NotImplementedError then yes. But it generates incorrect documentation, so I believe it is a bug.

user753 avatar Oct 14 '20 05:10 user753

@user753 The idiomatic approach, at least as documented, is to map query parameters to a case class with the mapTo and/or mapInTo methods.

Also note, your codec suggests you want json as a query parameter. Also note, Schema derivation is not tied to serde (which is unfortunate for many use cases).

andyczerwonka avatar Oct 14 '20 15:10 andyczerwonka