Rust web app, how to redirect to previous url when form validation fails?

Hi,
I am used to Django framework where I could easily redirect to a previous url if required. I would simply do a return redirect(<gosomewhere>)

My typical usecase for this:

  • The user is on a User Registration page with a form.
  • User fills the form, click Ok and in the backgrourd the app sends the data to another URL endpoint that will register everything in the database and display a success message.
  • But first it validates the data, and if something is invalid, it redirect back to the User Registration page, refill the form with the previous data, along with an error message about what the problem is.

How would I do something like that in a Rust web framework that are much more minimalist? (I am learning axum right now but I don't think actix or rocket had it either when I looked into them briefly)

Here is what I did for the moment, but it really doesn't look clean to me.

  • Located at the endpoint /reg_user, I fill the form(making sure I enter some invalid data) and click Ok, it send the data to another url/handler (/register) for validation and registration in the database
  • The form is validated, but since it got error, I recreate the form(using askama templating engine) and display it again with the error message. But when I do that, notice I am not back at the original /reg_user url, I am still at the /register url.

I am sure I missed something obvious somewhere

Django is nice for hobbyist like me since it does alot of "magic" like this, but the downside is that I never learned the proper way to do that in a framework that doesn't have "batteries included" :confused:

I am doing redirects under Axum. My code generates a header and status code, then writes the response. This is the code that implements IntoResponse.

use axum::{
    body::{Bytes, Full},
    http::{header::HeaderName, status::StatusCode, HeaderValue, Response},
    response::IntoResponse,
};

impl IntoResponse for ServerQuery {
    type Body = Full<Bytes>;
    type BodyError = std::convert::Infallible;

    fn into_response(self) -> Response<Self::Body> {
        let mut res = Response::new(Full::from(self.x.output));

        *res.status_mut() = StatusCode::from_u16(self.x.status_code).unwrap();

        for (name, value) in &self.x.headers {
            res.headers_mut().insert(
                HeaderName::from_lowercase(name.as_bytes()).unwrap(),
                HeaderValue::from_str(value).unwrap(),
            );
        }
        res
    }
}

Full example here.

Hope this helps!

( The header required is location : <your url>
The status code should be 303 ( or other maybe other values ).
)

1 Like

Personally I always don't use "another URL". I think it's simpler to use the same URL to save the posted results from a form. I redirect after a successful post. Not saying my way is better, I don't know!

1 Like

I am checking out your full example and it's very enlightening for me, it is lighting up a couple of light-bulb in my brain.

It is very sensible to do that, yes. I must get rid of old habits :slight_smile: