juhaku / utoipa

Simple, Fast, Code first and Compile time generated OpenAPI documentation for Rust
Apache License 2.0
2.47k stars 192 forks source link

Derive Component doesn't support tuples? #176

Closed kellpossible closed 1 year ago

kellpossible commented 2 years ago
#[derive(Component)]
struct Bar {
    foo: (String, String)
}

or

#[derive(Component)]
struct Bar {
    foo: (String)
}

I get the following error message:

unexpected type in component part get type path, expected one of: Path, Reference, Group
juhaku commented 2 years ago

Yeah they are not supported. The reason is that there is no good way to serialize them as OpenAPI doc and the only way to represent tuples are to represent them as array of items with a specifc size. Also if tuple contains different types then we can only represent it as array of general object types thus not being helpful to the user. Here https://serde.rs/json.html tuples are serialized as array of types and OpenAPI cannot represent multitype arrays.

kellpossible commented 2 years ago

The json schema generated for this struct is:

{
  "$schema": "http://json-schema.org/draft-07/schema#",
  "title": "Bar",
  "type": "object",
  "required": [
    "foo"
  ],
  "properties": {
    "foo": {
      "type": "array",
      "items": [
        {
          "type": "string"
        },
        {
          "type": "string"
        }
      ],
      "maxItems": 2,
      "minItems": 2
    }
  }
}

I guess the subset of json schema that OpenAPI 3.0 uses doesn't include items...

Okay from the spec:

items - Value MUST be an object and not an array. Inline or referenced schema MUST be of a Schema Object and not a standard JSON Schema. items MUST be present if the type is array.

kellpossible commented 2 years ago

Perhaps at least we could improve the error message?

juhaku commented 2 years ago

Yeah, we could, and also what we can do also is to implement support for this behaviour similary already existin for UnnamedStruct in https://github.com/juhaku/utoipa/blob/master/utoipa-gen/src/schema/component.rs#L323.

So what it does it creates an object array with the size of the array which will be the amount of tuple items. Adding this kind of behaviour to the component fields is not too big of a addition though. But I dont know whether it is useful for the users thus I haven't implemented it previously.

It's because Rust's type system is so flexible. So it makes it difficult to support all the type representations supported by the Rust in OpenAPI spec as it was not build for Rust originally.

juhaku commented 1 year ago

Related #330, #391

juhaku commented 1 year ago

Native support for tuples is coming here: #541