i32 being rendered as #/components/schemas/i32"
Closed this issue · 9 comments
Hi.
Using the following example
#[derive(OpenApi)]
#[openapi(components(schemas(Transactions)))]
struct ApiDoc;
#[derive(ToSchema)]
pub enum Transactions {
Transaction(EntryAlias),
}
pub type EntryAlias = Entry<i32>;
#[derive(ToSchema)]
pub struct Entry<I> {
pub entry_id: I,
}
Integers are being rendered as #/components/schemas/i32"
"components": {
"schemas": {
"Entry": {
"type": "object",
"required": [
"entry_id"
],
"properties": {
"entry_id": {
"$ref": "#/components/schemas/i32"
}
}
},
"Transactions": {
"oneOf": [
{
"type": "object",
"required": [
"Transaction"
],
"properties": {
"Transaction": {
"$ref": "#/components/schemas/Entry"
}
}
}
]
}
}
}
Expected result
"entry_id": {
"type": "integer",
"format": "int32",
}
If Enum is specified like this
#[derive(ToSchema)]
pub enum Transactions {
Transaction(Entry<i32>),
}
Then it renders correctly.
Also I have tried using utoipa-config
use utoipa_config::Config;
fn main() {
Config::new()
.alias_for("EntryAlias","Entry<i32>")
.write_to_file();
}
But this did not help either (assuming I've done it correctly..)
Additionally, by using this example
#[derive(OpenApi)]
#[openapi(components(schemas(Transactions)))]
struct ApiDoc;
#[derive(ToSchema)]
pub enum Transactions {
TransactionWithInteger(EntryIntegerAlias),
TransactionWithString(EntryStringAlias),
}
pub type EntryIntegerAlias = Entry<i32>;
pub type EntryStringAlias = Entry<String>;
#[derive(ToSchema)]
pub struct Entry<I> {
pub entry_id: I,
}
It generates this json
"components": {
"schemas": {
"Entry": {
"type": "object",
"required": [
"entry_id"
],
"properties": {
"entry_id": {
"$ref": "#/components/schemas/String"
}
}
},
"Transactions": {
"oneOf": [
{
"type": "object",
"required": [
"TransactionWithInteger"
],
"properties": {
"TransactionWithInteger": {
"$ref": "#/components/schemas/Entry"
}
}
},
{
"type": "object",
"required": [
"TransactionWithString"
],
"properties": {
"TransactionWithString": {
"$ref": "#/components/schemas/Entry"
}
}
}
]
}
}
}
In which the integer schema disappears
When you change the config in build.rs
try cargo clean
so that next time you build the app wont even accidentally use old cached Config
. This might be happening and is common even with other libs like tonic
.
Otherwise I need the check this up when I get time.
I've tried cargo clean and still generating as "#/components/schemas/i32"
Okay, I have to investigate this a bit and see is there something that can be done. Maybe I have missed something or it did hit the limit of possibilities with automatic resolution.
The build.rs config should not let that happen.
n
Compiling utoipa-config-test v0.1.0 (/home/juha/dev/repos/utoipa/utoipa-config/config-test-crate)
Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.72s
Running `target/debug/utoipa-config-test`
{
"openapi": "3.1.0",
"info": {
"title": "utoipa-config-test",
"description": "",
"license": {
"name": ""
},
"version": "0.1.0"
},
"paths": {},
"components": {
"schemas": {
"Entry_i32": {
"type": "object",
"required": [
"entry_id"
],
"properties": {
"entry_id": {
"type": "integer",
"format": "int32"
}
}
},
"Transactions": {
"oneOf": [
{
"type": "object",
"required": [
"Transaction"
],
"properties": {
"Transaction": {
"$ref": "#/components/schemas/Entry_i32"
}
}
}
]
}
}
}
}
main.rs
#[derive(OpenApi)]
#[openapi(components(schemas(Transactions)))]
struct ApiDoc;
#[derive(ToSchema)]
pub enum Transactions {
Transaction(EntryAlias),
}
pub type EntryAlias = Entry<i32>;
#[derive(ToSchema)]
pub struct Entry<I> {
pub entry_id: I,
}
fn main() {
let api = ApiDoc::openapi();
println!(
"{}",
serde_json::to_string_pretty(&api).expect("api must be JSON serializable")
);
}
build.rs
fn main() {
utoipa_config::Config::new()
.alias_for("EntryAlias", "Entry<i32>")
.write_to_file()
}
And likewise if I have this:
#[derive(OpenApi)]
#[openapi(components(schemas(Transactions)))]
struct ApiDoc;
#[derive(ToSchema)]
pub enum Transactions {
Transaction(EntryAlias),
TransactionEntryString(EntryString),
}
pub type EntryAlias = Entry<i32>;
pub type EntryString = Entry<String>;
#[derive(ToSchema)]
pub struct Entry<I> {
pub entry_id: I,
}
build.rs
fn main() {
utoipa_config::Config::new()
.alias_for("EntryAlias", "Entry<i32>")
.alias_for("EntryString", "Entry<String>")
.write_to_file()
}
the output is
{
"openapi": "3.1.0",
"info": {
"title": "utoipa-config-test",
"description": "",
"license": {
"name": ""
},
"version": "0.1.0"
},
"paths": {},
"components": {
"schemas": {
"Entry_String": {
"type": "object",
"required": [
"entry_id"
],
"properties": {
"entry_id": {
"type": "string"
}
}
},
"Entry_i32": {
"type": "object",
"required": [
"entry_id"
],
"properties": {
"entry_id": {
"type": "integer",
"format": "int32"
}
}
},
"Transactions": {
"oneOf": [
{
"type": "object",
"required": [
"Transaction"
],
"properties": {
"Transaction": {
"$ref": "#/components/schemas/Entry_i32"
}
}
},
{
"type": "object",
"required": [
"TransactionEntryString"
],
"properties": {
"TransactionEntryString": {
"$ref": "#/components/schemas/Entry_String"
}
}
}
]
}
}
}
}
Ugh, not again 😅
I will try again and report back. Thanks for investing
Unfortunately I still experience the same issue even after cargo clean
and cargo update
. Tested both of your examples and behavior is the same as I reported.
It is likely that its something wrong with cargo.lock as in the issue that I previously reported. I trust that it will work fine after release.
So for now the issue may be closed if you wish so. Thanks
Right super weird, hope it will start working then at least as it should. When I tried with the test crate and modified the build.rs
file I had to sometimes to build multiple times or change some files in the codebase in order it to recognize that there was any changes so it could use the fresh config.
Nonetheless closing for now.