Rust API - Criando a rota de get by id com rust - Part V
Primeiramente iremos lidar com o nosso arquivo de services, onde iremos importar o nosso Path, para fazer o recenhecimento a partir dele o id ou uuid no caso, que trabalharemos a nossa query de busca:
use actix_web::{
get,
post,
web::{
Data,
Json,
scope,
Query,
Path,
ServiceConfig
},
HttpResponse,
Responder
};
E iremos escrever abaixo a nossa função:
#[get("/tasks/{id}")]
async fn get_task_by_id(path: Path<uuid::Uuid>, data: Data<AppState>) -> impl Responder {
}
Dentro do escopo da nossa função, nós iremos começar a verificar a partir da nossa url o task_id, ou o uuid da nossa url:
#[get("/tasks/{id}")]
async fn get_task_by_id(path: Path<uuid::Uuid>, data: Data<AppState>) -> impl Responder {
let task_id = path.into_inner();
}
Próximo ponto é fazer a nossa query e o tratamento de erro:
#[get("/tasks/{id}")]
async fn get_task_by_id(path: Path<uuid::Uuid>, data: Data<AppState>) -> impl Responder {
let task_id = path.into_inner();
let query_result = sqlx
::query_as!(TaskModel, "SELECT * FROM tasks WHERE id = $1", task_id)
.fetch_one(&data.db).await;
match query_result {
Ok(task) => {
let task_note = json!({
"status": "success",
"task": task
});
return HttpResponse::Ok().json(task_note);
}
Err(error) => {
return HttpResponse::InternalServerError().json(
json!({
"status": "error",
"message": format!("{:?}", error)
})
)
}
}
}
Por fim, adicionar ela junto a nossa config
pub fn config(conf: &mut ServiceConfig) {
let scope = scope("/api")
.service(health_checker)
.service(create_task)
.service(get_all_tasks)
.service(get_task_by_id);
conf.service(scope);
}
O nosso arquivo no final fica assim:
src/services.rs
use crate::{
model::TaskModel,
schema:: {
CreateTaskSchema,
FilterOptions
}, AppState
};
use actix_web::{
get,
post,
web::{
Data,
Json,
scope,
Query,
Path,
ServiceConfig
},
HttpResponse,
Responder
};
use serde_json::json;
#[get("/healthchecker")]
async fn health_checker() -> impl Responder {
const MESSAGE: &str = "Health check API is up and running smoothly.";
HttpResponse::Ok().json(json!({"status": "success", "message": MESSAGE }))
}
#[post("/task")]
async fn create_task(body: Json<CreateTaskSchema>, data: Data<AppState>) -> impl Responder {
match
sqlx
::query_as!(
TaskModel,
"INSERT INTO tasks (title, content) VALUES ($1, $2)
RETURNING * ",
body.title.to_string(),
body.content.to_string()
)
.fetch_one(&data.db)
.await {
Ok(task) => {
let task_note = json!({
"status": "success",
"task": task
});
return HttpResponse::Ok().json(task_note);
}
Err(error) => {
return HttpResponse::InternalServerError().json(
json!({
"status": "error",
"message": format!("{:?}", error)
})
)
}
}
}
#[get("/tasks")]
pub async fn get_all_tasks(opts: Query<FilterOptions>, data: Data<AppState>) -> impl Responder {
let limit = opts.limit.unwrap_or(10);
let offset = (opts.page.unwrap_or(1) - 1) * limit;
match
sqlx
::query_as!(
TaskModel,
"SELECT * FROM tasks ORDER by id LIMIT $1 OFFSET $2",
limit as i32,
offset as i32
)
.fetch_all(&data.db)
.await {
Ok(task) => {
let task_note = json!({
"status": "success",
"task": task
});
return HttpResponse::Ok().json(task_note);
}
Err(error) => {
return HttpResponse::InternalServerError().json(
json!({
"status": "error",
"message": format!("{:?}", error)
})
)
}
}
}
#[get("/tasks/{id}")]
async fn get_task_by_id(path: Path<uuid::Uuid>, data: Data<AppState>) -> impl Responder {
let task_id = path.into_inner();
let query_result = sqlx
::query_as!(TaskModel, "SELECT * FROM tasks WHERE id = $1", task_id)
.fetch_one(&data.db).await;
match query_result {
Ok(task) => {
let task_note = json!({
"status": "success",
"task": task
});
return HttpResponse::Ok().json(task_note);
}
Err(error) => {
return HttpResponse::InternalServerError().json(
json!({
"status": "error",
"message": format!("{:?}", error)
})
)
}
}
}
pub fn config(conf: &mut ServiceConfig) {
let scope = scope("/api")
.service(health_checker)
.service(create_task)
.service(get_all_tasks)
.service(get_task_by_id);
conf.service(scope);
}
Para testar, nós iremos criar uma nova task:
curl --request POST \
--url http://localhost:8080/api/task \
--header 'Content-Type: application/json' \
--data '{
"title": "title test2",
"content": "content test"
}'
Ele deve me gerar essa task onde eu irei pegar o nosso id:
{
"status": "success",
"task": {
"content": "content test",
"created_at": "2023-06-10T15:05:53.710564Z",
"id": "d6b52611-8117-43d3-a8f6-56732ac94bd5",
"title": "title test2"
}
}
E podemos testar da seguinte forma:
curl --request GET \
--url http://localhost:8080/api/tasks/d6b52611-8117-43d3-a8f6-56732ac94bd5
E ai temos o seguinte resultado:
{
"task":{
"content":"content test",
"created_at":"2023-06-10T15:05:53.710564Z",
"id":"d6b52611-8117-43d3-a8f6-56732ac94bd5",
"title":"title test2"
}
"status":"success"
}
E bem, por hoje é só!