jofas / actix_proxy

Glue code between awc and actix-web
Other
12 stars 3 forks source link

Failed to extract `Data<awc::client::Client>` for `proxy` #17

Open Sleepful opened 1 month ago

Sleepful commented 1 month ago

Tried to run the sample code in README, this happens:

Failed to extract `Data<awc::client::Client>` for `proxy` handler. For the Data extractor to work correctly, wrap the data with `Data::new()` and pass it to `App::app_data()`. Ensure that types align in both the set and retrieve calls

What did I do wrong?

upset that the basic code doesn't work haha

jofas commented 1 month ago

Well, the samples from the README are just snippets showing the relevant parts of how to use the traits of this crate. What they don't show is that you need to add a awc::client::Client to the app data of your actix-web webserver in order for it to work. Like this, for example:

use awc::Client;

use actix_web::{get, web, HttpResponse};

use actix_proxy::{IntoHttpResponse, SendRequestError};

#[get("/{url:.*}")]
async fn proxy(
    path: web::Path<(String,)>,
    client: web::Data<Client>,
) -> Result<HttpResponse, SendRequestError> {
    let (url,) = path.into_inner();

    let url = format!("https://duckduckgo.com/{url}");

    // here we use `IntoHttpResponse` to return the request to 
    // duckduckgo back to the client that called this endpoint
    Ok(client.get(&url).send().await?.into_http_response())
}

#[actix_web::main]
async fn main() -> std::io::Result<()> {
    HttpServer::new(|| {
        App::new()
            .app_data(web::Data::new(Client::default())) // This is the important line
            .service(proxy)
    })
    .bind(("127.0.0.1", 8080))?
    .run()
    .await
}

How can I improve documentation to make it clear that you are required to add an instance of awc::client::Client to the app data in the examples? Do you want me to add the main function to the snippets as well? I didn't add it, because I thought it'd make the snippets too complicated as it is not immediately clear what the benefit of this crate might be. Alternatively, I could reduce the examples and create the client inside the endpoint, but that's very wasteful and I don't necessarily want to promote code that is clearly suboptimal. My preferred enhancement to the docs would be to add a fully working example (#3) to the repo (which would basically be the code I listed above), would that have been helpful for you? Then we could add a link to the example in the docs.