Search code examples
jsonrustrust-rocketsea-orm

How to create rocket + sea orm correct json response?


I am new in rust and have problems with correct JSON response in the Rocket framework.

I have Entity that was created by sea-ql I just added [serde(crate = "rocket::serde")] and use rocket::serde::{Deserialize, Serialize};

use sea_orm::entity::prelude::*;
use rocket::serde::{Deserialize, Serialize};

#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq, Serialize, Deserialize)]
#[serde(crate = "rocket::serde")]
#[sea_orm(table_name = "terminology_dosage_form")]
pub struct Model {
    #[sea_orm(primary_key, auto_increment = false)]
    pub id: Uuid,
    pub code: Uuid,
    pub snomed_code: Option<String>,
    pub name: Option<String>,
    pub display_name: Option<String>,
    pub created_at: DateTimeWithTimeZone,
    pub updated_at: DateTimeWithTimeZone,
}

#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]
pub enum Relation {}

impl ActiveModelBehavior for ActiveModel {}

and handler that I want to return JSON from that model entity

use entities::{prelude::*, *};
    .....
use entities::{prelude::*, *};
.....
#[get("/forms")]
async fn bakeries(db: &State<DatabaseConnection>) -> Result<Json<Vec<DosageForm>>, ErrorResponder> {
let db = db as &DatabaseConnection;

let bakeries = DosageForm::find()
    .all(db)
    .await?
    .into_json()
    .await?;

Ok(Json(bakeries))

}

and receive errors when trying to run the rocket with cargo run

error[E0599]: no method named `into_json` found for struct `Vec<dosage_form::Model>` in the current scope
  --> src/main.rs:30:10
   |
30 |         .into_json()
   |          ^^^^^^^^^ method not found in `Vec<dosage_form::Model>`

error[E0282]: type annotations needed
  --> src/main.rs:24:54
   |
24 | async fn bakeries(db: &State<DatabaseConnection>) -> Result<Json<Vec<DosageForm>>, ErrorResponder> {
   |                                                      ^^^^^^
   |
help: consider giving `___responder` an explicit type
   |
24 | async fn bakeries(db: &State<DatabaseConnection>) -> Result: _<Json<Vec<DosageForm>>, ErrorResponder> {
   |                                                            +++

due to this code I gave to use into before await https://www.sea-ql.org/SeaORM/docs/basic-crud/json/

but when I use .into_json().all(db).await?; I received the error

error[E0599]: no method named `into_json` found for opaque type `impl std::future::Future<Output = Result<Vec<<dosage_form::Entity as sea_orm::EntityTrait>::Model>, sea_orm::DbErr>>` in the current scope
  --> src/main.rs:29:10
   |
29 |         .into_json()
   |          ^^^^^^^^^ method not found in `impl std::future::Future<Output = Result<Vec<<dosage_form::Entity as sea_orm::EntityTrait>::Model>, sea_orm::DbErr>>`

error[E0282]: type annotations needed
  --> src/main.rs:24:54
   |
24 | async fn bakeries(db: &State<DatabaseConnection>) -> Result<Json<Vec<DosageForm>>, ErrorResponder> {
   |                                                      ^^^^^^
   |
help: consider giving `___responder` an explicit type
   |
24 | async fn bakeries(db: &State<DatabaseConnection>) -> Result: _<Json<Vec<DosageForm>>, ErrorResponder> {
   |  


                                                    +++

Solution

  • As a newbie I was also struggling for quite a while. What works for me is the following: I use the serialization functionality from rocket for the entity:

    use sea_orm::entity::prelude::*;
    use rocket::serde::Serialize;
    
    #[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq, Serialize)]
    #[serde(crate = "rocket::serde")]
    #[sea_orm(table_name = "materialtype")]
    pub struct Model {
        #[sea_orm(primary_key)]
        pub id: i32,
        pub name: String,
    }
    

    Then you can do the following in your response:

    use materialdb_backend::entities::prelude::*;
    use materialdb_backend::entities::*;
    use materialdb_backend::setup::*;
    use rocket::serde::json::Json;
    use rocket::*;
    use sea_orm::*;
    #[get("/materialtypes")]
    async fn materialtypes(db: &State<DatabaseConnection>) -> Json<Vec<materialtype::Model>> {
        let db = db as &DatabaseConnection;
        let material_types = Materialtype::find().all(db).await.unwrap();
        Json(material_types)
    }
    

    I skipped the error handling here but I hope you get the idea...