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

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

Open
Sleepful opened this issue May 30, 2024 · 2 comments
Open

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

Sleepful opened this issue May 30, 2024 · 2 comments

Comments

@Sleepful
Copy link

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

jofas commented May 30, 2024

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.

@Sleepful
Copy link
Author

Sleepful commented Jul 11, 2024

Hello! Yes I think a fully working example would be helpful for other clueless people like me.

I really enjoyed this other crate for example: arrow-rs, because there were examples that I could run as their own programs:

(I think this example setup is the one you linked to in The Cargo Book)

I remember trying to look at the tests in actix_proxy to figure it out, but no luck.

In the end I went with the NodeJS cors-anywhere project, which is what I was trying to achieve with this package at the time (fetching a resource and removing CORS limitations to proxy it to the browser).

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

No branches or pull requests

2 participants