Tidying up routes, query parameters for posts, better database api
This commit is contained in:
		
							parent
							
								
									204ed8ec41
								
							
						
					
					
						commit
						4fc00eaf23
					
				
					 5 changed files with 39 additions and 20 deletions
				
			
		|  | @ -2,9 +2,14 @@ use crate::routes::{NewPost, Post}; | |||
| use log::warn; | ||||
| use sqlx::SqlitePool; | ||||
| 
 | ||||
| // Gets all posts from the database
 | ||||
| pub async fn db_get_posts(pool: &SqlitePool) -> Vec<Post> { | ||||
|     sqlx::query_as!(Post, "SELECT * FROM posts") | ||||
| // Gets the latest posts from the database, ordered by created_at
 | ||||
| pub async fn db_get_latest_posts(pool: &SqlitePool, limit: i64, offset: i64) -> Vec<Post> { | ||||
|     sqlx::query_as!( | ||||
|         Post, | ||||
|         "SELECT * FROM posts ORDER BY created_at DESC LIMIT ? OFFSET ?", | ||||
|         limit, | ||||
|         offset | ||||
|     ) | ||||
|     .fetch_all(pool) | ||||
|     .await | ||||
|     .unwrap() | ||||
|  |  | |||
|  | @ -1,7 +1,3 @@ | |||
| // use crate::{
 | ||||
| //     config::{DAYS_VALID, JWT_SECRET},
 | ||||
| //     Claims,
 | ||||
| // };
 | ||||
| use jsonwebtoken::{ | ||||
|     decode, encode, errors::Result as JwtResult, DecodingKey, EncodingKey, Header, Validation, | ||||
| }; | ||||
|  |  | |||
|  | @ -1,7 +1,7 @@ | |||
| use crate::db::{db_get_posts, db_new_post}; | ||||
| use crate::db::{db_get_latest_posts, db_new_post}; | ||||
| use crate::ServerState; | ||||
| 
 | ||||
| use actix_web::web::Data; | ||||
| use actix_web::web::{Data, Query}; | ||||
| use actix_web::{get, post, web::Json, HttpResponse, Responder, Result}; | ||||
| use log::info; | ||||
| use serde::{Deserialize, Serialize}; | ||||
|  | @ -27,6 +27,7 @@ pub struct Post { | |||
|     pub updated_at: chrono::NaiveDateTime, | ||||
| } | ||||
| 
 | ||||
| /// The user as it is stored in the database, with all the related metadata
 | ||||
| #[derive(Debug, Serialize, Deserialize, Clone, FromRow)] | ||||
| pub struct User { | ||||
|     pub id: i64, | ||||
|  | @ -36,11 +37,30 @@ pub struct User { | |||
|     pub updated_at: chrono::NaiveDateTime, | ||||
| } | ||||
| 
 | ||||
| #[get("/posts")] | ||||
| pub async fn get_posts(state: Data<ServerState>) -> Result<impl Responder> { | ||||
|     Ok(HttpResponse::Ok().json(db_get_posts(&state.pool).await)) | ||||
| // These look like /posts?limit=10&offset=20 in the URL
 | ||||
| // Note that these are optional
 | ||||
| /// Query parameters for the /posts endpoint
 | ||||
| #[derive(Debug, Serialize, Deserialize)] | ||||
| struct QueryParams { | ||||
|     limit: Option<i64>, | ||||
|     offset: Option<i64>, | ||||
| } | ||||
| 
 | ||||
| /// Gets all posts from the database, query parameters are optional
 | ||||
| /// If limit is not specified, it defaults to a sane value
 | ||||
| #[get("/posts")] | ||||
| pub async fn get_posts( | ||||
|     query: Query<QueryParams>, | ||||
|     state: Data<ServerState>, | ||||
| ) -> Result<impl Responder> { | ||||
|     if let (Some(lim), Some(ofs)) = (query.limit, query.offset) { | ||||
|         return Ok(HttpResponse::Ok() | ||||
|             .json(db_get_latest_posts(&state.pool, std::cmp::min(lim, 30), ofs).await)); | ||||
|     } | ||||
|     Ok(HttpResponse::Ok().json(db_get_latest_posts(&state.pool, 30, 0).await)) | ||||
| } | ||||
| 
 | ||||
| /// Creates a new post, requires a token in release mode
 | ||||
| #[post("/posts")] | ||||
| pub async fn new_post(new_post: Json<NewPost>, state: Data<ServerState>) -> Result<impl Responder> { | ||||
|     return match db_new_post(new_post.into_inner(), &state.pool).await { | ||||
|  |  | |||
|  | @ -74,10 +74,6 @@ pub async fn register( | |||
| 
 | ||||
| #[post("/login")] | ||||
| pub async fn login(data: Json<LoginData>, state: Data<ServerState>) -> Result<impl Responder> { | ||||
|     // let q = "SELECT password FROM users WHERE username = ?";
 | ||||
|     // let query = sqlx::query(q).bind(&data.username);
 | ||||
|     // let result = query.fetch_one(&state.pool).await.ok();
 | ||||
| 
 | ||||
|     let uname = data.username.clone(); | ||||
|     let q = sqlx::query!("SELECT password FROM users WHERE username = ?", uname) | ||||
|         .fetch_one(&state.pool) | ||||
|  |  | |||
|  | @ -35,10 +35,12 @@ impl ServerState { | |||
| async fn debug_setup(pool: &SqlitePool) -> Result<(), sqlx::Error> { | ||||
|     use sqlx::query; | ||||
| 
 | ||||
|     query!("INSERT INTO users (username, password) VALUES ('testuser', 'testpassword')",) | ||||
|     // Or ignore is just to silence the error if the user already exists
 | ||||
|     query!("INSERT OR IGNORE INTO users (username, password) VALUES ('testuser', 'testpassword')",) | ||||
|         .execute(pool) | ||||
|         .await?; | ||||
| 
 | ||||
|     // This requires that the user with id 1 exists in the user table
 | ||||
|     query!("INSERT INTO posts (user_id, content) VALUES (1, 'Hello world!')",) | ||||
|         .execute(pool) | ||||
|         .await?; | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Imbus
						Imbus