Using rust and the actix framework, I am trying to fetch a list of records from postgres and return it as JSON.
I am referencing this example code: https://github.com/actix/examples/tree/master/databases/postgres
The following are my changes. The get_users
function returns only one user because of the pop
. How do I fix this to return the entire list of users so I can return it as JSON?
pub async fn get_users(client: &Client) -> Result<User, MyError> {
client
.query("SELECT * FROM testing.users", &[])
.await?
.iter()
.map(|row| User::from_row_ref(row).unwrap())
.collect::<Vec<User>>()
.pop()
.ok_or(MyError::NotFound)
}
Try this:
pub async fn get_users(client: &Client) -> Result<Vec<User>, MyError> {
let res = client
.query("SELECT * FROM testing.users", &[])
.await?
.iter()
.map(|row| User::from_row_ref(row).unwrap())
.collect::<Vec<User>>();
Ok(res)
}
We changed the return type from Result<User, MyError>
to Result<Vec<User>, MyError>
.
Let's follow what we changed in the function implementation. The result of collect()
is Vec<User>
.
In your piece of code, the pop()
function returns an Option
, which will be None
if the vector is empty. In that case you convert the None
to an error (via ok_or()
).
Now the calls to pop()
and ok_or()
become redundant.
Since your function returns a Result
, you need to manually wrap the Vec<User>
that comes from collect()
in a Result::Ok
(remember, the ok_or()
did that for you - in the case of Some
, it would create a Result::Ok
).