schemars icon indicating copy to clipboard operation
schemars copied to clipboard

`serde(skip_serializing)` causes missing fields in examples

Open arctic-alpaca opened this issue 3 years ago • 0 comments

Hello,

I'm writing a REST API and using schemars with rocket_okapi and okapi to create the documentation. This is working quite well so far, but I encountered an issue.

I'm using #[serde(skip_serializing)] to skip a field when serializing a struct, but I expect the field when de-serializing a struct. When I now use #[schemars(example = "Self::example")], the field that's skipped when serializing is missing from the example.

This is my reduced code to show the problem:

[dependencies]
schemars = "0.8.3"
serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0"
use serde::{Deserialize, Serialize};
use schemars::{schema_for, JsonSchema};

pub trait SchemaExample {
    fn example() -> Self;
}

#[derive( JsonSchema,Serialize, Deserialize,  Debug, Default, Clone, Eq, PartialEq)]
#[schemars(example = "Self::example")]
pub struct MyStruct {
    #[serde(skip_serializing)]
    pub field_one: String,
    pub field_two: Option<bool>,
}

impl SchemaExample for MyStruct {
    fn example() -> Self {
        Self {
            field_one: String::from("MyStruct"),
            field_two: Some(true),
        }
    }
}

fn main() {
    let schema = schema_for!(MyStruct);
    println!("{}", serde_json::to_string_pretty(&schema).unwrap());
}

This produces:

{
  "$schema": "http://json-schema.org/draft-07/schema#",
  "title": "MyStruct",
  "examples": [
    {
      "field_two": true
    }
  ],
  "type": "object",
  "required": [
    "field_one"
  ],
  "properties": {
    "field_one": {
      "writeOnly": true,
      "type": "string"
    },
    "field_two": {
      "type": [
        "boolean",
        "null"
      ]
    }
  }
}

instead of the expected:

{
  "$schema": "http://json-schema.org/draft-07/schema#",
  "title": "MyStruct",
  "examples": [
    {
      "field_one": "MyStruct",
      "field_two": true
    }
  ],
  "type": "object",
  "required": [
    "field_one"
  ],
  "properties": {
    "field_one": {
      "writeOnly": true,
      "type": "string"
    },
    "field_two": {
      "type": [
        "boolean",
        "null"
      ]
    }
  }
}

I'm not sure how this can be avoided since creating the example via serializing with serde_json seems like the most straight forward way.

arctic-alpaca avatar Jul 19 '21 11:07 arctic-alpaca