axum/CHANGELOG.md
David Pedersen c8c8e6509b
Add upgrade examples to the changelog (#245)
Shows how to upgrade

- General routing
- SSE
- WebSockets
2021-08-23 18:24:08 +02:00

12 KiB

Changelog

All notable changes to this project will be documented in this file.

The format is based on Keep a Changelog, and this project adheres to Semantic Versioning.

Unreleased

  • Overall:

    • added: Add default feature tower-log which exposes tower's log feature. (#218)
    • fixed: Overall compile time improvements. If you're having issues with compile time please file an issue! (#184) (#198) (#220)
    • fixed: Remove prelude. Explicit imports are now required (#195)
    • changed: Replace body::BoxStdError with axum::Error, which supports downcasting (#150)
  • Routing:

    • added: Add dedicated Router to replace the RoutingDsl trait (#214)
    • added: Add Router::or for combining routes (#108)
    • fixed: Support matching different HTTP methods for the same route that aren't defined together. So Router::new().route("/", get(...)).route("/", post(...)) now accepts both GET and POST. Previously only POST would be accepted (#224)
    • fixed: get routes will now also be called for HEAD requests but will always have the response body removed (#129)
    • changed: Replace axum::route(...) with axum::Router::new().route(...). This means there is now only one way to create a new router. Same goes for axum::routing::nest. (#215)
    • changed: Implement routing::MethodFilter via bitflags (#158)
    • changed: Move handle_error from ServiceExt to service::OnMethod (#160)

    With these changes this app using 0.1:

    use axum::{extract::Extension, prelude::*, routing::BoxRoute, AddExtensionLayer};
    
    let app = route("/", get(|| async { "hi" }))
        .nest("/api", api_routes())
        .layer(AddExtensionLayer::new(state));
    
    fn api_routes() -> BoxRoute<Body> {
        route(
            "/users",
            post(|Extension(state): Extension<State>| async { "hi from nested" }),
        )
        .boxed()
    }
    

    Becomes this in 0.2:

    use axum::{
        extract::Extension,
        handler::{get, post},
        routing::BoxRoute,
        Router,
    };
    
    let app = Router::new()
        .route("/", get(|| async { "hi" }))
        .nest("/api", api_routes());
    
    fn api_routes() -> Router<BoxRoute> {
        Router::new()
            .route(
                "/users",
                post(|Extension(state): Extension<State>| async { "hi from nested" }),
            )
            .boxed()
    }
    
  • Extractors:

    • added: Make FromRequest default to being generic over body::Body (#146)
    • added: Implement std::error::Error for all rejections (#153)
    • added: Add OriginalUri for extracting original request URI in nested services (#197)
    • added: Implement FromRequest for http::Extensions (#169)
    • added: Make RequestParts::{new, try_into_request} public so extractors can be used outside axum (#194)
    • added: Implement FromRequest for axum::body::Body (#241)
    • changed: Removed extract::UrlParams and extract::UrlParamsMap. Use extract::Path instead (#154)
    • changed: extractor_middleware now requires RequestBody: Default (#167)
    • changed: Convert RequestAlreadyExtracted to an enum with each possible error variant (#167)
    • changed: extract::BodyStream is no longer generic over the request body (#234)
    • changed: extract::Body has been renamed to extract::RawBody to avoid conflicting with body::Body (#233)
    • changed: RequestParts changes (#153)
      • method new returns an &http::Method
      • method_mut new returns an &mut http::Method
      • take_method has been removed
      • uri new returns an &http::Uri
      • uri_mut new returns an &mut http::Uri
      • take_uri has been removed
    • changed: Remove several rejection types that were no longer used (#153) (#154)
  • Responses:

    • added: Add Headers for easily customizing headers on a response (#193)
    • added: Add Redirect response (#192)
    • added: Add body::StreamBody for easily responding with a stream of byte chunks (#237)
    • changed: Add associated Body and BodyError types to IntoResponse. This is required for returning responses with bodies other than hyper::Body from handlers. See the docs for advice on how to implement IntoResponse (#86)
    • changed: tower::util::Either no longer implements IntoResponse (#229)

    This IntoResponse from 0.1:

    use axum::{http::Response, prelude::*, response::IntoResponse};
    
    struct MyResponse;
    
    impl IntoResponse for MyResponse {
        fn into_response(self) -> Response<Body> {
            Response::new(Body::empty())
        }
    }
    

    Becomes this in 0.2:

    use axum::{body::Body, http::Response, response::IntoResponse};
    
    struct MyResponse;
    
    impl IntoResponse for MyResponse {
        type Body = Body;
        type BodyError = <Self::Body as axum::body::HttpBody>::Error;
    
        fn into_response(self) -> Response<Self::Body> {
            Response::new(Body::empty())
        }
    }
    
  • SSE:

    • added: Add response::sse::Sse. This implements SSE using a response rather than a service (#98)
    • changed: Remove axum::sse. Its been replaced by axum::response::sse (#98)

    Handler using SSE in 0.1:

    use axum::{
        prelude::*,
        sse::{sse, Event},
    };
    use std::convert::Infallible;
    
    let app = route(
        "/",
        sse(|| async {
            let stream = futures::stream::iter(vec![Ok::<_, Infallible>(
                Event::default().data("hi there!"),
            )]);
            Ok::<_, Infallible>(stream)
        }),
    );
    

    Becomes this in 0.2:

    use axum::{
        handler::get,
        response::sse::{Event, Sse},
        Router,
    };
    use std::convert::Infallible;
    
    let app = Router::new().route(
        "/",
        get(|| async {
            let stream = futures::stream::iter(vec![Ok::<_, Infallible>(
                Event::default().data("hi there!"),
            )]);
            Sse::new(stream)
        }),
    );
    
  • WebSockets:

    • changed: Change WebSocket API to use an extractor plus a response (#121)
    • changed: Make WebSocket Message an enum (#116)
    • changed: WebSocket now uses Error as its error type (#150)

    Handler using WebSockets in 0.1:

    use axum::{
        prelude::*,
        ws::{ws, WebSocket},
    };
    
    let app = route(
        "/",
        ws(|socket: WebSocket| async move {
            // do stuff with socket
        }),
    );
    

    Becomes this in 0.2:

    use axum::{
        extract::ws::{WebSocket, WebSocketUpgrade},
        handler::get,
        Router,
    };
    
    let app = Router::new().route(
        "/",
        get(|ws: WebSocketUpgrade| async move {
            ws.on_upgrade(|socket: WebSocket| async move {
                // do stuff with socket
            })
        }),
    );
    
  • Misc

    • changed: EmptyRouter now requires the response body to implement Send + Sync + 'static' (#108)
    • changed: Router::check_infallible now returns a CheckInfallible service. This is to improve compile times (#198)
    • changed: Router::into_make_service now returns routing::IntoMakeService rather than tower::make::Shared (#229)
    • changed: All usage of tower::BoxError has been replaced with axum::BoxError (#229)
    • changed: Several response future types have been moved into dedicated future modules (#133)
    • changed: EmptyRouter, ExtractorMiddleware, ExtractorMiddlewareLayer, and QueryStringMissing no longer implement Copy (#132)
    • changed: service::OnMethod, handler::OnMethod, and routing::Nested have new response future types (#157)

0.1.3 (06. August, 2021)

  • Fix stripping prefix when nesting services at / (#91)
  • Add support for WebSocket protocol negotiation (#83)
  • Use pin-project-lite instead of pin-project (#95)
  • Re-export http crate and hyper::Server (#110)
  • Fix Query and Form extractors giving bad request error when query string is empty. (#117)
  • Add Path extractor. (#124)
  • Fixed the implementation of IntoResponse of (HeaderMap, T) and (StatusCode, HeaderMap, T) would ignore headers from T (#137)
  • Deprecate extract::UrlParams and extract::UrlParamsMap. Use extract::Path instead (#138)

0.1.2 (01. August, 2021)

  • Implement Stream for WebSocket (#52)
  • Implement Sink for WebSocket (#52)
  • Implement Deref most extractors (#56)
  • Return 405 Method Not Allowed for unsupported method for route (#63)
  • Add extractor for remote connection info (#55)
  • Improve error message of MissingExtension rejections (#72)
  • Improve documentation for routing (#71)
  • Clarify required response body type when routing to tower::Services (#69)
  • Add axum::body::box_body to converting an http_body::Body to axum::body::BoxBody (#69)
  • Add axum::sse for Server-Sent Events (#75)
  • Mention required dependencies in docs (#77)
  • Fix WebSockets failing on Firefox (#76)

0.1.1 (30. July, 2021)

  • Misc readme fixes.

0.1.0 (30. July, 2021)

  • Initial release.