-
Notifications
You must be signed in to change notification settings - Fork 1
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Astrazione del body della request #9
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ripensando un attimo alla struttura delle request pensavo che forse la request dovrebbe essere indipendente dal bridge essendo solo il "mezzo" su cui viene eseguita, l'api potrebbe essere qualcosa tipo bridge.send(RestRequest::new())
o RestRequest::new().send(&bridge)
use crate::errors::PrimaBridgeError; | ||
use std::convert::TryFrom; | ||
|
||
#[derive(Clone, Debug)] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
perché il body di una request dovrebbe essere clonabile? forse dovrebbe contenere solo un riferimento all'array di bytes
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
perchè credo che reqwest sotto si prenda l'ownership del body, quindi non posso passarlo per referenza....
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
prenderei in considerazione di consumare la DeliverableRequest
implementando
impl<T: DeliverableRequest> From<T> for RequestBuilder
dove consumi la "nostra" request e ottieni un builder di reqwest in un colpo solo evitando diversi clone
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
interessante....da esplorare...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
è un po' un casino perchè nel trait ora ci sono le due implementazioni di send
per le due feature async
e blocking
. Il RequestBuilder è diverso a sua volta in base ad async e blocking...quindi non hanno un interfaccia comune
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
sono ignorante in rust, quindi il massimo contributo che posso dare è provare a integrarlo su toretto con la chiamata a pasteur e farci un qa
@chess4ever che è tantissimo! @Guara92 bridge.send non è per niente male...ma anche RestRequest::new(&bridge) non mi dispiace. |
Aspetto un tuo ok e poi volo! |
Stavo pensando forse si puo' fare anche piu' breve es.: Request::get(&bridge).send() # ::get(..) puo ritornare RestRequest::new(&bridge)
Request::post(&bridge).body(..).send()
.
.
Request::graphql(&bridge).body(..).send() # ::graphql(..) puo ritornare GraphqlRequest::new(&bridge) Che ne pensate? |
molto bello! |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Bel lavoro di refactoring. Ho solo il dubbio che non stiamo testando veramente l'invio di un payload non utf8-serializalbe.
@@ -1,6 +1,6 @@ | |||
pub use super::errors::*; | |||
pub use super::{ | |||
request::{GraphQL, RequestType, Rest}, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Così però chi usa la versione precedente importando dal prelude
si rompe...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Vero! Ma siamo in versione 0.*, così forziamo l'update...
#[test] | ||
fn request_post_with_custom_raw_body() -> Result<(), Box<dyn Error>> { | ||
let body = "abcde"; | ||
let _mock = mock("POST", "/") | ||
.match_body(Matcher::Exact(body.to_owned())) | ||
.with_status(200) | ||
.create(); | ||
|
||
let url = Url::parse(mockito::server_url().as_str()).unwrap(); | ||
let bridge = Bridge::new(url); | ||
|
||
let result = Request::post(&bridge).raw_body(body).send(); | ||
assert!(result.is_ok()); | ||
Ok(()) | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Questo testa sempre l'invio di una stringa, giusto? Non ho capito benissimo se raw_body
accetta Vec<u8>
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
eh ma c'è il vecchio tema.. con mockito non puoi "ancora" fare il match dei binary
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
la funzione .raw_body() accetta un impl ToString
. Questo vuol dire che effettivamente ad ora non puoi passare direttamente un Vec, ma dovresti fare così:
let binary:Vec<u8> = "pippo".to_string().into_bytes();
let body = std::str::from_utf8(&binary)?;
let result = Request::post(&bridge).raw_body(body).send();
Quindi mi aspetto che chi passa il raw_body si accerti che sia una lista valida di caratteri utf-8. La gestione di questa conversione non credo debba stare nella libreria perchè è forse out of scope.
Tra l'altro esiste anche una versione che non ritorna result from_utf8_unchecked.
In from_utf8 c'è la spiegazione del perchè eistono le due versioni (utile solo a me perchè sono ignorante)
@torrefatto e altri che ne dite? Secondo voi devo fare la conversione all'interno della libreria e accettare un tipo ancora più generico?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
non mi torna.. pensavo fosse possibile ora inviare direttamente un Vec<u8>
; lo use case di Toretto per le chiamate verso Pasteur è proprio questo, inviare un binary che non è utf-8
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
no ora ci provo..
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
a proposito @torrefatto e @chess4ever siete ancora in tempo per provare a integrarlo?
Potreste fare una prova con questo branch?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
perchè non mi sento proprio 100% confident
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
volo!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
sai come fare? Penso che tu possa usarlo come submodule...o magari cargo ti lascia referenziare un branch?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Molto belle le nuove API :) Sarebbe fico come accennavi tu, rendere impossibile una cosa del genere // ok
Request::post(&bridge).raw_body("abcde").send().await;
// error
Request::graphql(&bridge, (query, variables))?.raw_body("abcde").send().await anche su altri metodi tipo |
@wolf4ood ❤️ per ora ho implementato qualcosina...https://github.com/primait/bridge.rs/blob/v2/src/v2/request/mod.rs |
@wolf4ood secondo te facciamo proprio tipi separati? Tipo typestate pattern, oppure faccio tornare un result dalle funzioni incriminate? |
Si tipo una cosa del genere struct GraphQL;
struct Rest;
struct Request<T> {
}
impl Request<Rest> {
fn json_body(self) -> Self {
self
}
}
impl<T> Request<T> {
fn send(self) {
}
}
....
}
mettendo sul Rest quelli che hanno poco senso sul GraphQL |
src/v2/mod.rs
Outdated
@@ -43,7 +43,7 @@ pub trait DeliverableRequest<'a>: Sized + 'a { | |||
/// adds a new set of headers to the request. Any header already present gets removed. | |||
fn set_custom_headers(self, headers: Vec<(HeaderName, HeaderValue)>) -> Self; | |||
|
|||
/// add a custom header to the set of request headers | |||
/// add a custom header to the set of request headersbeh 500 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
credo ti sia scappato
Non richiede più un Serializable ma chiede qualsiasi cosa convertibile in un
Body
. Apre la possibilità di usare un binary come body in una request REST.Ad oggi ho solo deprecato la vecchia parte. Prossima release butto via tutto...
Nella parte dei test si può vedere cosa cambia nell'utilizzo dell'api.
In pratica da
diventa
(GET è di default, così come il body vuoto)
Tutto è nato dall'esigenza di usare binary body con pasteur, ma in generale preferisco la nuova api. Mi sembra molto più tersa. Voi che dite?
Qui si vede come passare il body alla request in costruzione.
Una cosa che non mi piace molto è la possibilità di usare raw_body con una request graphql, che non ha molto senso. Se dovesse diventare un problema si potrebbero dividere completamente i due tipi RestRequest e GraphQLRequest, eliminando il trait DeliverableRequest. Ma questo vorrebbe dire un sacco di codice duplicato, quindi preferisco per ora mantenerlo così...