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