Commit graph

60 commits

Author SHA1 Message Date
David Pedersen
9a082a74b0
Version 0.2.1 (#256)
0.2.1 (24. August, 2021)

- **added:** Add `Redirect::to` constructor ([#255](https://github.com/tokio-rs/axum/pull/255))
- **added:** Document how to implement `IntoResponse` for custom error type ([#258](https://github.com/tokio-rs/axum/pull/258))
2021-08-24 12:53:57 +02:00
David Pedersen
02e61dfdd6
Version 0.2.0 (#247)
- Overall:
  - **fixed:** Overall compile time improvements. If you're having issues with compile time
    please file an issue! ([#184](https://github.com/tokio-rs/axum/pull/184)) ([#198](https://github.com/tokio-rs/axum/pull/198)) ([#220](https://github.com/tokio-rs/axum/pull/220))
  - **changed:** Remove `prelude`. Explicit imports are now required ([#195](https://github.com/tokio-rs/axum/pull/195))
- Routing:
  - **added:** Add dedicated `Router` to replace the `RoutingDsl` trait ([#214](https://github.com/tokio-rs/axum/pull/214))
  - **added:** Add `Router::or` for combining routes ([#108](https://github.com/tokio-rs/axum/pull/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](https://github.com/tokio-rs/axum/pull/224))
  - **fixed:** `get` routes will now also be called for `HEAD` requests but will always have
    the response body removed ([#129](https://github.com/tokio-rs/axum/pull/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](https://github.com/tokio-rs/axum/pull/215))
  - **changed:** Implement `routing::MethodFilter` via [`bitflags`](https://crates.io/crates/bitflags) ([#158](https://github.com/tokio-rs/axum/pull/158))
  - **changed:** Move `handle_error` from `ServiceExt` to `service::OnMethod` ([#160](https://github.com/tokio-rs/axum/pull/160))

  With these changes this app using 0.1:

  ```rust
  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:

  ```rust
  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](https://github.com/tokio-rs/axum/pull/146))
  - **added:** Implement `std::error::Error` for all rejections ([#153](https://github.com/tokio-rs/axum/pull/153))
  - **added:** Add `OriginalUri` for extracting original request URI in nested services ([#197](https://github.com/tokio-rs/axum/pull/197))
  - **added:** Implement `FromRequest` for `http::Extensions` ([#169](https://github.com/tokio-rs/axum/pull/169))
  - **added:** Make `RequestParts::{new, try_into_request}` public so extractors can be used outside axum ([#194](https://github.com/tokio-rs/axum/pull/194))
  - **added:** Implement `FromRequest` for `axum::body::Body` ([#241](https://github.com/tokio-rs/axum/pull/241))
  - **changed:** Removed `extract::UrlParams` and `extract::UrlParamsMap`. Use `extract::Path` instead ([#154](https://github.com/tokio-rs/axum/pull/154))
  - **changed:** `extractor_middleware` now requires `RequestBody: Default` ([#167](https://github.com/tokio-rs/axum/pull/167))
  - **changed:** Convert `RequestAlreadyExtracted` to an enum with each possible error variant ([#167](https://github.com/tokio-rs/axum/pull/167))
  - **changed:** `extract::BodyStream` is no longer generic over the request body ([#234](https://github.com/tokio-rs/axum/pull/234))
  - **changed:** `extract::Body` has been renamed to `extract::RawBody` to avoid conflicting with `body::Body` ([#233](https://github.com/tokio-rs/axum/pull/233))
  - **changed:** `RequestParts` changes ([#153](https://github.com/tokio-rs/axum/pull/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](https://github.com/tokio-rs/axum/pull/153)) ([#154](https://github.com/tokio-rs/axum/pull/154))
- Responses:
  - **added:** Add `Headers` for easily customizing headers on a response ([#193](https://github.com/tokio-rs/axum/pull/193))
  - **added:** Add `Redirect` response ([#192](https://github.com/tokio-rs/axum/pull/192))
  - **added:** Add `body::StreamBody` for easily responding with a stream of byte chunks ([#237](https://github.com/tokio-rs/axum/pull/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](https://github.com/tokio-rs/axum/pull/86))
  - **changed:** `tower::util::Either` no longer implements `IntoResponse` ([#229](https://github.com/tokio-rs/axum/pull/229))

  This `IntoResponse` from 0.1:
  ```rust
  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:
  ```rust
  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](https://github.com/tokio-rs/axum/pull/98))
  - **changed:** Remove `axum::sse`. Its been replaced by `axum::response::sse` ([#98](https://github.com/tokio-rs/axum/pull/98))

  Handler using SSE in 0.1:
  ```rust
  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:

  ```rust
  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](https://github.com/tokio-rs/axum/pull/121))
  - **changed:** Make WebSocket `Message` an enum ([#116](https://github.com/tokio-rs/axum/pull/116))
  - **changed:** `WebSocket` now uses `Error` as its error type ([#150](https://github.com/tokio-rs/axum/pull/150))

  Handler using WebSockets in 0.1:

  ```rust
  use axum::{
      prelude::*,
      ws::{ws, WebSocket},
  };

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

  Becomes this in 0.2:

  ```rust
  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
  - **added:** Add default feature `tower-log` which exposes `tower`'s `log` feature. ([#218](https://github.com/tokio-rs/axum/pull/218))
  - **changed:** Replace `body::BoxStdError` with `axum::Error`, which supports downcasting ([#150](https://github.com/tokio-rs/axum/pull/150))
  - **changed:** `EmptyRouter` now requires the response body to implement `Send + Sync + 'static'` ([#108](https://github.com/tokio-rs/axum/pull/108))
  - **changed:** `Router::check_infallible` now returns a `CheckInfallible` service. This
    is to improve compile times ([#198](https://github.com/tokio-rs/axum/pull/198))
  - **changed:** `Router::into_make_service` now returns `routing::IntoMakeService` rather than
    `tower::make::Shared` ([#229](https://github.com/tokio-rs/axum/pull/229))
  - **changed:** All usage of `tower::BoxError` has been replaced with `axum::BoxError` ([#229](https://github.com/tokio-rs/axum/pull/229))
  - **changed:** Several response future types have been moved into dedicated
    `future` modules ([#133](https://github.com/tokio-rs/axum/pull/133))
  - **changed:** `EmptyRouter`, `ExtractorMiddleware`, `ExtractorMiddlewareLayer`,
    and `QueryStringMissing` no longer implement `Copy` ([#132](https://github.com/tokio-rs/axum/pull/132))
  - **changed:** `service::OnMethod`, `handler::OnMethod`, and `routing::Nested` have new response future types ([#157](https://github.com/tokio-rs/axum/pull/157))
2021-08-23 20:49:29 +02:00
David Pedersen
f8a0d81d79
Remove tower from axum's public API (#229)
Instead rely on `tower-service` and `tower-layer`. `tower` itself is
only used internally.

Fixes https://github.com/tokio-rs/axum/issues/186
2021-08-21 15:01:30 +02:00
Johannes Becker
7350b817b0
expose tower log feature (#218) 2021-08-20 13:41:28 +02:00
simonborje
421faceae3
Update tokio-tungstenite version (#211)
Co-authored-by: Simon Börjesson <no@address.com>
2021-08-19 14:51:21 +02:00
David Pedersen
e22045d42f
Change nested routes to see the URI with prefix stripped (#197) 2021-08-18 09:48:36 +02:00
David Pedersen
6c9651c14a
Move all examples to their own crates (#201)
This makes it much clearer which dependencies each example has.
2021-08-18 00:49:01 +02:00
David Pedersen
995ffc1aa2
Correctly handle HEAD requests (#129) 2021-08-15 20:27:13 +02:00
Kai Jewson
9cd543401f
Implement SSE using responses (#98) 2021-08-14 17:29:09 +02:00
Paolo Barbolini
045287aef9
Reduce futures-util features (#173) 2021-08-10 20:08:44 +02:00
David Pedersen
6b218c7150
Clean up RequestParts API (#167)
In http-body 0.4.3 `BoxBody` implements `Default`. This allows us to
clean up the API of `RequestParts` quite a bit.
2021-08-08 19:48:30 +02:00
fluunke
0674c9136a
Add oauth2 example (#144) 2021-08-08 17:22:24 +02:00
David Pedersen
72071cf5de
Implement MethodFilter via bitflags (#158)
Fixes https://github.com/tokio-rs/axum/issues/107
2021-08-07 23:05:53 +02:00
Jonas Platte
6a042a9b3a
Cleanup CI (#141)
* Feature-gate test that depends on non-default features

Makes `cargo check` work without extra flags.

* Don't set doc(html_root_url)

It is no longer recommended:
https://github.com/rust-lang/api-guidelines/pull/230

* Remove documentation URL from Cargo.toml

crates.io will link to the right version on docs.rs automatically.

* Ensure toolchains installed by actions-rs/toolchain are actually used

* Fix missing rustup component in check job

* Raise MSRV to 1.51

Older versions weren't actually working before.

* Only run clippy & rustfmt on stable toolchain

MSRV is checked in test-versions.

* Allow cargo doc to succeed without headers and multipart features

CI will still ensure that intra-doc links that rely on these are not broken.
2021-08-07 11:06:42 +02:00
David Pedersen
e13f1da11d
Version 0.1.3 (#139)
- Fix stripping prefix when nesting services at `/` ([#91](https://github.com/tokio-rs/axum/pull/91))
- Add support for WebSocket protocol negotiation ([#83](https://github.com/tokio-rs/axum/pull/83))
- Use `pin-project-lite` instead of `pin-project` ([#95](https://github.com/tokio-rs/axum/pull/95))
- Re-export `http` crate and `hyper::Server` ([#110](https://github.com/tokio-rs/axum/pull/110))
- Fix `Query` and `Form` extractors giving bad request error when query string is empty. ([#117](https://github.com/tokio-rs/axum/pull/117))
- Add `Path` extractor. ([#124](https://github.com/tokio-rs/axum/pull/124))
- Fixed the implementation of `IntoResponse` of `(HeaderMap, T)` and `(StatusCode, HeaderMap, T)` would ignore headers from `T` ([#137](https://github.com/tokio-rs/axum/pull/137))
- Deprecate `extract::UrlParams` and `extract::UrlParamsMap`. Use `extract::Path` instead ([#138](https://github.com/tokio-rs/axum/pull/138))
2021-08-06 11:20:42 +02:00
Sunli
09ecd42b32
Add async-graphql example (#93)
Fixes https://github.com/tokio-rs/axum/issues/68
2021-08-04 12:10:20 +02:00
Sunli
be68227d73
Use pin-project-lite instead of pin-project (#95) 2021-08-03 09:33:00 +02:00
David Pedersen
9fbababc3a
Make it clear how to run all examples (#92)
* Handle errors in websocket example

* Make it clear how to run all examples
2021-08-02 23:09:09 +02:00
Javier Viola
c6b7ad0f33
Add chat example documentation. (#85) 2021-08-02 21:42:10 +02:00
minghuaw
ee9032b9d1
Changed http-body dependency version to 0.4.2 (#81) 2021-08-01 23:09:08 +02:00
David Pedersen
55c1a29420
Version 0.1.2 (#80) 2021-08-01 22:13:43 +02:00
David Pedersen
6d787665d6
Server-Sent Events (#75)
Example usage:

```rust
use axum::{prelude::*, sse::{sse, Event, KeepAlive}};
use tokio_stream::StreamExt as _;
use futures::stream::{self, Stream};
use std::{
    time::Duration,
    convert::Infallible,
};

let app = route("/sse", sse(make_stream).keep_alive(KeepAlive::default()));

async fn make_stream(
    // you can also put extractors here
) -> Result<impl Stream<Item = Result<Event, Infallible>>, Infallible> {
    // A `Stream` that repeats an event every second
    let stream = stream::repeat_with(|| Event::default().data("hi!"))
        .map(Ok)
        .throttle(Duration::from_secs(1));

    Ok(stream)
}
```

Implementation is based on [warp's](https://github.com/seanmonstar/warp/blob/master/src/filters/sse.rs)
2021-08-01 21:49:17 +02:00
David Pedersen
ea82acd175
Add sessions and cookies examples (#65)
Uses [`async-session`](https://crates.io/crates/async-session).
2021-08-01 09:15:44 +02:00
programatik29
3b579c7215
Add TLS example (with rustls) (#57) 2021-08-01 08:32:47 +02:00
David Pedersen
f67abd1ee2
Add extractor for remote connection info (#55)
Fixes https://github.com/tokio-rs/axum/issues/43

With this you can get the remote address like so:

```rust
use axum::{prelude::*, extract::ConnectInfo};
use std::net::SocketAddr;

let app = route("/", get(handler));

async fn handler(ConnectInfo(addr): ConnectInfo<SocketAddr>) -> String {
    format!("Hello {}", addr)
}

// Starting the app with `into_make_service_with_connect_info` is required
// for `ConnectInfo` to work.
let make_svc = app.into_make_service_with_connect_info::<SocketAddr, _>();

hyper::Server::bind(&"0.0.0.0:3000".parse().unwrap())
    .serve(make_svc)
    .await
    .expect("server failed");
```

This API is fully generic and supports whatever transport layer you're using with Hyper. I've updated the unix domain socket example to extract `peer_creds` and `peer_addr`.
2021-07-31 21:36:30 +02:00
David Pedersen
6c1279a415 Version 0.1.1 2021-07-30 17:20:38 +02:00
David Pedersen
272e22a23b Release prep 2021-07-30 15:56:01 +02:00
David Pedersen
ba9c03d146 Update links 2021-07-22 19:39:08 +02:00
David Pedersen
6705e79ed7
Add todos example (#38) 2021-07-22 15:38:32 +02:00
David Pedersen
028c472c84
Add Multipart extractor for consuming multipart/form-data requests (#32)
Multipart implementation on top of `multer`
2021-07-14 16:53:37 +02:00
David Pedersen
e641caefaf
Remove hyper-h1 and hyper-h2 features (#31) 2021-07-14 16:29:06 +02:00
David Pedersen
5a5710d290
Rename to axum (#28) 2021-07-09 21:36:14 +02:00
David Pedersen
c4d266e94d
Allow errors (#26)
This changes error model to actually allow errors. I think if we're going to use this for things like tonic's route we need a more flexible error handling model. The same `handle_error` adaptors are still there but services aren't required to have `Infallible` as their error type. The error type is simply propagated all the way through.
2021-07-05 16:18:39 +02:00
David Pedersen
356f1c8424
Generic request body (#22)
Fixes #21
2021-06-19 12:50:33 +02:00
David Pedersen
6a16cd40ca
Add error handling and dependency injection example (#23) 2021-06-19 12:34:42 +02:00
David Pedersen
8a82fd00aa
Add bb8 connection pool example (#19)
I figure this will be quite common.
2021-06-15 22:25:41 +02:00
David Pedersen
b6e67eefd7
Add support for extracting typed headers (#18)
Uses the `headers` crate.
2021-06-15 21:27:21 +02:00
David Pedersen
2f6699aeae
Add HTML template example (#17) 2021-06-13 13:58:12 +02:00
David Pedersen
1002685a20
Rename to awebframework (#13) 2021-06-13 11:22:02 +02:00
David Pedersen
04d62798b6
Reduce body boxing (#9)
Previously, when routing between one or two requests the two body types
would be merged by boxing them. This isn't ideal since it introduces a
layer indirection for each route.

We can't require the services to be routed between as not all services
use the same body type.

This changes that so it instead uses an `Either` enum that implements
`http_body::Body` if each variant does. Will reduce the overall
allocations and hopefully the compiler can optimize things if both
variants are the same.
2021-06-12 23:59:18 +02:00
David Pedersen
b3bc4e024c
Add RoutingDsl::{serve, into_make_service} (#8) 2021-06-12 21:44:40 +02:00
David Pedersen
c9c507aece
Add support for websockets (#3)
Basically a copy/paste of whats in warp.

Example usage:

```rust
use tower_web::{prelude::*, ws::{ws, WebSocket}};

let app = route("/ws", ws(handle_socket));

async fn handle_socket(mut socket: WebSocket) {
    while let Some(msg) = socket.recv().await {
        let msg = msg.unwrap();
        socket.send(msg).await.unwrap();
    }
}
```
2021-06-12 20:50:30 +02:00
David Pedersen
002e3f92b3
Misc repo setup (#7) 2021-06-12 20:18:21 +02:00
David Pedersen
099e886575 Notes on backpressure 2021-06-08 23:55:25 +02:00
David Pedersen
21872c9f7a Remove some unnecessary dependencies 2021-06-08 22:27:38 +02:00
David Pedersen
1f8b39f05d More docs and expand key_value_store example 2021-06-08 12:43:16 +02:00
David Pedersen
a005427d40 Write some docs 2021-06-06 15:19:54 +02:00
David Pedersen
c3977d0b71 Change routing DSL 2021-06-04 01:00:48 +02:00
David Pedersen
00737c4e0a checkpoint 2021-06-02 22:07:37 +02:00
David Pedersen
ea582ab8d9 Quality of life improvements 2021-06-01 14:52:18 +02:00