Skip to main content

App

Struct App 

Source
pub struct App<St: State, In = (), Out = In, M = Identity, F = Filter<St, In>> { /* private fields */ }
Expand description

The main builder for a web application.

Start with App::new() then add routes, resources, scopes, middleware, filters, application state, and a fallback response.

Middleware and filters run before routing. ntex then chooses the resource or scope that matches the request. If nothing matches, the application returns 404 Not Found unless you provide a custom fallback.

Add application-wide settings, such as middleware, filters, App::with_config(), and case-insensitive routing, before adding the first route or service. After that, the builder becomes AppServices, where you can continue adding routes and services.

use ntex::web::{self, middleware, App, HttpResponse};

App::default()
    .middleware(middleware::Logger::default())
    .service(
        web::resource("/users")
            .route(web::get().to(async || "users"))
            .route(web::post().to(async || HttpResponse::Created())),
    )
    .default_service(
        web::to(async || HttpResponse::NotFound().body("Not found")),
    );

Implementations§

Source§

impl<St: State, In> App<St, In, In>

Source

pub fn new() -> Self

Create application builder. Application can be configured with a builder-like pattern.

Source§

impl<St, In, Out, M, F> App<St, In, Out, M, F>
where St: State, In: 'static, Out: 'static, F: ServiceFactory<St, WebRequest<In>, Res = WebRequest<Out>, Error = WebError<St, St::Error>, InitError = Failure>,

Source

pub fn configure( self, f: impl FnOnce(&mut ServiceConfig<St, Out>), ) -> AppServices<St, In, Out, M, F>

Run external configuration as part of the application building process.

This function is useful for moving parts of configuration to a different module or even library. For example, some of the resource’s configuration could be moved to different module.

ⓘ
use ntex::web::{self, middleware, App, HttpResponse};

// this function could be located in different module
fn config(cfg: &mut web::ServiceConfig) {
    cfg.service(web::resource("/test")
        .route(web::get().to(async || { HttpResponse::Ok() }))
        .route(web::head().to(async || { HttpResponse::MethodNotAllowed() }))
    );
}

fn main() {
    let app = App::default()
        .middleware(middleware::Logger::default())
        .configure(config)  // <- register resources
        .route("/index.html", web::get().to(async || { HttpResponse::Ok() }));
}
Source

pub fn route( self, path: &str, route: Route<St, Out>, ) -> AppServices<St, In, Out, M, F>

Register a route for an application path.

This is shorthand for creating a Resource with one route and registering it with App::service(). The route’s method and custom guards are promoted to resource guards.

Each call creates a separate resource, so the same path can be registered more than once with different guards.

use ntex::web::{self, App, HttpResponse};

App::default()
    .route("/items", web::get().to(async || "list"))
    .route("/items", web::post().to(async || HttpResponse::Created()));
Source

pub fn service<S>(self, factory: S) -> AppServices<St, In, Out, M, F>
where S: WebServiceFactory<St, Out> + 'static,

Registers a web service with the application.

A service defines its own path and guards through WebServiceFactory. Common services include Resource, Scope, handlers created with route attribute macros, and custom services built with web::service().

Use a resource to group several routes, filters, middleware, or a fallback under one path. Use a scope to group services under a shared path prefix.

If no registered service matches the request path and guards, the application’s default service is used.

use ntex::web::{self, App, HttpResponse};

App::default()
    .service(
        web::resource("/users")
            .route(web::get().to(async || "users"))
            .route(web::post().to(async || HttpResponse::Created())),
    )
    .service(
        web::scope("/api")
            .route("/health", web::get().to(async || "OK")),
    );
Source

pub fn default_service<U>( self, f: impl IntoServiceFactory<U, St, WebRequest<Out>>, ) -> AppServices<St, In, Out, M, F>
where U: ServiceFactory<St, WebRequest<Out>, Res = WebResponse> + 'static, U::Error: WebResponseError<St, St::Error>, U::InitError: IntoFailure,

Set the fallback service for unmatched application requests.

The fallback is called when no top-level resource or scope matches the request path and guards. Without a custom fallback, the application returns 404 Not Found.

A matched resource or scope handles its own routing failures, so its requests do not fall through to this service.

use ntex::web::{self, App, HttpRequest, HttpResponse};

async fn not_found(req: HttpRequest) -> HttpResponse {
    HttpResponse::NotFound()
        .body(format!("No resource for {}", req.path()))
}

App::default()
    .route("/health", web::get().to(async || "ready"))
    .default_service(web::to(not_found));
Source

pub fn external_resource( self, name: impl AsRef<str>, url: impl AsRef<str>, ) -> Self

Register an external resource.

External resources are useful for URL generation purposes only and are never considered for matching at request time. Calls to HttpRequest::url_for() will work as expected.

use ntex::web::{self, App, HttpRequest, HttpResponse, error::UrlGenerationError};

async fn index(req: HttpRequest) -> Result<HttpResponse, UrlGenerationError> {
    let url = req.url_for("youtube", &["asdlkjqme"])?;
    assert_eq!(url.as_str(), "https://youtube.com/watch/asdlkjqme");
    Ok(HttpResponse::Ok().into())
}

