paperclip
paperclip copied to clipboard
Support serde attributes
This code:
use actix_web::{App, HttpServer};
use paperclip::actix::{
OpenApiExt, Apiv2Schema, api_v2_operation,
web::{self, Json},
};
use serde::{Serialize, Deserialize};
#[derive(Serialize, Deserialize, Apiv2Schema)]
struct Pet {
#[serde(skip_serializing)]
ser: String,
#[serde(skip_deserializing)]
de: String,
#[serde(skip)]
both: String,
name: String,
id: Option<i64>,
}
#[api_v2_operation]
async fn echo_pet(body: Json<Pet>) -> Result<Json<Pet>, ()> {
Ok(body)
}
#[actix_web::main]
async fn main() -> std::io::Result<()> {
HttpServer::new(|| App::new()
.wrap_api()
.service(
web::resource("/pets")
.route(web::post().to(echo_pet))
)
.with_json_spec_at("/api/spec")
.build()
).bind("127.0.0.1:8081")?
.run().await
}
generates this JSON:
{
"swagger": "2.0",
"definitions": {
"Pet": {
"type": "object",
"properties": {
"both": {
"type": "string"
},
"de": {
"type": "string"
},
"id": {
"type": "integer",
"format": "int64"
},
"name": {
"type": "string"
},
"ser": {
"type": "string"
}
},
"required": ["both", "de", "name", "ser"]
}
},
"paths": {
"/pets": {
"post": {
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/Pet"
}
}
},
"parameters": [{
"in": "body",
"name": "body",
"required": true,
"schema": {
"$ref": "#/definitions/Pet"
}
}]
}
}
},
"info": {
"version": "",
"title": ""
}
}
But because of the serde configurations I have, the generated JSON is wrong!
I expect to see something similar to this:
{
"swagger": "2.0",
"definitions": {
"Pet1": {
"type": "object",
"properties": {
"de": {
"type": "string"
},
"id": {
"type": "integer",
"format": "int64"
},
"name": {
"type": "string"
}
},
"required": ["de", "name"]
},
"Pet2": {
"type": "object",
"properties": {
"id": {
"type": "integer",
"format": "int64"
},
"name": {
"type": "string"
},
"ser": {
"type": "string"
}
},
"required": ["name", "ser"]
}
},
"paths": {
"/pets": {
"post": {
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/Pet2"
}
}
},
"parameters": [{
"in": "body",
"name": "body",
"required": true,
"schema": {
"$ref": "#/definitions/Pet1"
}
}]
}
}
},
"info": {
"version": "",
"title": ""
}
}
Maybe there are some better ways of handling this.
We do support parsing some serde attributes, but we have to support the remaining serde attributes. I don't see another way, sadly 😕
@omid have a look at #309. It handles the skip but I'm not sure how to handle the selective skip_serializing and skip_deserializing properly.
@tiagolobocastro thanks, it's awesome.
Yep, the skip_serializing
and skip_deserializing
are harder. Since it needs to create two different definitions (for example /definitions/Pet_serialize
and /definitions/Pet_deserialize
, instead of just /definitions/Pet
) automatically, and it seems anti-pattern for a proper API!