Responses

Response

A builder-like pattern is used to construct an instance of HttpResponse. HttpResponse provides several methods that return a HttpResponseBuilder instance, which implements various convenience methods for building responses.

Check the documentation for type descriptions.

The methods .body, .finish, and .json finalize response creation and return a constructed HttpResponse instance. If this methods is called on the same builder instance multiple times, the builder will panic.

use actix_web::HttpResponse;

fn index() -> HttpResponse {
    HttpResponse::Ok()
        .content_type("plain/text")
        .header("X-Hdr", "sample")
        .body("data")
}

Content encoding

Actix-web can automatically compresses payloads with the Compress middleware. The following codecs are supported:

  • Brotli
  • Gzip
  • Deflate
  • Identity
use actix_web::{middleware, HttpResponse};

fn index_br() -> HttpResponse {
    HttpResponse::Ok().body("data")
}

pub fn main() {
    use actix_web::{web, App, HttpServer};

    HttpServer::new(|| {
        App::new()
            .wrap(middleware::Compress::default())
            .route("/", web::get().to(index_br))
    })
    .bind("127.0.0.1:8088")
    .unwrap()
    .run()
    .unwrap();
}

Response payload is compressed based on the encoding parameter from the middleware::BodyEncoding trait. By default, ContentEncoding::Auto is used. If ContentEncoding::Auto is selected, then the compression depends on the request’s Accept-Encoding header.

ContentEncoding::Identity can be used to disable compression. If another content encoding is selected, the compression is enforced for that codec.

For example, to enable brotli for a single handler use ContentEncoding::Br:

use actix_web::{http::ContentEncoding, middleware::BodyEncoding, HttpResponse};

fn index_br() -> HttpResponse {
    HttpResponse::Ok()
        .encoding(ContentEncoding::Br)
        .body("data")
}

pub fn main() {
    use actix_web::{middleware, web, App, HttpServer};

    HttpServer::new(|| {
        App::new()
            .wrap(middleware::Compress::default())
            .route("/", web::get().to(index_br))
    })
    .bind("127.0.0.1:8088")
    .unwrap()
    .run()
    .unwrap();
}

or for the entire application:

use actix_web::{http::ContentEncoding, middleware::BodyEncoding, HttpResponse};

fn index_br() -> HttpResponse {
    HttpResponse::Ok().body("data")
}

pub fn main() {
    use actix_web::{middleware, web, App, HttpServer};

    HttpServer::new(|| {
        App::new()
            .wrap(middleware::Compress::new(ContentEncoding::Br))
            .route("/", web::get().to(index_br))
    })
    .bind("127.0.0.1:8088")
    .unwrap()
    .run()
    .unwrap();
}

In this case we explicitly disable content compression by setting content encoding to an Identity value:

use actix_web::{
    http::ContentEncoding, middleware, middleware::BodyEncoding, HttpResponse,
};

fn index() -> HttpResponse {
    HttpResponse::Ok()
        // v- disable compression
        .encoding(ContentEncoding::Identity)
        .body("data")
}

pub fn main() {
    use actix_web::{web, App, HttpServer};

    HttpServer::new(|| {
        App::new()
            .wrap(middleware::Compress::default())
            .route("/", web::get().to(index))
    })
    .bind("127.0.0.1:8088")
    .unwrap()
    .run()
    .unwrap();
}

When dealing with an already compressed body (for example when serving assets), set the content encoding to Identity to avoid compressing the already compressed data and set the content-encoding header manually:

use actix_web::{
    http::ContentEncoding, middleware, middleware::BodyEncoding, HttpResponse,
};

static HELLO_WORLD: &[u8] = &[
    0x1f, 0x8b, 0x08, 0x00, 0xa2, 0x30, 0x10, 0x5c, 0x00, 0x03, 0xcb, 0x48, 0xcd, 0xc9,
    0xc9, 0x57, 0x28, 0xcf, 0x2f, 0xca, 0x49, 0xe1, 0x02, 0x00, 0x2d, 0x3b, 0x08, 0xaf,
    0x0c, 0x00, 0x00, 0x00,
];

pub fn index() -> HttpResponse {
    HttpResponse::Ok()
        .encoding(ContentEncoding::Identity)
        .header("content-encoding", "gzip")
        .body(HELLO_WORLD)
}

Also it is possible to set default content encoding on application level, by default ContentEncoding::Auto is used, which implies automatic content compression negotiation.

use actix_web::{http::ContentEncoding, middleware, HttpResponse};

fn index() -> HttpResponse {
    HttpResponse::Ok().body("data")
}

pub fn main() {
    use actix_web::{web, App, HttpServer};

    HttpServer::new(|| {
        App::new()
            .wrap(middleware::Compress::new(ContentEncoding::Br))
            .route("/", web::get().to(index))
    })
    .bind("127.0.0.1:8088")
    .unwrap()
    .run()
    .unwrap();
}

JSON Response

The Json type allows to respond with well-formed JSON data: simply return a value of type Json where T is the type of a structure to serialize into JSON. The type T must implement the Serialize trait from serde.

use actix_web::{web, HttpResponse, Result};
use serde::{Deserialize, Serialize};

#[derive(Serialize, Deserialize)]
struct MyObj {
    name: String,
}

fn index(obj: web::Path<MyObj>) -> Result<HttpResponse> {
    Ok(HttpResponse::Ok().json(MyObj {
        name: obj.name.to_string(),
    }))
}

pub fn main() {
    use actix_web::{App, HttpServer};

    HttpServer::new(|| App::new().route(r"/a/{name}", web::get().to(index)))
        .bind("127.0.0.1:8088")
        .unwrap()
        .run()
        .unwrap();
}

Chunked transfer encoding

Chunked encoding on a response can be enabled with HttpResponseBuilder::chunked(). This takes effect only for Body::Streaming(BodyStream) or Body::StreamingContext bodies. If the response payload compression is enabled and a streaming body is used, chunked encoding is enabled automatically.

Enabling chunked encoding for HTTP/2.0 responses is forbidden.

Next up: Testing