> ## Documentation Index
> Fetch the complete documentation index at: https://mintlify.com/tokio-rs/axum/llms.txt
> Use this file to discover all available pages before exploring further.

# Json

> Serialize responses to JSON with automatic content-type handling

The `Json` response type serializes data to JSON and automatically sets the `Content-Type: application/json` header.

## Basic usage

Return any type that implements `serde::Serialize`:

```rust theme={null}
use axum::{Json, routing::get, Router};
use serde::Serialize;
use uuid::Uuid;

#[derive(Serialize)]
struct User {
    id: Uuid,
    username: String,
}

async fn get_user() -> Json<User> {
    let user = User {
        id: Uuid::new_v4(),
        username: "alice".to_string(),
    };
    Json(user)
}

let app = Router::new().route("/user", get(get_user));
```

## How it works

### IntoResponse implementation

The `Json` type implements `IntoResponse` by serializing the inner value using `serde_json`:

```rust theme={null}
impl<T> IntoResponse for Json<T>
where
    T: Serialize,
{
    fn into_response(self) -> Response {
        // Serializes to JSON with initial 128-byte buffer capacity
        // Sets Content-Type: application/json on success
        // Returns 500 Internal Server Error if serialization fails
    }
}
```

See implementation in `axum/src/json.rs:197-232`.

### Serialization behavior

The serialization process:

1. Creates a `BytesMut` buffer with 128-byte initial capacity
2. Serializes the value using `serde_json::to_writer`
3. On success: Returns response with `Content-Type: application/json` header
4. On failure: Returns `500 Internal Server Error` with error message as plain text

## Error handling

If serialization fails (e.g., map with non-string keys), a 500 status code is returned with the error message:

```rust theme={null}
async fn handler() -> Json<HashMap<Vec<u8>, i32>> {
    // This will fail to serialize and return 500
    let map = HashMap::from([(vec![1, 2, 3], 123)]);
    Json(map)
}
```

To prevent status code override on serialization errors, use `ForceStatusCode`:

```rust theme={null}
use axum_core::response::ForceStatusCode;
use axum::http::StatusCode;

// Force 418 status even if serialization fails
let response = (
    ForceStatusCode(StatusCode::IM_A_TEAPOT),
    Json(potentially_failing_data),
);
```

## Response fields

<ResponseField name="Content-Type" type="header">
  Automatically set to `application/json`
</ResponseField>

<ResponseField name="body" type="bytes">
  The serialized JSON bytes
</ResponseField>

## Common patterns

### Returning JSON with custom status

```rust theme={null}
use axum::http::StatusCode;

async fn create_user(/* ... */) -> (StatusCode, Json<User>) {
    let user = create_user_in_db().await;
    (StatusCode::CREATED, Json(user))
}
```

### Returning JSON arrays

```rust theme={null}
async fn list_users() -> Json<Vec<String>> {
    Json(vec!["alice".to_string(), "bob".to_string()])
}
```

## See also

* Extract JSON request bodies using the [Json extractor](/api/extractors/json)
* [IntoResponse trait](/api/responses/into-response) for custom response types
