Skip to content
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

Merged
merged 22 commits into from
Oct 26, 2020
Merged

Astrazione del body della request #9

merged 22 commits into from
Oct 26, 2020

Conversation

matteosister
Copy link
Member

@matteosister matteosister commented Oct 20, 2020

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

let body: Option<String> = None;
bridge.request(RequestType::rest(body, Method::GET)).send();

diventa

RestRequest::new(&bridge).send();

(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ì...

@matteosister matteosister linked an issue Oct 20, 2020 that may be closed by this pull request
@matteosister matteosister marked this pull request as ready for review October 21, 2020 08:32
Copy link
Contributor

@Guara92 Guara92 left a 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)

src/request.rs Show resolved Hide resolved
src/request.rs Show resolved Hide resolved
src/request.rs Show resolved Hide resolved
src/v2/body.rs Outdated Show resolved Hide resolved
src/v2/body.rs Outdated Show resolved Hide resolved
use crate::errors::PrimaBridgeError;
use std::convert::TryFrom;

#[derive(Clone, Debug)]
Copy link
Contributor

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

Copy link
Member Author

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....

Copy link
Contributor

@Guara92 Guara92 Oct 22, 2020

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

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

interessante....da esplorare...

Copy link
Member Author

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

Copy link

@chess4ever chess4ever left a 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

@matteosister
Copy link
Member Author

@chess4ever che è tantissimo!

@Guara92 bridge.send non è per niente male...ma anche RestRequest::new(&bridge) non mi dispiace.

@chess4ever
Copy link

@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!

@miterst
Copy link
Contributor

miterst commented Oct 22, 2020

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?

@matteosister
Copy link
Member Author

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!

@matteosister
Copy link
Member Author

Ho implementato le cose che diceva @Guara92 (non sulla parte request che ora è deprecata e a breve si butta) e l'api fancy suggerita da @miterst.

@matteosister matteosister requested a review from Guara92 October 22, 2020 12:07
Copy link

@torrefatto torrefatto left a 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},

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...

Copy link
Member Author

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...

Comment on lines +198 to +212
#[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(())
}

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>.

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

Copy link
Member Author

@matteosister matteosister Oct 22, 2020

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?

Copy link

@chess4ever chess4ever Oct 22, 2020

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

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

no ora ci provo..

Copy link
Member Author

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?

Copy link
Member Author

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

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

volo!

Copy link
Member Author

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?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@wolf4ood
Copy link
Contributor

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 to method ad esempio

@matteosister
Copy link
Member Author

matteosister commented Oct 23, 2020

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 to method ad esempio

@wolf4ood ❤️ per ora ho implementato qualcosina...https://github.com/primait/bridge.rs/blob/v2/src/v2/request/mod.rs

@matteosister
Copy link
Member Author

@wolf4ood secondo te facciamo proprio tipi separati? Tipo typestate pattern, oppure faccio tornare un result dalle funzioni incriminate?

@wolf4ood
Copy link
Contributor

wolf4ood commented Oct 23, 2020

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
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

credo ti sia scappato

chess4ever
chess4ever previously approved these changes Oct 23, 2020
@matteosister matteosister merged commit c20096f into master Oct 26, 2020
@matteosister matteosister deleted the v2 branch October 26, 2020 10:53
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Rendere possibile l'invio di un body in formato binario
6 participants