2

I'm building a simple REST API using Rust and Rocket. One of the endpoints accepts a POST method request, and reads a large string from the request body. I can't figure out how to do this with Rocket.

The documentation describes how to read a JSON object from the body of a POST request, as well as how to read multipart form-data, but not a raw string. Does anyone know how to do this?


Update:

Following the advice in Dave's answer below, I implemented the FromDataSimple trait to try to parse the request body. This is what I've implemented, but it has only resulted in getting a "404 Not Found" response:

struct Store {
    contents: String,
}

impl FromDataSimple for Store {
    type Error = String;

    fn from_data(req: &Request, data: Data) -> data::Outcome<Self, String> {
        let mut contents = String::new();

        if let Err(e) = data.open().take(256).read_to_string(&mut contents) {
            return Failure((Status::InternalServerError, format!("{:?}", e)));
        }

        Success(Store { contents })
    }
}

#[post("/process", format = "application/json", data = "<input>")]
fn process_store(input: Store) -> &'static str {
    "200 Okey Dokey"
}

Unfortunately when I run this and then ping it with the following request, I just get a 404 Not Found response :-(

curl -X POST -H "Content-Type: application/json" --data "{ \"contents\": \"testytest\"}"  http://localhost:8080/process

Update 2:

Actually this does work, I just forgot the mount the method into the routing handlers:

fn main() {
    rocket::ignite().mount("/", routes![index, process_store]).launch();
}
simbro
  • 3,372
  • 7
  • 34
  • 46

1 Answers1

6

Body data processing, like much of Rocket, is type directed. To indicate that a handler expects body data, annotate it with data = "", where param is an argument in the handler. The argument's type must implement the FromData trait. It looks like this, where T is assumed to implement FromData:

#[post("/", data = "<input>")]
fn new(input: T) { /* .. */ }

so you just need to create a type that implements FromDataSimple or FromData

dave
  • 62,300
  • 5
  • 72
  • 93
  • 1
    Thanks for the link Dave. Following your advice, I tried implemented the FromData trait (actually the FromDataSimple trait) but I couldn't get it to work. I've updated my question with the details. – simbro Aug 10 '20 at 12:41
  • My bad: I just forgot to mount the route handler method! – simbro Aug 10 '20 at 12:57