From 0a058ba2064d323451462a79c71580dea7d8ec8c Mon Sep 17 00:00:00 2001 From: FxQnLr Date: Mon, 4 Mar 2024 21:37:55 +0100 Subject: Closes #19. Added OpenApi through `utoipa` --- src/routes/device.rs | 91 +++++++++++++++++++++++++++++++++++++++++++--------- src/routes/start.rs | 16 +++++++-- 2 files changed, 88 insertions(+), 19 deletions(-) (limited to 'src/routes') diff --git a/src/routes/device.rs b/src/routes/device.rs index d39d98e..d01d9f0 100644 --- a/src/routes/device.rs +++ b/src/routes/device.rs @@ -1,14 +1,25 @@ use crate::db::Device; use crate::error::Error; -use axum::extract::State; +use axum::extract::{Path, State}; use axum::Json; use mac_address::MacAddress; -use serde::{Deserialize, Serialize}; +use serde::Deserialize; use serde_json::{json, Value}; use sqlx::types::ipnetwork::IpNetwork; -use std::{sync::Arc, str::FromStr}; +use std::{str::FromStr, sync::Arc}; use tracing::{debug, info}; +use utoipa::ToSchema; +#[utoipa::path( + get, + path = "/device", + request_body = GetDevicePayload, + responses( + (status = 200, description = "Get `Device` information", body = [Device]) + ), + security(("api_key" = [])) +)] +#[deprecated] pub async fn get( State(state): State>, Json(payload): Json, @@ -31,11 +42,53 @@ pub async fn get( Ok(Json(json!(device))) } -#[derive(Deserialize)] +#[utoipa::path( + get, + path = "/device/{id}", + responses( + (status = 200, description = "Get `Device` information", body = [Device]) + ), + params( + ("id" = String, Path, description = "Device id") + ), + security(("api_key" = [])) +)] +pub async fn get_path( + State(state): State>, + Path(path): Path, +) -> Result, Error> { + info!("get device from path {}", path); + let device = sqlx::query_as!( + Device, + r#" + SELECT id, mac, broadcast_addr, ip, times + FROM devices + WHERE id = $1; + "#, + path + ) + .fetch_one(&state.db) + .await?; + + debug!("got device {:?}", device); + + Ok(Json(json!(device))) +} + +#[derive(Deserialize, ToSchema)] pub struct GetDevicePayload { id: String, } +#[utoipa::path( + put, + path = "/device", + request_body = PutDevicePayload, + responses( + (status = 200, description = "List matching todos by query", body = [DeviceSchema]) + ), + security(("api_key" = [])) +)] pub async fn put( State(state): State>, Json(payload): Json, @@ -44,26 +97,28 @@ pub async fn put( "add device {} ({}, {}, {})", payload.id, payload.mac, payload.broadcast_addr, payload.ip ); - + let ip = IpNetwork::from_str(&payload.ip)?; let mac = MacAddress::from_str(&payload.mac)?; - sqlx::query!( + let device = sqlx::query_as!( + Device, r#" INSERT INTO devices (id, mac, broadcast_addr, ip) - VALUES ($1, $2, $3, $4); + VALUES ($1, $2, $3, $4) + RETURNING id, mac, broadcast_addr, ip, times; "#, payload.id, mac, payload.broadcast_addr, ip ) - .execute(&state.db) + .fetch_one(&state.db) .await?; - Ok(Json(json!(PutDeviceResponse { success: true }))) + Ok(Json(json!(device))) } -#[derive(Deserialize)] +#[derive(Deserialize, ToSchema)] pub struct PutDevicePayload { id: String, mac: String, @@ -71,11 +126,15 @@ pub struct PutDevicePayload { ip: String, } -#[derive(Serialize)] -pub struct PutDeviceResponse { - success: bool, -} - +#[utoipa::path( + post, + path = "/device", + request_body = PostDevicePayload, + responses( + (status = 200, description = "List matching todos by query", body = [DeviceSchema]) + ), + security(("api_key" = [])) +)] pub async fn post( State(state): State>, Json(payload): Json, @@ -104,7 +163,7 @@ pub async fn post( Ok(Json(json!(device))) } -#[derive(Deserialize)] +#[derive(Deserialize, ToSchema)] pub struct PostDevicePayload { id: String, mac: String, diff --git a/src/routes/start.rs b/src/routes/start.rs index d4c0802..ef6e8f2 100644 --- a/src/routes/start.rs +++ b/src/routes/start.rs @@ -6,10 +6,20 @@ use axum::extract::State; use axum::Json; use serde::{Deserialize, Serialize}; use serde_json::{json, Value}; +use utoipa::ToSchema; use std::sync::Arc; use tracing::{debug, info}; use uuid::Uuid; +#[utoipa::path( + post, + path = "/start", + request_body = Payload, + responses( + (status = 200, description = "List matching todos by query", body = [Response]) + ), + security(("api_key" = [])) +)] pub async fn start( State(state): State>, Json(payload): Json, @@ -88,14 +98,14 @@ fn setup_ping(state: Arc, device: Device) -> String { uuid_ret } -#[derive(Deserialize)] +#[derive(Deserialize, ToSchema)] pub struct Payload { id: String, ping: Option, } -#[derive(Serialize)] -struct Response { +#[derive(Serialize, ToSchema)] +pub struct Response { id: String, boot: bool, uuid: Option, -- cgit v1.2.3