how to make okapi comment rocket return Object
Closed this issue · 1 comments
I am using rust rocket as my web server, this is the code looks like:
/// # search the template list
///
/// return different type of template
#[openapi(tag = "template")]
#[get("/v1/list?<query..>")]
pub fn list(query: TemplateRequest) -> content::RawJson<String> {
let contents = get_template_list(query.template_type, query.name);
return box_rest_response(contents);
}
this code works fine. Now I facing a problem is that the rust rocket return raw json, the client side could not know the return content structure. it only show a json string in swagger:
the client did not know what the response content is. I have read the the rust rocket official document still did not figure out what should I do to return the entity structure. I have tried like this:
pub fn list(query: TemplateRequest) -> Result<Vec<TemplateResponse>, String> {
let contents = get_template_list(query.template_type, query.name);
return Ok(contents);
}
the compiler shows:
error[E0277]: the trait bound `std::vec::Vec<TemplateResponse>: Responder<'_, '_>` is not satisfied
--> src/biz/template/bill_book_template_controller.rs:28:1
|
28 | #[openapi(tag = "账本模版")]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Responder<'_, '_>` is not implemented for `std::vec::Vec<TemplateResponse>`
|
= help: the following implementations were found:
<std::vec::Vec<u8> as Responder<'r, 'static>>
= note: required because of the requirements on the impl of `Responder<'_, '_>` for `Result<std::vec::Vec<TemplateResponse>, std::string::String>`
note: required by a bound in `rocket_okapi::response::OpenApiResponder::responses`
--> /Users/xiaoqiangjiang/.cargo/git/checkouts/okapi-727e9b4b9c217cbb/65244f0/rocket-okapi/src/response/mod.rs:10:41
|
10 | pub trait OpenApiResponder<'a, 'r: 'a>: rocket::response::Responder<'a, 'r> {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `rocket_okapi::response::OpenApiResponder::responses`
= note: this error originates in the attribute macro `openapi` (in Nightly builds, run with -Z macro-backtrace for more info)
I also tried to implement like this:
impl<'r> Responder<'r, 'static> for Vec<TemplateResponse> {
fn respond_to(self, _: &'r Request<'_>) -> response::Result<'static> {
// Convert object to json
let body = serde_json::to_string(&self).unwrap();
Response::build()
.sized_body(body.len(), std::io::Cursor::new(body))
.header(rocket::http::ContentType::JSON)
.status(rocket::http::Status::new(self.http_status_code))
.ok()
}
}
seems did not work. I have tried this:
pub fn list(query: TemplateRequest) -> Result<content::RawJson<String>, String> {
let contents = get_template_list(query.template_type, query.name);
return Ok(box_rest_response(contents));
}
it works but still could not show the response structure at client side.
The easiest way to return JSON is to use Json<...>
with a struct.
For example:
okapi/examples/json-web-api/src/main.rs
Lines 84 to 91 in 65244f0
Then you can add the structure and documentation like this:
okapi/examples/json-web-api/src/main.rs
Lines 74 to 82 in 65244f0
With RawJson
you can return any JSON, so there is no way to know what the structure is of the JSON at compile time.