poem-web / poem

A full-featured and easy-to-use web framework with the Rust programming language.
Apache License 2.0
3.65k stars 293 forks source link

Support for nullable data types (Option<>) in poem-openapi #701

Open ettom opened 1 year ago

ettom commented 1 year ago

Description of the feature

It would be nice if a type being wrapped in Option<> would be shown as nullable in the OpenAPI document. See https://stackoverflow.com/questions/48111459/how-to-define-a-property-that-can-be-string-or-null-in-openapi-swagger

Code example

#[oai(path = "/hello", method = "get")]
async fn hello(&self) -> Json<Option<String>> {
    Json(None)
}

would generate

paths:
  /hello:
    get:
      responses:
        '200':
          description: ''
          content:
            application/json; charset=utf-8:
              schema:
                type: string
                nullable: true

Additionally,

#[derive(Object)]
struct Foo {
    x: Option<i32>,
}

#[OpenApi]
impl Api {
    #[oai(path = "/hello", method = "post")]
    async fn hello(&self, _p: Json<Foo>) {}
}

would generate

paths:
  /hello:
    post:
      requestBody:
        content:
          application/json; charset=utf-8:
            schema:
              $ref: '#/components/schemas/Foo'
        required: true
      responses:
        '200':
          description: ''
components:
  schemas:
    Foo:
      type: object
      properties:
        x:
          type: integer
          format: int32
          nullable: true

Thanks for the amazing work!

moritzruth commented 8 months ago

By default, serde serializes Option::None as null. It does not skip the field altogether.

This means that objects serialized by serde actually do not adhere to the schema generated by poem-openapi in case there are Option::None values.

kidqueb commented 1 month ago

By default, serde serializes Option::None as null. It does not skip the field altogether.

Isn't this what is happening in the example and PR? A nullable field, albeit manually specified in the PR, would make None become null