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,12 +2,17 @@ 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")
|
||||
.fetch_all(pool)
|
||||
.await
|
||||
.unwrap()
|
||||
// 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()
|
||||
}
|
||||
|
||||
// Inserts a new post to the database
|
||||
|
|
|
@ -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…
Reference in a new issue