NotFound error and add validation
This commit is contained in:
parent
de157a3b1e
commit
f30be5f451
@ -1,8 +1,8 @@
|
|||||||
CREATE TABLE IF NOT EXISTS "items" (
|
CREATE TABLE IF NOT EXISTS "items" (
|
||||||
"id" SERIAL PRIMARY KEY NOT NULL,
|
"id" SERIAL PRIMARY KEY NOT NULL,
|
||||||
"title" VARCHAR(255) NOT NULL,
|
"title" VARCHAR(255) NOT NULL,
|
||||||
"url" VARCHAR(255) NOT NULL,
|
"url" VARCHAR(2048) NOT NULL,
|
||||||
"description" VARCHAR(255),
|
"description" TEXT,
|
||||||
"created_at" timestamp(3) NOT NULL,
|
"created_at" timestamp(3) NOT NULL,
|
||||||
"updated_at" timestamp(3) NOT NULL,
|
"updated_at" timestamp(3) NOT NULL,
|
||||||
"deleted_at" timestamp(3)
|
"deleted_at" timestamp(3)
|
||||||
|
@ -21,8 +21,13 @@ pub enum Error {
|
|||||||
|
|
||||||
#[error("validation error in request body")]
|
#[error("validation error in request body")]
|
||||||
InvalidEntity(#[from] ValidationErrors),
|
InvalidEntity(#[from] ValidationErrors),
|
||||||
|
|
||||||
|
#[error("{0} not found")]
|
||||||
|
NotFound(&'static str),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub type Result<T, E = Error> = ::std::result::Result<T, E>;
|
||||||
|
|
||||||
impl IntoResponse for Error {
|
impl IntoResponse for Error {
|
||||||
fn into_response(self) -> Response {
|
fn into_response(self) -> Response {
|
||||||
#[serde_with::serde_as]
|
#[serde_with::serde_as]
|
||||||
@ -59,7 +64,7 @@ impl Error {
|
|||||||
use Error::*;
|
use Error::*;
|
||||||
|
|
||||||
match self {
|
match self {
|
||||||
Sqlx(sqlx::Error::RowNotFound) => StatusCode::NOT_FOUND,
|
NotFound(_) => StatusCode::NOT_FOUND,
|
||||||
Sqlx(_) | Anyhow(_) => StatusCode::INTERNAL_SERVER_ERROR,
|
Sqlx(_) | Anyhow(_) => StatusCode::INTERNAL_SERVER_ERROR,
|
||||||
InvalidEntity(_) => StatusCode::UNPROCESSABLE_ENTITY,
|
InvalidEntity(_) => StatusCode::UNPROCESSABLE_ENTITY,
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,9 @@
|
|||||||
use chrono::NaiveDateTime;
|
use chrono::NaiveDateTime;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use sqlx::PgPool;
|
use sqlx::PgPool;
|
||||||
|
use validator::Validate;
|
||||||
|
|
||||||
|
use crate::error::{Error, Result};
|
||||||
|
|
||||||
#[derive(Debug, Serialize, Deserialize)]
|
#[derive(Debug, Serialize, Deserialize)]
|
||||||
pub struct Item {
|
pub struct Item {
|
||||||
@ -13,17 +16,26 @@ pub struct Item {
|
|||||||
deleted_at: Option<NaiveDateTime>,
|
deleted_at: Option<NaiveDateTime>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Deserialize)]
|
#[derive(Debug, Deserialize, Validate)]
|
||||||
pub struct CreateItem {
|
pub struct CreateItem {
|
||||||
|
#[validate(length(max = 255))]
|
||||||
title: String,
|
title: String,
|
||||||
|
#[validate(url)]
|
||||||
url: String,
|
url: String,
|
||||||
|
#[validate(length(max = 524288))]
|
||||||
description: Option<String>,
|
description: Option<String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn get_item(pool: PgPool, id: i32) -> sqlx::Result<Item> {
|
pub async fn get_item(pool: PgPool, id: i32) -> Result<Item> {
|
||||||
sqlx::query_as!(Item, "SELECT * FROM items WHERE id = $1", id)
|
sqlx::query_as!(Item, "SELECT * FROM items WHERE id = $1", id)
|
||||||
.fetch_one(&pool)
|
.fetch_one(&pool)
|
||||||
.await
|
.await
|
||||||
|
.map_err(|error| {
|
||||||
|
if let sqlx::error::Error::RowNotFound = error {
|
||||||
|
return Error::NotFound("item");
|
||||||
|
}
|
||||||
|
Error::Sqlx(error)
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn get_items(pool: PgPool) -> sqlx::Result<Vec<Item>> {
|
pub async fn get_items(pool: PgPool) -> sqlx::Result<Vec<Item>> {
|
||||||
@ -32,8 +44,9 @@ pub async fn get_items(pool: PgPool) -> sqlx::Result<Vec<Item>> {
|
|||||||
.await
|
.await
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn create_item(pool: PgPool, payload: CreateItem) -> sqlx::Result<Item> {
|
pub async fn create_item(pool: PgPool, payload: CreateItem) -> Result<Item> {
|
||||||
sqlx::query_as!(
|
payload.validate()?;
|
||||||
|
Ok(sqlx::query_as!(
|
||||||
Item,
|
Item,
|
||||||
"INSERT INTO items (
|
"INSERT INTO items (
|
||||||
title, url, description, created_at, updated_at
|
title, url, description, created_at, updated_at
|
||||||
@ -45,5 +58,5 @@ pub async fn create_item(pool: PgPool, payload: CreateItem) -> sqlx::Result<Item
|
|||||||
payload.description
|
payload.description
|
||||||
)
|
)
|
||||||
.fetch_one(&pool)
|
.fetch_one(&pool)
|
||||||
.await
|
.await?)
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user