fn main() {
    let app = App::default()
        .external_resource("youtube", "https://youtube.com/watch/{video_id}")
        .service(web::resource("/index.html").route(
            web::get().to(index)));
}
Source

pub fn with_config(self, cfg: impl Into<Cfg<WebAppConfig>>) -> Self

Set the application’s runtime configuration.

WebAppConfig contains connection metadata used by the application, such as the host, secure-connection flag, local address, and request pool size. It can also store typed configuration values with WebAppConfig::set_state(); those values are available through HttpRequest::app_state() and WebRequest::app_state().

Without an explicit configuration, each request uses the WebAppConfig from its I/O context, or the default configuration if the request has no associated I/O object. This method overrides that selection for every request handled by this application.

This configuration is separate from the service-level application state represented by St. To register routes and services from an external function, use App::configure() instead.

use ntex::web::{self, App, HttpRequest, WebAppConfig};

async fn index(req: HttpRequest) -> String {
    let value = req.app_state::<usize>().copied().unwrap_or_default();
    format!("Configured value: {value}")
}

let config = WebAppConfig::new()
    .set_host("www.example.com".to_owned())
    .set_secure()
    .set_state(42usize);

App::default()
    .with_config(config)
    .route("/", web::get().to(index));
Source

pub fn filter<Sf, R>( self, filter: impl IntoServiceFactory<Sf, St, WebRequest<Out>>, ) -> App<St, In, R, M, impl ServiceFactory<St, WebRequest<In>, Res = WebRequest<R>, Error = WebError<St, St::Error>, InitError = Failure>>
where Sf: ServiceFactory<St, WebRequest<Out>, Res = WebRequest<R>>, Sf::Error: WebResponseError<St, St::Error>, Sf::InitError: IntoFailure,

Registers a request filter.

Application filters run before the application router selects a resource or scope. Filters are called in registration order, and each filter receives the WebRequest returned by the previous one.

A filter can inspect or modify the request, or use WebRequest::map_state() to change its request-local state type. It must return another WebRequest to continue processing. Returning an error stops the filter chain and prevents routing; the error is handled through WebResponseError.

Application middleware wraps the filter and router, so middleware runs before filters on the inbound path.

use std::convert::Infallible;
use ntex::web::{self, App, WebRequest};

async fn authenticate(
    req: WebRequest<()>,
) -> Result<WebRequest<&'static str>, Infallible> {
    Ok(req.map_state(|()| "alice"))
}

async fn index(_state: &(), user: &'static str) -> String {
    format!("Hello, {user}!")
}

App::new()
    .filter(authenticate)
    .route("/", web::get().to_with_state(index));
Source

pub fn middleware<U>(self, mw: U) -> App<St, In, Out, WebStack<St, U, M>, F>

Registers a middleware for this application.

Use application middleware for work that should apply to every request, such as logging, response headers, or authentication. It runs before the application filter and router on the way in, and can inspect or modify the response on the way back.

Middleware may also return a response without calling the service it wraps. In that case, the rest of the application pipeline is skipped.

Requests pass through middleware in the order it was added. Responses travel back in the opposite order. In this example, DefaultHeaders sees the request before Logger, while Logger sees the response before DefaultHeaders.

Custom middleware should call the wrapped service through Ctx::call() so readiness and lifecycle events are handled correctly.

use ntex::web::{self, middleware, App};

App::default()
    .middleware(
        middleware::DefaultHeaders::new()
            .header("x-application", "example"),
    )
    .middleware(middleware::Logger::default())
    .route("/", web::get().to(async || "Hello"));
Source

pub fn case_insensitive_routing(self) -> Self

Use ascii case-insensitive routing.

Only static segments could be case-insensitive.

Trait Implementations§

Source§

impl<St: State, In, Out, M, F> Debug for App<St, In, Out, M, F>

Source§

fn fmt(&self, __derive_more_f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl Default for App<()>

Source§

fn default() -> Self

Returns the “default value” for a type. Read more

Auto Trait Implementations§

§

impl<St, In = (), Out = In, M = Identity, F = Filter<St, In>> !Freeze for App<St, In, Out, M, F>

§

impl<St, In = (), Out = In, M = Identity, F = Filter<St, In>> !RefUnwindSafe for App<St, In, Out, M, F>

§

impl<St, In = (), Out = In, M = Identity, F = Filter<St, In>> !Send for App<St, In, Out, M, F>

§

impl<St, In = (), Out = In, M = Identity, F = Filter<St, In>> !Sync for App<St, In, Out, M, F>

§

impl<St, In = (), Out = In, M = Identity, F = Filter<St, In>> !UnwindSafe for App<St, In, Out, M, F>

§

impl<St, In, Out, M, F> Unpin for App<St, In, Out, M, F>
where M: Unpin, F: Unpin, Out: Unpin, St: Unpin, In: Unpin,

§

impl<St, In, Out, M, F> UnsafeUnpin for App<St, In, Out, M, F>
where M: UnsafeUnpin, F: UnsafeUnpin,

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.