From fe6a79008e4d4f8af883884c063454161873fef9 Mon Sep 17 00:00:00 2001 From: Dominic Date: Tue, 1 Oct 2019 00:49:13 +0200 Subject: [PATCH] add request bodies to openapi --- src/lib.rs | 11 +++++------ src/openapi/router.rs | 20 ++++++++++++-------- src/openapi/types.rs | 4 +--- src/resource.rs | 6 +++--- src/result.rs | 14 ++++++++++++++ src/routing.rs | 19 ++++++++++--------- 6 files changed, 45 insertions(+), 29 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index 0506d71..715cb90 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -2,8 +2,7 @@ #[macro_use] extern crate serde; pub use hyper::StatusCode; -#[cfg(not(feature = "openapi"))] -use serde::Serialize; +use serde::{de::DeserializeOwned, Serialize}; pub mod helper; @@ -40,12 +39,12 @@ pub use routing::WithOpenapi; /// that is serializable with serde, however, it is recommended to use the rest_struct! /// macro to create one. #[cfg(not(feature = "openapi"))] -pub trait ResourceType : Serialize +pub trait ResourceType : DeserializeOwned + Serialize { } #[cfg(not(feature = "openapi"))] -impl ResourceType for T +impl ResourceType for T { } @@ -53,11 +52,11 @@ impl ResourceType for T /// that is serializable with serde, however, it is recommended to use the rest_struct! /// macro to create one. #[cfg(feature = "openapi")] -pub trait ResourceType : OpenapiType +pub trait ResourceType : OpenapiType + DeserializeOwned + Serialize { } #[cfg(feature = "openapi")] -impl ResourceType for T +impl ResourceType for T { } diff --git a/src/openapi/router.rs b/src/openapi/router.rs index 25dc3c0..1539f4d 100644 --- a/src/openapi/router.rs +++ b/src/openapi/router.rs @@ -2,7 +2,8 @@ use crate::{ resource::*, result::*, routing::*, - OpenapiType + OpenapiType, + ResourceType }; use futures::future::ok; use gotham::{ @@ -68,7 +69,7 @@ impl OpenapiRouter self.0.paths.insert(path.to_string(), Item(item)); } - fn add_schema(&mut self, path : &str, method : &str, desc : &str) -> String + fn add_schema(&mut self, path : &str, method : &str, desc : &str) -> String { let name = T::schema_name().unwrap_or_else(|| format!("path_{}_{}_{}", path, method, desc)); let item = Schema { @@ -278,15 +279,16 @@ macro_rules! implOpenapiRouter { fn create(&mut self) where - Body : DeserializeOwned, + Body : ResourceType, Res : ResourceResult, Handler : ResourceCreate { let schema = (self.0).1.add_schema::(&self.1, "create", "result_body"); + let body_schema = (self.0).1.add_schema::(&self.1, "create", "body"); let path = format!("/{}", &self.1); let mut item = (self.0).1.remove_path(&path); - item.post = Some(new_operation(&schema, vec![], None)); + item.post = Some(new_operation(&schema, vec![], Some(&body_schema))); (self.0).1.add_path(path, item); (&mut *(self.0).0, self.1.to_string()).create::() @@ -294,15 +296,16 @@ macro_rules! implOpenapiRouter { fn update_all(&mut self) where - Body : DeserializeOwned, + Body : ResourceType, Res : ResourceResult, Handler : ResourceUpdateAll { let schema = (self.0).1.add_schema::(&self.1, "update_all", "result_body"); + let body_schema = (self.0).1.add_schema::(&self.1, "create", "body"); let path = format!("/{}", &self.1); let mut item = (self.0).1.remove_path(&path); - item.put = Some(new_operation(&schema, vec![], None)); + item.put = Some(new_operation(&schema, vec![], Some(&body_schema))); (self.0).1.add_path(path, item); (&mut *(self.0).0, self.1.to_string()).update_all::() @@ -311,15 +314,16 @@ macro_rules! implOpenapiRouter { fn update(&mut self) where ID : DeserializeOwned + Clone + RefUnwindSafe + Send + Sync + 'static, - Body : DeserializeOwned, + Body : ResourceType, Res : ResourceResult, Handler : ResourceUpdate { let schema = (self.0).1.add_schema::(&self.1, "update", "result_body"); + let body_schema = (self.0).1.add_schema::(&self.1, "create", "body"); let path = format!("/{}/{{id}}", &self.1); let mut item = (self.0).1.remove_path(&path); - item.put = Some(new_operation(&schema, vec!["id"], None)); + item.put = Some(new_operation(&schema, vec!["id"], Some(&body_schema))); (self.0).1.add_path(path, item); (&mut *(self.0).0, self.1.to_string()).update::() diff --git a/src/openapi/types.rs b/src/openapi/types.rs index 8ed2851..3b70003 100644 --- a/src/openapi/types.rs +++ b/src/openapi/types.rs @@ -1,11 +1,9 @@ -use indexmap::IndexMap; use openapiv3::{ ArrayType, IntegerType, NumberType, ObjectType, ReferenceOr::Item, Schema, SchemaData, SchemaKind, StringType, Type }; -use serde::Serialize; -pub trait OpenapiType : Serialize +pub trait OpenapiType { fn schema_name() -> Option { diff --git a/src/resource.rs b/src/resource.rs index f82947c..d05594f 100644 --- a/src/resource.rs +++ b/src/resource.rs @@ -1,4 +1,4 @@ -use crate::{DrawResourceRoutes, ResourceResult}; +use crate::{DrawResourceRoutes, ResourceResult, ResourceType}; use gotham::state::State; use serde::de::DeserializeOwned; use std::panic::RefUnwindSafe; @@ -30,7 +30,7 @@ where } /// Handle a POST request on the Resource root. -pub trait ResourceCreate +pub trait ResourceCreate { fn create(state : &mut State, body : Body) -> R; } @@ -42,7 +42,7 @@ pub trait ResourceUpdateAll } /// Handle a PUT request on the Resource with an id. -pub trait ResourceUpdate +pub trait ResourceUpdate where ID : DeserializeOwned + Clone + RefUnwindSafe + Send + Sync + 'static { diff --git a/src/result.rs b/src/result.rs index b67333d..3f8eed1 100644 --- a/src/result.rs +++ b/src/result.rs @@ -17,6 +17,20 @@ pub trait ResourceResult fn to_schema() -> SchemaKind; } +#[cfg(feature = "openapi")] +impl crate::OpenapiType for Res +{ + fn schema_name() -> Option + { + Self::schema_name() + } + + fn to_schema() -> SchemaKind + { + Self::to_schema() + } +} + /// The default json returned on an 500 Internal Server Error. #[derive(Debug, Serialize)] pub struct ResourceError diff --git a/src/routing.rs b/src/routing.rs index 726dc85..5d720b2 100644 --- a/src/routing.rs +++ b/src/routing.rs @@ -1,6 +1,7 @@ use crate::{ resource::*, result::{ResourceError, ResourceResult}, + ResourceType, StatusCode }; #[cfg(feature = "openapi")] @@ -66,20 +67,20 @@ pub trait DrawResourceRoutes fn create(&mut self) where - Body : DeserializeOwned, + Body : ResourceType, Res : ResourceResult, Handler : ResourceCreate; fn update_all(&mut self) where - Body : DeserializeOwned, + Body : ResourceType, Res : ResourceResult, Handler : ResourceUpdateAll; fn update(&mut self) where ID : DeserializeOwned + Clone + RefUnwindSafe + Send + Sync + 'static, - Body : DeserializeOwned, + Body : ResourceType, Res : ResourceResult, Handler : ResourceUpdate; @@ -176,7 +177,7 @@ where fn create_handler(state : State) -> Box where - Body : DeserializeOwned, + Body : ResourceType, Res : ResourceResult, Handler : ResourceCreate { @@ -185,7 +186,7 @@ where fn update_all_handler(state : State) -> Box where - Body : DeserializeOwned, + Body : ResourceType, Res : ResourceResult, Handler : ResourceUpdateAll { @@ -195,7 +196,7 @@ where fn update_handler(state : State) -> Box where ID : DeserializeOwned + Clone + RefUnwindSafe + Send + Sync + 'static, - Body : DeserializeOwned, + Body : ResourceType, Res : ResourceResult, Handler : ResourceUpdate { @@ -286,7 +287,7 @@ macro_rules! implDrawResourceRoutes { fn create(&mut self) where - Body : DeserializeOwned, + Body : ResourceType, Res : ResourceResult, Handler : ResourceCreate { @@ -296,7 +297,7 @@ macro_rules! implDrawResourceRoutes { fn update_all(&mut self) where - Body : DeserializeOwned, + Body : ResourceType, Res : ResourceResult, Handler : ResourceUpdateAll { @@ -307,7 +308,7 @@ macro_rules! implDrawResourceRoutes { fn update(&mut self) where ID : DeserializeOwned + Clone + RefUnwindSafe + Send + Sync + 'static, - Body : DeserializeOwned, + Body : ResourceType, Res : ResourceResult, Handler : ResourceUpdate {