murar8 / axum_typed_multipart

Type safe multipart/form-data handling for axum.
77 stars 13 forks source link

Field name with square brackets #10

Open pnevyk opened 1 year ago

pnevyk commented 1 year ago

It seems that it's a common practice to use trailing square brackets (e.g., names[]=Foo) when one wants to send multiple values with the same field name. For examples, here is the PHP manual for uploading multiple files and I found the same recommendations during internet search (1, 2).

This would mean that for the following program:

use axum::{http::StatusCode, routing::post, Router};
use axum_typed_multipart::{TryFromMultipart, TypedMultipart};

#[derive(TryFromMultipart)]
struct RequestData {
    names: Vec<String>,
}

async fn handler(TypedMultipart(RequestData { names }): TypedMultipart<RequestData>) -> StatusCode {
    println!("names = {:?}", names);
    StatusCode::OK
}

#[tokio::main]
async fn main() {
    // build our application with a single route
    let app = Router::new().route("/", post(handler));

    // run it with hyper on localhost:3000
    axum::Server::bind(&"0.0.0.0:3000".parse().unwrap())
        .serve(app.into_make_service())
        .await
        .unwrap();
}

the following request:

curl -X POST --form "names[]=Foo" --form "names[]=Bar" http://localhost:3000

prints names = ["Foo", "Bar"].

Rocket and its FromForm derive trait supports this.

I think that supporting just names[] is a good start, later it would be nice to support things like names[0] (explicit ordering) or even names[foo] -> HashMap.

If this is desired feature, I could try to send a PR. In that case and advice and pointers into the codebase would be appreciated.

murar8 commented 1 year ago

Hi, I took a look at the Rocket docs and it looks like a really cool idea but it would be quite a bit of work so I'm not sure I will be able to work on it at the moment.

murar8 commented 1 year ago

Rocket also has support for nested structs which is very nice so I guess it would be easier to add support for everything at once. Let me look into it as soon as I have some free time and see if it's doable

pnevyk commented 1 year ago

Sure, take your time, it's not a blocker for me. Thanks!

The advanced features that Rocket supports are nice, but I wonder how much they are useful in practice.

murar8 commented 1 year ago

Yeah that's a good point, I guess we could start with the names[] and names[0] convention for arrays, that would probably cover 99% of use cases

gaurav-bagga commented 9 months ago

Nested structs too please. Sample use case, perhaps possible.

struct Student {
  name: String,
  avatar: FieldData<Bytes>
}

struct School {
   name: String,
   students: Vec<Student>,
   avatar: FieldData<Bytes>
}