Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Unexpected error with schemas #352

Closed
TheAwiteb opened this issue Nov 18, 2022 · 3 comments
Closed

Unexpected error with schemas #352

TheAwiteb opened this issue Nov 18, 2022 · 3 comments

Comments

@TheAwiteb
Copy link

My endpoint attr

/// Login a user
///
/// This route will return a new token for the user, if the user does not exist, it will return an error.
/// To revoke a previous tokens, use the revoke route `/api/auth/revoke`.
#[utoipa::path(
    context_path = "/api/auth",
    request_body = crate::schemas::auth::LoginSchema,
    responses(
        (status = 200, description = "Login successfully and return a new token", body = crate::schemas::user::UserSchema),
        (status = 400, description = "The username or password is incorrect", body = crate::schemas::errors::ErrorSchema),
    ),
    tag = "auth"
)]
#[post("/login")]
pub async fn login(
    db: web::Data<DatabaseConnection>,
    payload: web::Json<LoginSchema>,
) -> impl Responder {
    // ...
}

My openapi struct

#[derive(OpenApi)]
#[openapi(
    paths(
        crate::auth::login::login
    ),
    components (
        schemas (
            crate::schemas::auth::LoginSchema,
            crate::schemas::errors::ErrorSchema,
            crate::schemas::user::UserSchema,
        )
    ),
    tags(
        (name = "auth", description = "A tag for authentication routes")
    ),
    modifiers(&SecurityAddon)
)]
pub struct ApiDoc;

My schemas

/// The schema for login request
#[derive(Debug, Serialize, Deserialize, ToSchema, Clone)]
pub struct LoginSchema {
    /// The username of the user
    #[schema(example = "Awiteb")]
    pub username: String,
    /// The password of the user
    #[schema(example = "123456")]
    pub password: String,
}
/// The schema for response error
#[derive(Debug, Serialize, Deserialize, ToSchema, Clone)]
pub struct ErrorSchema {
    /// The status code of the error
    #[schema(example = "400")]
    pub status: u16,
    /// The error message
    #[schema(example = "The username or password is incorrect")]
    pub message: String,
}
/// The schema of the user response
#[derive(Debug, Serialize, Deserialize, ToSchema, Clone)]
pub struct UserSchema {
    /// The name of the user
    #[serde(rename = "username")]
    #[schema(example = "Awiteb")]
    pub name: String,
    /// The token of the user
    #[schema(
        example = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJqdXN0IjoidGVzdCJ9.rCOJrqm0MQvxTcNyyXJdqI7smV7VNvAJZ02LslGkL78"
    )]
    pub token: String,
    #[serde(skip)]
    #[schema(hidden)]
    code: u16,
}

The errors

Errors

Resolver error at paths./api/auth/login.post.requestBody.content.application/json.schema.$ref
Could not resolve reference: Could not resolve pointer: /components/schemas/crate.schemas.auth.LoginSchema does not exist in document
Resolver error at paths./api/auth/login.post.responses.200.content.application/json.schema.$ref
Could not resolve reference: Could not resolve pointer: /components/schemas/crate.schemas.user.UserSchema does not exist in document
Resolver error at paths./api/auth/login.post.responses.400.content.application/json.schema.$ref
Could not resolve reference: Could not resolve pointer: /components/schemas/crate.schemas.errors.ErrorSchema does not exist in document
@juhaku
Copy link
Owner

juhaku commented Nov 18, 2022

The request_body and body accepts path format to allow distinction for different objects which have same name. In order to make this work at the moment there is 2 options.

 components (
       schemas (
           crate::schemas::auth::LoginSchema,
           crate::schemas::errors::ErrorSchema,
           crate::schemas::user::UserSchema,
       )
   ),

// ........... later in code
#[utoipa::path(
   context_path = "/api/auth",
   request_body = crate::schemas::auth::LoginSchema,
   responses(
       (status = 200, description = "Login successfully and return a new token", body = crate::schemas::user::UserSchema),
       (status = 400, description = "The username or password is incorrect", body = crate::schemas::errors::ErrorSchema),
   ),
   tag = "auth"
)]
  1. Option, either define schemas with as` keyword e.g:
        schemas (
            crate::schemas::auth::LoginSchema as crate::schemas::user::LoginSchema,
            crate::schemas::errors::ErrorSchema as crate::schemas::errors::ErrorSchema,
            crate::schemas::user::UserSchema as crate::schemas::user::UserSchema ,
        )
  1. Option, use direct names when defining response body or request_body e.g:
    request_body = LoginSchema,
    responses(
        (status = 200, description = "Login successfully and return a new token", body = UserSchema),

This is indeed not well documented behavior, and should most likely be revised a bit. Perhaps the whole as statement should be removed from the schemas and at least should be better documented indeed.

Related to #187

@TheAwiteb
Copy link
Author

@juhaku Thanks, its work with me now. As I understand that I have to put the name in the openapi and not the schema I have, I think this should be documented somewhere

@juhaku
Copy link
Owner

juhaku commented Jan 26, 2023

There is a new functionality coming in new release 3.0.0 described here #435 (comment). It is also documented better in the docs as well.

@juhaku juhaku closed this as completed Jan 26, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants