okapi icon indicating copy to clipboard operation
okapi copied to clipboard

Unable to deserialize and then serialize SecurityScheme into JSON

Open Flowneee opened this issue 3 years ago • 0 comments

Hi. There is problem with deserializing and then serializing security scheme into JSON. I have a code which parse spec from YAML, then attempt to serialize it into both YAML and JSON. YAML is valid, but JSON produces duplicated fields type and scheme:

use okapi::openapi3::OpenApi;

static SPEC_ROOT: &str = r##"openapi: 3.0.3
info:
  title: CARDI API
  version: 0.14.0
paths: {}
security:
  - BasicAuth: []
components:
  securitySchemes:
    BasicAuth:
      type: http
      scheme: basic
"##;

let mut spec: OpenApi = serde_yaml::from_str(SPEC_ROOT).unwrap();
println!(
    "DEBUG: {:#?}\nJSON: {}\nYAML: {}", 
    spec, 
    serde_json::to_string_pretty(&spec).unwrap(), 
    serde_yaml::to_string(&spec).unwrap()
);

Problem is that fields type and scheme ends up in both data and extensions fields. Since it looks like some serde limitation/bug, proper solution could be custom deserialization. If this approach is OK, I could try to implement it.

I believe this might be related to https://github.com/GREsau/okapi/issues/74.

Debug output

DEBUG: OpenApi {
    openapi: "3.0.3",
    info: Info {
        title: "CARDI API",
        description: None,
        terms_of_service: None,
        contact: None,
        license: None,
        version: "0.14.0",
        extensions: {},
    },
    servers: [],
    paths: {},
    components: Some(
        Components {
            schemas: {},
            responses: {},
            parameters: {},
            examples: {},
            request_bodies: {},
            headers: {},
            security_schemes: {
                "BasicAuth": Object(
                    SecurityScheme {
                        description: None,
                        data: Http {
                            scheme: "basic",
                            bearer_format: None,
                        },
                        extensions: {
                            "scheme": String(
                                "basic",
                            ),
                            "type": String(
                                "http",
                            ),
                        },
                    },
                ),
            },
            links: {},
            callbacks: {},
            extensions: {},
        },
    ),
    security: [
        {
            "BasicAuth": [],
        },
    ],
    tags: [],
    external_docs: None,
    extensions: {},
}

JSON output (invalid)

{
  "openapi": "3.0.3",
  "info": {
    "title": "CARDI API",
    "version": "0.14.0"
  },
  "paths": {},
  "components": {
    "securitySchemes": {
      "BasicAuth": {
        "type": "http",
        "scheme": "basic",
        "scheme": "basic",
        "type": "http"
      }
    }
  },
  "security": [
    {
      "BasicAuth": []
    }
  ]
}

YAML output (ok)

---
openapi: 3.0.3
info:
  title: CARDI API
  version: 0.14.0
paths: {}
components:
  securitySchemes:
    BasicAuth:
      scheme: basic
      type: http
security:
  - BasicAuth: []

Flowneee avatar Mar 03 '22 14:03 Flowneee