The problem with Go’s default HTTP handlers
I like the way Axum for Rust handles this.  All response handlers return something that implements IntoResponse.  Lots of types implement IntoResponse, thus making the simple cases really streamlined.async fn create_user(
    Json(payload): Json,
) -> impl IntoResponse {    let user = User {
        id: 1337,
        username: payload.username,
    };

    // this will be converted into a JSON response
    // with a status code of `201 Created`
    (StatusCode::CREATED, Json(user))
}If the handler is complex enough that branches can't all return the same type, you can just add .into_response() to each return site, and now you're just returning a response, which also implements IntoResponse (as a no-op).This avoids the problem discussed in this article while also avoiding much of the boilerplate of manually building responses.