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

AppEntry inaccessible due to app_service being a private module #2039

Closed
philip-peterson opened this issue Mar 1, 2021 · 4 comments
Closed
Labels
N/A Not applicable or remedied without code change.

Comments

@philip-peterson
Copy link

philip-peterson commented Mar 1, 2021

Hi there,

I was hoping to make a function that returns an App, but because it takes two generic types, one of which defaults to AppEntry, that was impossible. It would be nice if the app_service module was public so we can do this.

@fakeshadow
Copy link
Contributor

fakeshadow commented Mar 1, 2021

It's possible and you don't need the AppEntry type. As soon as you introduce some middleware it would transform to opaque type.

use actix_service::ServiceFactory;
use actix_web::dev::{Body, ServiceRequest, ServiceResponse};
use actix_web::middleware::{Compat, Logger};
use actix_web::{get, App, Error, HttpServer};

#[actix_web::main]
async fn main() -> std::io::Result<()> {
    HttpServer::new(|| app())
        .bind("127.0.0.1:8080")?
        .run()
        .await
}

fn app() -> App<
    impl ServiceFactory<
        ServiceRequest,
        Config = (),
        Response = ServiceResponse,
        Error = Error,
        InitError = (),
    >,
    Body,
> {
    App::new()
        .wrap(Compat::new(Logger::default()))
        .service(index)
}

#[get("/hi")]
async fn index() -> &'static str {
    "Hello World!"
}

In general do not return an App instance unless you have a very good understanding of how to describe the complicated types App returns. It wants an opaque type that impl ServiceFactory trait and a Body generic type of response body
Instead you can use App::configure API to customize your app build.

@simon-an
Copy link

simon-an commented Mar 2, 2021

Your code does not compile with the latest stable release

@robjtede
Copy link
Member

robjtede commented Mar 2, 2021

App::configure is the recommended solution. app_service is intentionally private.

@robjtede robjtede closed this as completed Mar 2, 2021
@fakeshadow
Copy link
Contributor

fakeshadow commented Mar 2, 2021

Your code does not compile with the latest stable release

Sorry the code is for actix-web v4. For actix-web v3 there is no Compat middleware to help you figure out the body type but you can try this if you don't wrap any middleware.

use actix_service::ServiceFactory;
use actix_web::dev::{Body, ServiceRequest, ServiceResponse};
use actix_web::{get, App, Error, HttpServer};

#[actix_web::main]
async fn main() -> std::io::Result<()> {
    HttpServer::new(|| app())
        .bind("127.0.0.1:8080")?
        .run()
        .await
}

fn app() -> App<
    impl ServiceFactory<
        Request = ServiceRequest,
        Config = (),
        Response = ServiceResponse,
        Error = Error,
        InitError = (),
    >,
    Body,
> {
    App::new().service(index)
}

#[get("/hi")]
async fn index() -> &'static str {
    "Hello World!"
}

This is why I said if you don't know how the types return needed to be you would have hard time to figure it out.
How you construct your App could change the returned type and it's up to you to figure that out with your own app.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
N/A Not applicable or remedied without code change.
Projects
None yet
Development

No branches or pull requests

4 participants