mirror of
https://gitlab.com/msrd0/gotham-restful.git
synced 2025-02-23 04:52:28 +00:00
add request bodies to openapi
This commit is contained in:
parent
389740cd64
commit
fe6a79008e
6 changed files with 45 additions and 29 deletions
11
src/lib.rs
11
src/lib.rs
|
@ -2,8 +2,7 @@
|
||||||
#[macro_use] extern crate serde;
|
#[macro_use] extern crate serde;
|
||||||
|
|
||||||
pub use hyper::StatusCode;
|
pub use hyper::StatusCode;
|
||||||
#[cfg(not(feature = "openapi"))]
|
use serde::{de::DeserializeOwned, Serialize};
|
||||||
use serde::Serialize;
|
|
||||||
|
|
||||||
pub mod helper;
|
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!
|
/// that is serializable with serde, however, it is recommended to use the rest_struct!
|
||||||
/// macro to create one.
|
/// macro to create one.
|
||||||
#[cfg(not(feature = "openapi"))]
|
#[cfg(not(feature = "openapi"))]
|
||||||
pub trait ResourceType : Serialize
|
pub trait ResourceType : DeserializeOwned + Serialize
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(not(feature = "openapi"))]
|
#[cfg(not(feature = "openapi"))]
|
||||||
impl<T : Serialize> ResourceType for T
|
impl<T : DeserializeOwned + Serialize> ResourceType for T
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -53,11 +52,11 @@ impl<T : Serialize> ResourceType for T
|
||||||
/// that is serializable with serde, however, it is recommended to use the rest_struct!
|
/// that is serializable with serde, however, it is recommended to use the rest_struct!
|
||||||
/// macro to create one.
|
/// macro to create one.
|
||||||
#[cfg(feature = "openapi")]
|
#[cfg(feature = "openapi")]
|
||||||
pub trait ResourceType : OpenapiType
|
pub trait ResourceType : OpenapiType + DeserializeOwned + Serialize
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "openapi")]
|
#[cfg(feature = "openapi")]
|
||||||
impl<T : OpenapiType> ResourceType for T
|
impl<T : OpenapiType + DeserializeOwned + Serialize> ResourceType for T
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,7 +2,8 @@ use crate::{
|
||||||
resource::*,
|
resource::*,
|
||||||
result::*,
|
result::*,
|
||||||
routing::*,
|
routing::*,
|
||||||
OpenapiType
|
OpenapiType,
|
||||||
|
ResourceType
|
||||||
};
|
};
|
||||||
use futures::future::ok;
|
use futures::future::ok;
|
||||||
use gotham::{
|
use gotham::{
|
||||||
|
@ -68,7 +69,7 @@ impl OpenapiRouter
|
||||||
self.0.paths.insert(path.to_string(), Item(item));
|
self.0.paths.insert(path.to_string(), Item(item));
|
||||||
}
|
}
|
||||||
|
|
||||||
fn add_schema<T : ResourceResult>(&mut self, path : &str, method : &str, desc : &str) -> String
|
fn add_schema<T : OpenapiType>(&mut self, path : &str, method : &str, desc : &str) -> String
|
||||||
{
|
{
|
||||||
let name = T::schema_name().unwrap_or_else(|| format!("path_{}_{}_{}", path, method, desc));
|
let name = T::schema_name().unwrap_or_else(|| format!("path_{}_{}_{}", path, method, desc));
|
||||||
let item = Schema {
|
let item = Schema {
|
||||||
|
@ -278,15 +279,16 @@ macro_rules! implOpenapiRouter {
|
||||||
|
|
||||||
fn create<Handler, Body, Res>(&mut self)
|
fn create<Handler, Body, Res>(&mut self)
|
||||||
where
|
where
|
||||||
Body : DeserializeOwned,
|
Body : ResourceType,
|
||||||
Res : ResourceResult,
|
Res : ResourceResult,
|
||||||
Handler : ResourceCreate<Body, Res>
|
Handler : ResourceCreate<Body, Res>
|
||||||
{
|
{
|
||||||
let schema = (self.0).1.add_schema::<Res>(&self.1, "create", "result_body");
|
let schema = (self.0).1.add_schema::<Res>(&self.1, "create", "result_body");
|
||||||
|
let body_schema = (self.0).1.add_schema::<Body>(&self.1, "create", "body");
|
||||||
|
|
||||||
let path = format!("/{}", &self.1);
|
let path = format!("/{}", &self.1);
|
||||||
let mut item = (self.0).1.remove_path(&path);
|
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);
|
(self.0).1.add_path(path, item);
|
||||||
|
|
||||||
(&mut *(self.0).0, self.1.to_string()).create::<Handler, Body, Res>()
|
(&mut *(self.0).0, self.1.to_string()).create::<Handler, Body, Res>()
|
||||||
|
@ -294,15 +296,16 @@ macro_rules! implOpenapiRouter {
|
||||||
|
|
||||||
fn update_all<Handler, Body, Res>(&mut self)
|
fn update_all<Handler, Body, Res>(&mut self)
|
||||||
where
|
where
|
||||||
Body : DeserializeOwned,
|
Body : ResourceType,
|
||||||
Res : ResourceResult,
|
Res : ResourceResult,
|
||||||
Handler : ResourceUpdateAll<Body, Res>
|
Handler : ResourceUpdateAll<Body, Res>
|
||||||
{
|
{
|
||||||
let schema = (self.0).1.add_schema::<Res>(&self.1, "update_all", "result_body");
|
let schema = (self.0).1.add_schema::<Res>(&self.1, "update_all", "result_body");
|
||||||
|
let body_schema = (self.0).1.add_schema::<Body>(&self.1, "create", "body");
|
||||||
|
|
||||||
let path = format!("/{}", &self.1);
|
let path = format!("/{}", &self.1);
|
||||||
let mut item = (self.0).1.remove_path(&path);
|
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);
|
(self.0).1.add_path(path, item);
|
||||||
|
|
||||||
(&mut *(self.0).0, self.1.to_string()).update_all::<Handler, Body, Res>()
|
(&mut *(self.0).0, self.1.to_string()).update_all::<Handler, Body, Res>()
|
||||||
|
@ -311,15 +314,16 @@ macro_rules! implOpenapiRouter {
|
||||||
fn update<Handler, ID, Body, Res>(&mut self)
|
fn update<Handler, ID, Body, Res>(&mut self)
|
||||||
where
|
where
|
||||||
ID : DeserializeOwned + Clone + RefUnwindSafe + Send + Sync + 'static,
|
ID : DeserializeOwned + Clone + RefUnwindSafe + Send + Sync + 'static,
|
||||||
Body : DeserializeOwned,
|
Body : ResourceType,
|
||||||
Res : ResourceResult,
|
Res : ResourceResult,
|
||||||
Handler : ResourceUpdate<ID, Body, Res>
|
Handler : ResourceUpdate<ID, Body, Res>
|
||||||
{
|
{
|
||||||
let schema = (self.0).1.add_schema::<Res>(&self.1, "update", "result_body");
|
let schema = (self.0).1.add_schema::<Res>(&self.1, "update", "result_body");
|
||||||
|
let body_schema = (self.0).1.add_schema::<Body>(&self.1, "create", "body");
|
||||||
|
|
||||||
let path = format!("/{}/{{id}}", &self.1);
|
let path = format!("/{}/{{id}}", &self.1);
|
||||||
let mut item = (self.0).1.remove_path(&path);
|
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);
|
(self.0).1.add_path(path, item);
|
||||||
|
|
||||||
(&mut *(self.0).0, self.1.to_string()).update::<Handler, ID, Body, Res>()
|
(&mut *(self.0).0, self.1.to_string()).update::<Handler, ID, Body, Res>()
|
||||||
|
|
|
@ -1,11 +1,9 @@
|
||||||
use indexmap::IndexMap;
|
|
||||||
use openapiv3::{
|
use openapiv3::{
|
||||||
ArrayType, IntegerType, NumberType, ObjectType, ReferenceOr::Item, Schema, SchemaData, SchemaKind, StringType, Type
|
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<String>
|
fn schema_name() -> Option<String>
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
use crate::{DrawResourceRoutes, ResourceResult};
|
use crate::{DrawResourceRoutes, ResourceResult, ResourceType};
|
||||||
use gotham::state::State;
|
use gotham::state::State;
|
||||||
use serde::de::DeserializeOwned;
|
use serde::de::DeserializeOwned;
|
||||||
use std::panic::RefUnwindSafe;
|
use std::panic::RefUnwindSafe;
|
||||||
|
@ -30,7 +30,7 @@ where
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Handle a POST request on the Resource root.
|
/// Handle a POST request on the Resource root.
|
||||||
pub trait ResourceCreate<Body : DeserializeOwned, R : ResourceResult>
|
pub trait ResourceCreate<Body : ResourceType, R : ResourceResult>
|
||||||
{
|
{
|
||||||
fn create(state : &mut State, body : Body) -> R;
|
fn create(state : &mut State, body : Body) -> R;
|
||||||
}
|
}
|
||||||
|
@ -42,7 +42,7 @@ pub trait ResourceUpdateAll<Body : DeserializeOwned, R : ResourceResult>
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Handle a PUT request on the Resource with an id.
|
/// Handle a PUT request on the Resource with an id.
|
||||||
pub trait ResourceUpdate<ID, Body : DeserializeOwned, R : ResourceResult>
|
pub trait ResourceUpdate<ID, Body : ResourceType, R : ResourceResult>
|
||||||
where
|
where
|
||||||
ID : DeserializeOwned + Clone + RefUnwindSafe + Send + Sync + 'static
|
ID : DeserializeOwned + Clone + RefUnwindSafe + Send + Sync + 'static
|
||||||
{
|
{
|
||||||
|
|
|
@ -17,6 +17,20 @@ pub trait ResourceResult
|
||||||
fn to_schema() -> SchemaKind;
|
fn to_schema() -> SchemaKind;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "openapi")]
|
||||||
|
impl<Res : ResourceResult> crate::OpenapiType for Res
|
||||||
|
{
|
||||||
|
fn schema_name() -> Option<String>
|
||||||
|
{
|
||||||
|
Self::schema_name()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn to_schema() -> SchemaKind
|
||||||
|
{
|
||||||
|
Self::to_schema()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// The default json returned on an 500 Internal Server Error.
|
/// The default json returned on an 500 Internal Server Error.
|
||||||
#[derive(Debug, Serialize)]
|
#[derive(Debug, Serialize)]
|
||||||
pub struct ResourceError
|
pub struct ResourceError
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
use crate::{
|
use crate::{
|
||||||
resource::*,
|
resource::*,
|
||||||
result::{ResourceError, ResourceResult},
|
result::{ResourceError, ResourceResult},
|
||||||
|
ResourceType,
|
||||||
StatusCode
|
StatusCode
|
||||||
};
|
};
|
||||||
#[cfg(feature = "openapi")]
|
#[cfg(feature = "openapi")]
|
||||||
|
@ -66,20 +67,20 @@ pub trait DrawResourceRoutes
|
||||||
|
|
||||||
fn create<Handler, Body, Res>(&mut self)
|
fn create<Handler, Body, Res>(&mut self)
|
||||||
where
|
where
|
||||||
Body : DeserializeOwned,
|
Body : ResourceType,
|
||||||
Res : ResourceResult,
|
Res : ResourceResult,
|
||||||
Handler : ResourceCreate<Body, Res>;
|
Handler : ResourceCreate<Body, Res>;
|
||||||
|
|
||||||
fn update_all<Handler, Body, Res>(&mut self)
|
fn update_all<Handler, Body, Res>(&mut self)
|
||||||
where
|
where
|
||||||
Body : DeserializeOwned,
|
Body : ResourceType,
|
||||||
Res : ResourceResult,
|
Res : ResourceResult,
|
||||||
Handler : ResourceUpdateAll<Body, Res>;
|
Handler : ResourceUpdateAll<Body, Res>;
|
||||||
|
|
||||||
fn update<Handler, ID, Body, Res>(&mut self)
|
fn update<Handler, ID, Body, Res>(&mut self)
|
||||||
where
|
where
|
||||||
ID : DeserializeOwned + Clone + RefUnwindSafe + Send + Sync + 'static,
|
ID : DeserializeOwned + Clone + RefUnwindSafe + Send + Sync + 'static,
|
||||||
Body : DeserializeOwned,
|
Body : ResourceType,
|
||||||
Res : ResourceResult,
|
Res : ResourceResult,
|
||||||
Handler : ResourceUpdate<ID, Body, Res>;
|
Handler : ResourceUpdate<ID, Body, Res>;
|
||||||
|
|
||||||
|
@ -176,7 +177,7 @@ where
|
||||||
|
|
||||||
fn create_handler<Handler, Body, Res>(state : State) -> Box<HandlerFuture>
|
fn create_handler<Handler, Body, Res>(state : State) -> Box<HandlerFuture>
|
||||||
where
|
where
|
||||||
Body : DeserializeOwned,
|
Body : ResourceType,
|
||||||
Res : ResourceResult,
|
Res : ResourceResult,
|
||||||
Handler : ResourceCreate<Body, Res>
|
Handler : ResourceCreate<Body, Res>
|
||||||
{
|
{
|
||||||
|
@ -185,7 +186,7 @@ where
|
||||||
|
|
||||||
fn update_all_handler<Handler, Body, Res>(state : State) -> Box<HandlerFuture>
|
fn update_all_handler<Handler, Body, Res>(state : State) -> Box<HandlerFuture>
|
||||||
where
|
where
|
||||||
Body : DeserializeOwned,
|
Body : ResourceType,
|
||||||
Res : ResourceResult,
|
Res : ResourceResult,
|
||||||
Handler : ResourceUpdateAll<Body, Res>
|
Handler : ResourceUpdateAll<Body, Res>
|
||||||
{
|
{
|
||||||
|
@ -195,7 +196,7 @@ where
|
||||||
fn update_handler<Handler, ID, Body, Res>(state : State) -> Box<HandlerFuture>
|
fn update_handler<Handler, ID, Body, Res>(state : State) -> Box<HandlerFuture>
|
||||||
where
|
where
|
||||||
ID : DeserializeOwned + Clone + RefUnwindSafe + Send + Sync + 'static,
|
ID : DeserializeOwned + Clone + RefUnwindSafe + Send + Sync + 'static,
|
||||||
Body : DeserializeOwned,
|
Body : ResourceType,
|
||||||
Res : ResourceResult,
|
Res : ResourceResult,
|
||||||
Handler : ResourceUpdate<ID, Body, Res>
|
Handler : ResourceUpdate<ID, Body, Res>
|
||||||
{
|
{
|
||||||
|
@ -286,7 +287,7 @@ macro_rules! implDrawResourceRoutes {
|
||||||
|
|
||||||
fn create<Handler, Body, Res>(&mut self)
|
fn create<Handler, Body, Res>(&mut self)
|
||||||
where
|
where
|
||||||
Body : DeserializeOwned,
|
Body : ResourceType,
|
||||||
Res : ResourceResult,
|
Res : ResourceResult,
|
||||||
Handler : ResourceCreate<Body, Res>
|
Handler : ResourceCreate<Body, Res>
|
||||||
{
|
{
|
||||||
|
@ -296,7 +297,7 @@ macro_rules! implDrawResourceRoutes {
|
||||||
|
|
||||||
fn update_all<Handler, Body, Res>(&mut self)
|
fn update_all<Handler, Body, Res>(&mut self)
|
||||||
where
|
where
|
||||||
Body : DeserializeOwned,
|
Body : ResourceType,
|
||||||
Res : ResourceResult,
|
Res : ResourceResult,
|
||||||
Handler : ResourceUpdateAll<Body, Res>
|
Handler : ResourceUpdateAll<Body, Res>
|
||||||
{
|
{
|
||||||
|
@ -307,7 +308,7 @@ macro_rules! implDrawResourceRoutes {
|
||||||
fn update<Handler, ID, Body, Res>(&mut self)
|
fn update<Handler, ID, Body, Res>(&mut self)
|
||||||
where
|
where
|
||||||
ID : DeserializeOwned + Clone + RefUnwindSafe + Send + Sync + 'static,
|
ID : DeserializeOwned + Clone + RefUnwindSafe + Send + Sync + 'static,
|
||||||
Body : DeserializeOwned,
|
Body : ResourceType,
|
||||||
Res : ResourceResult,
|
Res : ResourceResult,
|
||||||
Handler : ResourceUpdate<ID, Body, Res>
|
Handler : ResourceUpdate<ID, Body, Res>
|
||||||
{
|
{
|
||||||
|
|
Loading…
Add table
Reference in a new issue