Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Error in openapi schema for Enum #121

Closed
szagi3891 opened this issue Dec 7, 2021 · 14 comments
Closed

Error in openapi schema for Enum #121

szagi3891 opened this issue Dec 7, 2021 · 14 comments
Labels
bug Something isn't working

Comments

@szagi3891
Copy link

Expected Behavior

A different type is expected for the enum:

"geoRuleType": {
  "type": "string",
  "enum": [
    "DENY",
    "ALLOW"
  ]
}

Actual Behavior

"GeoRuleType": {
  "type": "GeoRuleType",
  "enum": [
    "DENY",
    "ALLOW"
  ]
},

Steps to Reproduce the Problem

  1. You have to clone https://github.com/szagi3891/poem-test
  2. And then run with cargo run

Specifications

  • Version: poem = "1.0.38", poem-openapi = "1.0.41"
  • Platform: MacOs
  • Subsystem:
{
  "openapi": "3.0.0",
  "info": {
    "title": "Oneof",
    "version": "1.0"
  },
  "servers": [],
  "tags": [],
  "paths": {
    "/api1/hello": {
      "post": {
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "type": {
                    "type": "string",
                    "enum": [
                      "A",
                      "B"
                    ]
                  }
                },
                "oneOf": [
                  {
                    "$ref": "#/components/schemas/A"
                  },
                  {
                    "$ref": "#/components/schemas/B"
                  }
                ],
                "discriminator": {
                  "propertyName": "type"
                }
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "Created successfully",
            "content": {
              "application/json": {
                "schema": {
                  "type": "integer",
                  "format": "uint64"
                }
              }
            }
          },
          "403": {
            "description": "Permission denied",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Forb"
                }
              }
            }
          },
          "500": {
            "description": "Internal error"
          }
        }
      }
    }
  },
  "components": {
    "schemas": {
      "GeoRuleType": {
        "type": "GeoRuleType",
        "enum": [
          "DENY",
          "ALLOW"
        ]
      },
      "B": {
        "type": "object",
        "required": [
          "v3",
          "list"
        ],
        "properties": {
          "v3": {
            "type": "number",
            "format": "float32"
          },
          "list": {
            "type": "object",
            "additionalProperties": {
              "type": "integer",
              "format": "uint64"
            }
          },
          "sport": {
            "$ref": "#/components/schemas/SportModel"
          }
        }
      },
      "Forb": {
        "type": "object",
        "required": [
          "message",
          "age"
        ],
        "properties": {
          "message": {
            "type": "string"
          },
          "age": {
            "type": "integer",
            "format": "int32"
          }
        }
      },
      "A": {
        "type": "object",
        "required": [
          "v1",
          "v2"
        ],
        "properties": {
          "v1": {
            "type": "integer",
            "format": "int32"
          },
          "v2": {
            "type": "string"
          }
        }
      },
      "SportModel": {
        "type": "object",
        "required": [
          "id",
          "name",
          "displayOrder",
          "geoRuleType"
        ],
        "properties": {
          "id": {
            "type": "string"
          },
          "name": {
            "type": "string"
          },
          "displayOrder": {
            "type": "integer",
            "format": "uint64"
          },
          "geoRuleType": {
            "$ref": "#/components/schemas/GeoRuleType"
          }
        }
      }
    }
  }
}
@szagi3891 szagi3891 added the bug Something isn't working label Dec 7, 2021
@szagi3891
Copy link
Author

I have validated this specification on https://editor.swagger.io/
This page returns such an error message:

Structural error at components.schemas.GeoRuleType.type
should be equal to one of the allowed values
allowedValues: array, boolean, integer, number, object, string

@szagi3891
Copy link
Author

pub enum State {
    #[serde(rename = "open")]
    Open
}

How to handle the renaming of a field in a poem ?

@sunli829
Copy link
Collaborator

sunli829 commented Dec 7, 2021

Thank you very much, fixed in 1.0.43 🙂

https://docs.rs/poem-openapi/1.0.40/poem_openapi/derive.Enum.html#item-parameters

#[derive(Enum)]
enum MyEnum {
     CreateUser,
     #[oai(rename = "delete_user")]
     DeleteUser,
}

@szagi3891
Copy link
Author

Works beautifully :)

And are there any equivalents for these attributes ?
#[serde(untagged)]
#[serde(deny_unknown_fields)]

@szagi3891
Copy link
Author

I think it will be good for my API if I get rid of these two attributes untagged and deny_unknown_fields.
Once again, many thanks for your help :)

@sunli829
Copy link
Collaborator

sunli829 commented Dec 8, 2021

#[serde(deny_unknown_fields)]

I want to deny unknown fields by default, what do you think? @szagi3891

@szagi3891
Copy link
Author

Yes, it would be nice to have this option.

Would it be possible to make an equivalent for this switch ?
#[serde(untagged)]

@sunli829
Copy link
Collaborator

sunli829 commented Dec 8, 2021

Sorry, can you tell me what #[serde(untagged)] does? 😁

@szagi3891
Copy link
Author

https://serde.rs/enum-representations.html#untagged

Then you can have many different variants of objects with different types. Something like OneOf but without the field that defines their type.

@sunli829
Copy link
Collaborator

sunli829 commented Dec 8, 2021

How to define this type in the spec?

@sunli829
Copy link
Collaborator

sunli829 commented Dec 8, 2021

I guess you want this?

#[serde(tag = "type")]
enum Obj {
    A {
        a: i32,
    }
    B {
        b: i32
    }
}

@szagi3891
Copy link
Author

This is a sample schema:

"sport": {
   "nullable":true,
   "oneOf":[
      {
         "type":"string"
      },
      {
         "items":{
            "type":"string"
         },
         "type":"array"
      },
      {
         "properties":{
            "ne":{
               "items":{
                  "type":"string"
               },
               "type":"array"
            }
         },
         "type":"object",
         "required":[
            "ne"
         ]
      }
   ]
},

In this case of use, the field that specifies the type of variant of the enum is not used at all

@szagi3891
Copy link
Author

This schema above, is generated from such a rustic structure|:

#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
#[serde(untagged)]
pub enum EventsQuerySport {
    Simple(Arc<String>),
    Vec(Vec<Arc<String>>),
    Not {
        ne: Vec<Arc<String>>
    }
}

@sunli829
Copy link
Collaborator

deny_unknown_fields

Released in v1.0.50 🙂

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

2 participants