utoipa
utoipa copied to clipboard
IntoParams optional parameter with #[serde(default)]
At the moment if a field is marked with #[serde(default)]
it is still noted as a required field in the generated openapi schema.
Yes serde(default)
is not regarded in any way at the moment. Support for this could be added though. I have a plan to support flatten
too so they could be implemented in tandem.
I am interested in working on this, I will update this issue with my progress. Don't let it stop anyone else though! This is my first contribution to this project so it will be slow.
Alright its good to have more contributions :) Speeds up the overall development.
I might have missed something, but I am unable to get a field to be documented as optional when using the IntoParams
derive macro. To make sure this was not a regression, I have used the 2.3.0 release where #339 was published:
# Cargo.toml
[package]
name = "optional-utoipa-param"
version = "0.1.0"
edition = "2021"
[dependencies]
serde = "1.0.188"
utoipa = "=2.3.0"
I am currently using the code below.
// src/main.rs
use serde::Deserialize;
use utoipa::{IntoParams, OpenApi};
#[derive(Deserialize, IntoParams)]
pub struct Params {
#[into_params(required = false)]
pub a: String,
pub b: Option<String>,
#[serde(default)]
pub c: String,
#[serde(default)]
pub d: Option<String>,
}
#[utoipa::path(get, path = "/test", params(Params))]
pub fn test() {
unimplemented!();
}
#[derive(OpenApi)]
#[openapi(paths(test))]
struct ApiDoc;
fn main() {
println!("{}", ApiDoc::openapi().to_json().unwrap());
}
However, with cargo build && ./target/debug/optional-utoipa-param | jq
, we can see that all four fields are marked as required:
{
"openapi": "3.0.3",
"info": {
"title": "optional-utoipa-param",
"description": "",
"contact": {
"name": ""
},
"license": {
"name": ""
},
"version": "0.1.0"
},
"paths": {
"/test": {
"get": {
"tags": [
"crate"
],
"description": "",
"operationId": "test",
"parameters": [
{
"name": "a",
"in": "path",
"required": true,
"schema": {
"type": "string"
}
},
{
"name": "b",
"in": "path",
"required": true,
"schema": {
"type": "string"
}
},
{
"name": "c",
"in": "path",
"required": true,
"schema": {
"type": "string"
}
},
{
"name": "d",
"in": "path",
"required": true,
"schema": {
"type": "string"
}
}
],
"responses": {},
"deprecated": false
}
}
}
}
Could you tell me if there is anything I missed?
To anyone wondering, this is because the parameters_in
default to path
, where all fields are always required. This fixes the issue I had:
diff --git a/src/main.rs b/src/main.rs
index aa9ff69..b391236 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -2,6 +2,7 @@ use serde::Deserialize;
use utoipa::{IntoParams, OpenApi, ToSchema};
#[derive(Deserialize, IntoParams, ToSchema)]
+#[into_params(parameter_in = Query)]
pub struct Params {
#[into_params(required = false)]
pub a: String,