Allow specifying query, limit and page when hitting /api/users

This is needed to introduce pagination and search in our admin panel.
This commit is contained in:
Antonio Scandurra 2022-06-13 17:30:01 +02:00
parent b1e8e81513
commit 49d7b4bc12
2 changed files with 28 additions and 7 deletions

View file

@ -70,8 +70,25 @@ pub async fn validate_api_token<B>(req: Request<B>, next: Next<B>) -> impl IntoR
Ok::<_, Error>(next.run(req).await) Ok::<_, Error>(next.run(req).await)
} }
async fn get_users(Extension(app): Extension<Arc<AppState>>) -> Result<Json<Vec<User>>> { #[derive(Debug, Deserialize)]
let users = app.db.get_all_users().await?; struct GetUsersQueryParams {
query: Option<String>,
page: Option<u32>,
limit: Option<u32>,
}
async fn get_users(
Query(params): Query<GetUsersQueryParams>,
Extension(app): Extension<Arc<AppState>>,
) -> Result<Json<Vec<User>>> {
let limit = params.limit.unwrap_or(100);
let users = if let Some(query) = params.query {
app.db.fuzzy_search_users(&query, limit).await?
} else {
app.db
.get_all_users(params.page.unwrap_or(0), limit)
.await?
};
Ok(Json(users)) Ok(Json(users))
} }

View file

@ -17,7 +17,7 @@ pub trait Db: Send + Sync {
email_address: Option<&str>, email_address: Option<&str>,
admin: bool, admin: bool,
) -> Result<UserId>; ) -> Result<UserId>;
async fn get_all_users(&self) -> Result<Vec<User>>; async fn get_all_users(&self, page: u32, limit: u32) -> Result<Vec<User>>;
async fn fuzzy_search_users(&self, query: &str, limit: u32) -> Result<Vec<User>>; async fn fuzzy_search_users(&self, query: &str, limit: u32) -> Result<Vec<User>>;
async fn get_user_by_id(&self, id: UserId) -> Result<Option<User>>; async fn get_user_by_id(&self, id: UserId) -> Result<Option<User>>;
async fn get_users_by_ids(&self, ids: Vec<UserId>) -> Result<Vec<User>>; async fn get_users_by_ids(&self, ids: Vec<UserId>) -> Result<Vec<User>>;
@ -141,9 +141,13 @@ impl Db for PostgresDb {
.map(UserId)?) .map(UserId)?)
} }
async fn get_all_users(&self) -> Result<Vec<User>> { async fn get_all_users(&self, page: u32, limit: u32) -> Result<Vec<User>> {
let query = "SELECT * FROM users ORDER BY github_login ASC"; let query = "SELECT * FROM users ORDER BY github_login ASC LIMIT $1 OFFSET $2";
Ok(sqlx::query_as(query).fetch_all(&self.pool).await?) Ok(sqlx::query_as(query)
.bind(limit)
.bind(page * limit)
.fetch_all(&self.pool)
.await?)
} }
async fn fuzzy_search_users(&self, name_query: &str, limit: u32) -> Result<Vec<User>> { async fn fuzzy_search_users(&self, name_query: &str, limit: u32) -> Result<Vec<User>> {
@ -1665,7 +1669,7 @@ pub mod tests {
} }
} }
async fn get_all_users(&self) -> Result<Vec<User>> { async fn get_all_users(&self, _page: u32, _limit: u32) -> Result<Vec<User>> {
unimplemented!() unimplemented!()
} }