-
Notifications
You must be signed in to change notification settings - Fork 27
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
How to use arangors with a web server #10
Comments
Thank you for sharing your experience with us. The Due to the orphan rule of rust, we cannot implement any The current solution can be:
I personally recommend the third solution as it's simple and the usage of But well, I should consider just adding a Have a nice day. |
Another solution could be using May your beard grow ever longer. |
Hey guys ! Wow for your answer @fMeow , Thank you so much to take the time to explain. I am learning a lot right now ! I'll give a try to Arc as you suggest. I will also try Rd2d @inzanez ! Actually my code is directly inspired by the example for authentication service in the Actix-web repo example. I had some R2d2 and I was looking for its implementation for Arangors but I didn't find it. Thank you so much guys ! |
@arn-the-long-beard you should find it using |
Thank you ! I'll come back once I have implemented everything :) |
Okay, I got some issues still, héhé :) When trying Arc, the compiler gives me 2 errors. Here is the code . let conn = Connection::establish_jwt("http://localhost:8529", "USER", "BEST PASSWORDEVER").unwrap();
let db= Arc::new(conn.db("test_db").unwrap()) ;
let mut server = HttpServer::new(move|| {
App::new()
.data(db)
.wrap(Logger::default())
.service(
web::scope("/api")
.service(
web::resource("/auth")
.route(web::post().to(auth::login))
),
)
}); Then I got 2 errors. I understand the sens of the second that explains that the value lives too short. How can I make it live longer ? For the first error, it seems because of missing traits. I do not understand the Fn closure message so.
And
Whats is the thing I am missing there ? |
Wow, it's my first time that I heard of As for the compiler error on life-time, this is deliberately designed that a So the solution is simple, wrap conn into let conn = Connection::establish_jwt("http://localhost:8529", "USER", "BEST PASSWORDEVER").unwrap();
let conn = Arc::new(conn);
let mut server = HttpServer::new(move|| {
App::new()
.data(conn)
.wrap(Logger::default())
.service(
web::scope("/api")
.service(
web::resource("/auth")
.route(web::post().to(auth::login))
),
)
}); If you care about the performance, you can wrap a tuple into let conn = Connection::establish_jwt("http://localhost:8529", "USER", "BEST PASSWORDEVER").unwrap();
let db= conn.db("test_db").unwrap() ;
let saved = Arc::new((conn, db)); Maybe the following way can bypass the compiler error about lifetime, but I am not sure. If compiles, it's certainly the most elegant way that meets your need. let db = Connection::establish_jwt("http://localhost:8529", "USER", "BEST PASSWORDEVER").unwrap().db("test_db").unwrap();
let db = Arc::new(db); |
The lastest version (v0.3.0) add |
Hey ! I was just gonna post :) I succeed to make it work with r2d2, but it is adding a lot of code that I do not understand. let manager = ArangoDBConnectionManager::new("http://localhost:8529", "user", "password", true);
let pool = r2d2::Pool::builder()
.build(manager)
.expect("Failed to create pool.");
let mut server = HttpServer::new(move || {
App::new()
.data(pool.clone())
.wrap(Logger::default())
.service(
web::scope("/api")
.service(
web::resource("/auth")
.route(web::post().to(auth::login))
),
)
}); then in my handler pub async fn login(auth_data: web::Json<AuthData>,
id: Identity, conn: web::Data<DbConnection>) -> Result<HttpResponse, ServiceError> {
let res = web::block(move || query(auth_data.into_inner(), conn)).await;
match res {
Ok(user) => {
let user_string = serde_json::to_string(&user).unwrap();
id.remember(user_string);
Ok(HttpResponse::Ok().finish())
}
Err(err) => match err {
BlockingError::Error(service_error) => Err(service_error),
BlockingError::Canceled => Err(ServiceError::InternalServerError),
},
}
} and the query fn query(auth_data: AuthData, conn: web::Data<DbConnection>) -> Result<User, ServiceError> {
let mut vars = HashMap::new();
vars.insert("email", serde_json::value::to_value(auth_data.email).unwrap());
let conn = &conn.get().unwrap();
let db = conn.db("test_db").unwrap();
let res: Result<Vec<FullUser>, failure::Error> = db.aql_bind_vars(r#"FOR u in users FILTER u.data.email == @email return u"#, vars);
// Ok(user) => Ok(user),
// Err(e) => Err(ServiceError::InternalServerError),
// };
if res.is_err() {
eprintln!("DbError: {}", res.unwrap_err());
return Err(ServiceError::InternalServerError);
}
if let Some(user) = res.unwrap().pop() {
if let Ok(matching) = verify(&user.hash, &auth_data.password) {
if matching {
return Ok(user.data.into());
}
}
}
Err(ServiceError::Unauthorized)
} Question : I used &conn instead of conn like on the actix ecample. but it works fine with just conn. What are the benefits of using R2d2 over Arangors alone ? I had to use diesel and r2d2, and I would like to limit my dependencies to the strict minimum :) I ll try again with 0.3.0 without r2d2 to see how it does looks like the code. Thank you a lot for your update 👍 |
Okay I think I got the anwser. I do not succeed to make the 0.3.0 works. I got this error every I am using the connection.
And for some reason, I got a mismatch of type between the compiler and my IDE info. I have some Future in places where I do not have them. I ll 'stick with r2d2, it actually make stuff easier :) The Future stuff is still not known for me. I need to skip it for now. Thank you a lot guys for you help, I want to help in both projects. I am not the smartest programmer in the world, but I am good at documentation and giving examples 👍 How can I help you ? :) |
Thank you so much. Reaching out is already a valuable effort to help The v0.3.0 use let conn = Connection::establish_jwt("http://localhost:8529", "USER", "BEST PASSWORDEVER").await.unwrap();
let db= conn.db("test_db").await.unwrap(); Refer to documentation when you are not sure whether a function is Also you can stick with the sync one by specified feature gate in the following way: [dependencies]
arangors = { version = "0.3", features = ["reqwest_blocking"], default-features = false } I recommend migrating to I am planning to implement |
Hello ! I''ll come back with the example code :) |
Hey guys, I was busy with some IRL stuff for the last few days. I am back. I just tried to used r2d2-arangors with the last arangors 0.3.0. It seems we need an update on the r2d2-arangors part because of dependency to 0.2.0. Here is the working code in pure 0.3.0 without r2d2. main.rs let conn = Connection::establish_jwt("http://localhost:8529", "USER", "BEST PASSWORDEVER").unwrap();
let conn = Arc::new(conn);
let mut server = HttpServer::new(move || {
App::new()
.data(conn.clone())
.wrap(Logger::default())
.service(
web::scope("/api")
.service(
web::resource("/auth")
.route(web::post().to(auth::login))
),
)
}); login.rs pub async fn login(auth_data: web::Json<AuthData>,
id: Identity, conn: web::Data<Arc<GenericConnection<ReqwestClient>>>) -> Result<HttpResponse, ServiceError> {
let query = query(auth_data.into_inner(), conn).await;
let res = web::block(move || query)
.await;
match res {
Ok(user) => {
let user_string = serde_json::to_string(&user).unwrap();
id.remember(user_string);
Ok(HttpResponse::Ok().json(user))
}
Err(err) => match err {
BlockingError::Error(service_error) => Err(service_error),
BlockingError::Canceled => Err(ServiceError::InternalServerError),
},
}
}
//
/// Query for login
async fn query(auth_data: AuthData, conn: web::Data<Arc<GenericConnection<ReqwestClient>>>) -> Result<User, ServiceError> {
let mut vars = HashMap::new();
vars.insert("email", serde_json::value::to_value(auth_data.email).unwrap());
// let conn = &conn.get().unwrap();
let db = conn.db("test_db").await.unwrap();
let res: Result<Vec<FullUser>, ClientError> = db
.aql_bind_vars(r#"FOR u in users FILTER u.data.email == @email return u"#, vars)
.await;
// Ok(user) => Ok(user),
// Err(e) => Err(ServiceError::InternalServerError),
// };
if res.is_err() {
eprintln!("DbError: {}", res.unwrap_err());
return Err(ServiceError::InternalServerError);
}
if let Some(user) = res.unwrap().pop() {
if let Ok(matching) = verify(&user.hash, &auth_data.password) {
if matching {
return Ok(user.data.into());
}
}
}
Err(ServiceError::Unauthorized)
} Observations :
New questions :) 1 ) When I try to clone "Connection" without Arc, I get this Error
What does it mean not statisfied in this context ?
Thank you a lot guys, |
I just added support for async connection pooling using mobc: Published crate is called 'mobc-arangors'. |
Hello !
First, I am huge fan of ArangoDB, and I am starting rust serisouly only now. So big thank you for having made this package ! I am very fresh on rust, like a newbie, nice contrast from my js/ts world lol
Your package is the most advanced regarding Arango driver for Rust. But it seems you might need extra help maybe.
But first, I need some help. I am trying to use Arangodb on a actix-web server that I am making. But I am getting this error message
Here is the message I am having
And here is the code that make it happen
I tried to implement it with :
impl Clone for Database { fn clone(&self) -> Self { unimplemented!() } }
But then I got
Do you know how could I handle arangors inside my web server ? I do not want to write backend in Foxx Microservice, I really need to write rust code for my stuff. Also, if you need contributors, maybe I could be one if you want. But never done it before. I just have much time available right now.
Best regards,
a man with a very long beard because the barbershop is closed due to you know lol
The text was updated successfully, but these errors were encountered: