I am learning using rust to write a rest api to update some record. I have defined a rust(v1.69.0
) rocket api like this:
#[macro_use] extern crate rocket;
use rocket::{serde::json::Json, response::content};
use rust_wheel::common::util::model_convert::box_rest_response;
use rocket::serde::Deserialize;
use rocket::serde::Serialize;
#[put("/test", data = "<request>")]
pub fn flush_render_result(
request: Json<RenderResultRequest>
) -> content::RawJson<String> {
let req = request;
return box_rest_response("ok");
}
#[launch]
fn rocket() -> _ {
rocket::build().mount("/", routes![flush_render_result])
}
#[derive(Debug, PartialEq, Eq, Deserialize, Serialize)]
#[allow(non_snake_case)]
pub struct RenderResultRequest {
pub gen_status: i32,
pub id: i64,
}
this is the Cargo.toml
:
[package]
name = "rust-learn"
version = "0.1.0"
edition = "2018"
[dependencies]
serde = { version = "1.0.64", features = ["derive"] }
serde_json = "1.0.64"
rocket = { version = "0.5.0-rc.2", features = ["json"]}
rust_wheel = { git = "https://github.com/jiangxiaoqiang/rust_wheel.git", branch = "diesel2.0" }
and this is the Rocket.toml
:
[release]
workers = 5
log_level = "normal"
keep_alive = 5
port = 11016
[debug]
port = 11016
when I use the command to request the api in macOS 13.2 terminal:
> curl -X PUT http://127.0.0.1:11016/test -H "Content-Type: application/json" -H "x-access-token:1" -H "app-id:1" -H "user-id:1" -H "x-request-id:1" -H "device-id:1" -d "{
"id": 1,
"gen_status": 1
}"
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>400 Bad Request</title>
</head>
<body align="center">
<div role="main" align="center">
<h1>400: Bad Request</h1>
<p>The request could not be understood by the server due to malformed syntax.</p>
<hr />
</div>
<div role="contentinfo" align="center">
<small>Rocket</small>
</div>
</body>
</html>%
why did this happen? what should I do to fixed this issue? I have already add the "" for keys, why still tell me this error? The server log look like this:
📬 Routes:
>> (flush_render_result) PUT /test
📡 Fairings:
>> Shield (liftoff, response, singleton)
🛡️ Shield:
>> X-Content-Type-Options: nosniff
>> Permissions-Policy: interest-cohort=()
>> X-Frame-Options: SAMEORIGIN
🚀 Rocket has launched from http://127.0.0.1:11016
PUT /test application/json:
>> Matched: (flush_render_result) PUT /test
>> Data guard `Json < RenderResultRequest >` failed: Parse("{\n id: 1,\n gen_status: 1\n}", Error("key must be a string", line: 2, column: 5)).
>> Outcome: Failure
>> No 400 catcher registered. Using Rocket default.
>> Response succeeded.
I have tried to remove the space, still could not work:
curl -X PUT http://127.0.0.1:8000/cv/gen/v1/result -H "Content-Type: application/json" -H "x-access-token:1" -H "app-id:1" -H "user-id:1" -H "x-request-id:1" -H "device-id:1" -d "{"id": 1,"gen_status": 1}"
You failed to properly escape the "
in your curl invocation, so the shell consumed them resulting in a payload of
{
id: 1,
gen_status: 1
}
instead of the valid JSON
{
"id": 1,
"gen_status": 1
}
Note the difference in quoting of the keys.
to fix it you can invoke curl with escaped quotes (\"
) inside the json or by using different outer quotes like this:
curl -X PUT http://127.0.0.1:11016/test [...] -d '{"id": 1, "gen_status": 1}'