Skip to main content

Responses

Crafting advanced HTTP responses.

Actix 4.9+ 4 min read

# Crafting Responses

While returning simple strings or JSON objects is often enough, there are times when you need precise control over the HTTP response—setting headers, cookies, or streaming large bodies. The HttpResponseBuilder is your tool for this.

##HttpResponse Builder

The HttpResponse struct has associated methods corresponding to HTTP status codes, which return an HttpResponseBuilder.

code_blocksrust
use actix_web::{HttpResponse, Responder};

async fn custom_headers() -> impl Responder {
    HttpResponse::Ok()
        .insert_header(("X-RateLimit-Remaining", "42"))
        .content_type("text/plain")
        .body("Header set!")
}

##Cookies

Actix Web provides a Cookie struct in the actix_web::cookie module to handle cookies easily.

code_blocksrust
use actix_web::{cookie::Cookie, HttpResponse, Responder};

async fn set_cookie() -> impl Responder {
    let cookie = Cookie::build("session_id", "xyz123")
        .path("/")
        .secure(true)
        .http_only(true)
        .finish();

    HttpResponse::Ok()
        .cookie(cookie)
        .body("Cookie set")
}

##Streaming Responses

If you need to send a very large file or a stream of data generated on the fly, you shouldn't load the entire payload into memory. Instead, you can return a Stream.

code_blocksrust
use actix_web::{HttpResponse, Responder};
use futures::stream::once;
use bytes::Bytes;
use std::future::ready;

async fn stream_body() -> impl Responder {
    // Creating a very basic stream of a single chunk for demonstration
    let chunk = Bytes::from_static(b"Hello from stream!");
    let stream = once(ready(Ok::<_, actix_web::Error>(chunk)));

    HttpResponse::Ok()
        .content_type("application/octet-stream")
        .streaming(stream)
}

Actix Web is capable of incredibly fast streaming thanks to its non-blocking architecture, making it an excellent choice for video streaming or large file distribution.

Was this page helpful?

Reference Implementation

The following code snippet demonstrates the authoritative pattern for this documentation.

src/main.rs
1use actix_web::{get, HttpResponse, App, HttpServer, Responder};
2
3#[get("/download")]
4async fn download() -> impl Responder {
5 HttpResponse::Ok()
6 .insert_header(("Content-Disposition", "attachment; filename="data.txt""))
7 .body("Some generated data file content")
8}
9
10#[actix_web::main]
11async fn main() -> std::io::Result<()> {
12 HttpServer::new(|| App::new().service(download))
13 .bind("127.0.0.1:8080")?
14 .run()
15 .await
16}
Was this page helpful?