my "main" file
mod router;
mod student;
use std::sync::Arc;
use crate::router::init_router;
use crate::router::Memory;
use actix_web::{App, HttpServer};
#[actix_web::main]
async fn main() -> std::io::Result<()> {
dotenv::dotenv().ok();
let repo = Arc::new(Memory::repository());
let host = std::env::var("SERVER.HOST").unwrap_or("127.0.0.1".to_string());
let port = std::env::var("SERVER.PORT").unwrap_or("8080".to_string());
let url = format!("{}:{}", host, port);
println!("url: {}", &url);
HttpServer::new(move || {
App::new()
.data(repo.clone()) // shared
.configure(init_router)
})
.bind(&url)?
.run()
.await
}
my file: "router.rs"
use std::sync::Arc;
use crate::student::Student;
use actix_web::{get, web, HttpResponse, Responder};
use serde::{Serialize, Deserialize};
#[derive(Serialize, Deserialize)]
pub struct Memory {
pub students: Vec<Student>,
}
impl Memory {
fn new() -> Self {
Memory {
students: Vec::new(),
}
}
pub fn repository() -> Self{
Self {
students: vec![
{Student::new("1".to_string(), "Daniel".to_string(), 19)},
{Student::new("2".to_string(), "Lucia".to_string(), 17)},
{Student::new("3".to_string(), "Juan".to_string(), 14)}
]
}
}
}
#[get("/studen/list/all")]
async fn list_all(repo: web::Data<Arc<Memory>>) -> impl Responder {
HttpResponse::Ok().json(repo)
}
pub fn init_router(config: &mut web::ServiceConfig) {
config.service(list_all);
}
and my file: "student.rs"
use serde::{Serialize, Deserialize};
#[derive(Serialize, Deserialize)]
pub struct Student{
pub id: String,
pub nombre: String,
pub calificacion: u32,
}
impl Student{
pub fn new(id: String, nombre: String, calificacion: u32) -> Self{
Self{id, nombre, calificacion}
}
}
so I want to show all students in a json via the following path: 127.0.0.1:3000/student/list/all
but i have the following error
| HttpResponse::Ok().json(repo)
| ^^^^ the traitSerialize
is not implemented forData<Arc<Memory>>
I still can't pass this data by parameter of a GET method, I need a little help please to display it in json. It is necessary because later I will need this data by parameter to add or remove.
(Note that you typed #[get("/studen/list/all")]
instead of #[get("/student/list/all")]
in your original code.)
You don't want to serialize the Data<Arc<Memory>>
to JSON, you only want to serialize the Memory
. To do so, you can dereference the Data<Arc<Memory>>
to get an Arc<Arc<Memory>>
, then dereference the Arc
s twice to get a Memory
. Then, you add a reference as to not require cloning the resulting Memory
. So, you replace
HttpResponse::Ok().json(repo)
with
HttpResponse::Ok().json(&***repo)
However, Data
is already a wrapper around an Arc
, so no Arc<Memory>
in the is required. If you want to edit the Memory
eventually, you'll have to add a Mutex
inside. So, you'll have to obtain a lock on repo
before serializing it.