Commit graph

241 commits

Author SHA1 Message Date
David Pedersen
8a61b9ffe1
Use std::future::ready (#231)
`std::future::ready` has been stable since 1.48 so since axum's MSRV is
1.51 we can use this rather the one from `futures_util`.
2021-08-21 15:18:05 +02:00
David Pedersen
82dc847d47
Fix nest docs inconsistency (#230) 2021-08-21 15:06:15 +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
David Pedersen
35ea7ca0ff
Mention using Path<HashMap> to capture all params (#228)
Might not be entirely obvious that you can do this so makes sense to
mention in the docs.
2021-08-21 14:21:31 +02:00
David Pedersen
0d8f8b7b6c
Fallback to calling next route if no methods match (#224)
This removes a small foot gun from the routing.

This means matching different HTTP methods for the same route that
aren't defined together now works.

So `Router::new().route("/", get(...)).route("/", post(...))` now
accepts both `GET` and `POST`. Previously only `POST` would be accepted.
2021-08-21 01:00:12 +02:00
David Pedersen
971c0a394a
Revert "Simplify handler trait (#221)" (#223)
This reverts commit 44c58bdf5f.
2021-08-20 23:56:16 +02:00
David Pedersen
f984198440
Add more examples to "Building responses" section (#222)
Someone on reddit suggested adding more examples.
2021-08-20 20:50:11 +02:00
David Pedersen
44c58bdf5f
Simplify handler trait (#221)
Rely on the `impl FromRequest for (T, ...)` rather than extracting things directly inside the macro.
2021-08-20 20:36:34 +02:00
David Pedersen
e8bc3f5082
Further compile time improvements (#220)
This improves compiles further when using lots of nested routes. Such as
the example posted
[here](https://github.com/tokio-rs/axum/issues/200#issuecomment-902541073).

It seems rustc is really slow at checking bounds on these kinds of
intermediate builder methods. Should probably file an issue about that.
2021-08-20 19:51:29 +02:00
David Pedersen
23dcf3631e Export Or in a more consistent way 2021-08-19 22:44:26 +02:00
David Pedersen
570e13195c Inline Router in root module docs 2021-08-19 22:39:37 +02:00
David Pedersen
ca4d9a2bb9
Replace route with Router::new().route() (#215)
This way there is now only one way to create a router:

```rust
use axum::{Router, handler::get};

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

`nest` was changed in the same way:

```rust
use axum::Router;

let app = Router::new().nest("/foo", service);
```
2021-08-19 22:37:48 +02:00
David Pedersen
97b53768ba
Replace RoutingDsl trait with Router type (#214)
* Remove `RoutingDsl`

* Fix typo
2021-08-19 21:24:32 +02:00
David Pedersen
0fd17d4181
Bring back Handler::into_service (#212)
It was removed as part of https://github.com/tokio-rs/axum/pull/184 but
I do actually think it has some utility. So makes sense to keep even if
axum doesn't use it directly for routing.
2021-08-19 21:16:44 +02:00
Eduardo Canellas
2d6b5dd0b8
docs: fix typo on EmptyRouter documentation (#204) 2021-08-18 20:30:39 +02:00
David Pedersen
e22045d42f
Change nested routes to see the URI with prefix stripped (#197) 2021-08-18 09:48:36 +02:00
Florian Thelliez
d9a06ef14b
Remove axum::prelude (#195) 2021-08-18 00:04:15 +02:00
David Pedersen
dd0c345040
Improve compile times of handle_error and check_infallible (#198)
* Improve compile times of `handle_error`

This brings the compile time of the example posted [here][example] from
3 seconds down to 0.3 seconds for me.

Having the bounds on the methods does improve UX but not worth
sacrificing 10x compile time for.

[example]: https://github.com/tokio-rs/axum/issues/145#issue-963183256

* Improve compile time of `check_infallible`

* update changelog
2021-08-17 19:07:47 +02:00
David Pedersen
93cdfe8c5f
Work around for http2 hang with Or (#199)
This is a nasty hack that works around
https://github.com/hyperium/hyper/issues/2621.

Fixes https://github.com/tokio-rs/axum/issues/191
2021-08-17 19:00:24 +02:00
David Pedersen
97c140cdf7
Add Headers response (#193)
* Add `Headers`

Example usage:

```rust
use axum::{
    route,
    routing::RoutingDsl,
    response::{IntoResponse, Headers},
    handler::get,
};
use http::header::{HeaderName, HeaderValue};

// It works with any `IntoIterator<Item = (Key, Value)>` where `Key` can be
// turned into a `HeaderName` and `Value` can be turned into a `HeaderValue`
//
// Such as `Vec<(HeaderName, HeaderValue)>`
async fn just_headers() -> impl IntoResponse {
    Headers(vec![
        (HeaderName::from_static("X-Foo"), HeaderValue::from_static("foo")),
    ])
}

// Or `[(&str, &str)]`
async fn from_strings() -> impl IntoResponse {
    Headers([("X-Foo", "foo")])
}
```

Fixes https://github.com/tokio-rs/axum/issues/187

* Make work on Rust versions without `IntoIterator` for arrays

* format

* changelog
2021-08-17 17:28:02 +02:00
David Pedersen
baa99e5084
Make RequestParts::{new, try_into_request} public (#194)
Fixes https://github.com/tokio-rs/axum/issues/147
2021-08-16 20:55:22 +02:00
David Pedersen
b4cbd7f147
Add Redirect response (#192)
* Add `Redirect` response

* Add `Redirect::found`
2021-08-16 19:48:03 +02:00
David Pedersen
dda625759d Fix import 2021-08-16 17:29:47 +02:00
David Pedersen
a128a672a1
Remove allocation when calling handler (#190)
`Handler::call` already returns a boxed future so we don't have to box
it again.
2021-08-16 09:19:37 +02:00
Eduardo Canellas
57e440ed2e
move relevant docs sections to be under "Routing" (#175) 2021-08-16 09:17:26 +02:00
David Pedersen
be7e9e9bc6
Refactor TypedHeader extractor (#189)
I should use `HeaderMapExt::typed_try_get` rather than implementing it
manually.
2021-08-16 09:05:10 +02:00
David Pedersen
48afd30491
Improve compile times (#184)
* Inline `handler::IntoService`

* Inline `BoxResponseBody`

* Add missing debug impl
2021-08-15 23:01:26 +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
David Pedersen
8ef96f2199 Add test for routing matching multiple methods
I don't believe we had a test for this
2021-08-10 10:02:40 +02:00
David Pedersen
a790abca87 More consistent docs 2021-08-08 20:26:42 +02:00
David Pedersen
8500ea256d
Implement FromRequest for http::Extensions (#169)
Not sure its very useful but odd to not provide this. All other request
parts have an extractor and we already have the rejection for it.
2021-08-08 20:01:06 +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
David Pedersen
bc27b09f5c
Make sure nested services still see full URI (#166)
They'd previously see the nested URI as we mutated the request. Now we
always route based on the nested URI (if present) without mutating the
request. Also meant we could get rid of `OriginalUri` which is nice.
2021-08-08 17:27:23 +02:00
David Pedersen
d89d061724
Move some files to mod.rs (#165)
I prefer this setup but didn't wanna do it while there were too many
open PRs.
2021-08-08 16:54:03 +02:00
David Pedersen
b75b7b0184
Re-export more body utilities (#162)
Useful when implementing `IntoResponse`
2021-08-08 16:41:17 +02:00
David Pedersen
b4bdddf9d2
Add NestedUri (#161)
Fixes https://github.com/tokio-rs/axum/issues/159
2021-08-08 14:45:31 +02:00
David Pedersen
8013165908
Move methods from ServiceExt to RoutingDsl (#160)
Previously, on `main`, this wouldn't compile:

```rust
let app = route("/", get(handler))
    .layer(
        ServiceBuilder::new()
            .timeout(Duration::from_secs(10))
            .into_inner(),
    )
    .handle_error(...)
    .route(...); // <-- doesn't work
```

That is because `handle_error` would be
`axum::service::ServiceExt::handle_error` which returns `HandleError<_,
_, _, HandleErrorFromService>` which does _not_ implement `RoutingDsl`.
So you couldn't call `route`. This was caused by
https://github.com/tokio-rs/axum/pull/120.

Basically `handle_error` when called on a `RoutingDsl`, the resulting
service should also implement `RoutingDsl`, but if called on another
random service it should _not_ implement `RoutingDsl`.

I don't think thats possible by having `handle_error` on `ServiceExt`
which is implemented for any service, since all axum routers are also
services by design.

This resolves the issue by removing `ServiceExt` and moving its methods
to `RoutingDsl`. Then we have more tight control over what has a
`handle_error` method.

`service::OnMethod` now also has a `handle_error` so you can still
handle errors from random services, by doing
`service::any(svc).handle_error(...)`.
2021-08-08 14:30:51 +02:00
David Pedersen
9b3f3c9bdf Fix docs typo 2021-08-07 23:37:07 +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
David Pedersen
6ce355cca3
Add unique future types for all services (#157)
So we can more easily change them in the future.
2021-08-07 22:27:27 +02:00
David Pedersen
85bb0158be Fix outdated docs 2021-08-07 22:11:27 +02:00
David Pedersen
c570fb2d52
Fix Uri extractor not being the full URI if using nest (#156) 2021-08-07 22:07:50 +02:00
David Pedersen
a6b3e09827
Remove UrlParamsMap and UrlParams (#154)
Use `extract::Path` instead.
2021-08-07 21:22:08 +02:00
David Pedersen
6a82dd75ea
Implement std::error::Error for all rejections (#153) 2021-08-07 21:03:04 +02:00
David Pedersen
a38d5c3592
Re-export http_body::Body (#152)
Makes writing `IntoResponse` impls easier
2021-08-07 20:29:24 +02:00
David Pedersen
4bb17cbc2d
Remove take_* methods from RequestParts for Version, Method, and Uri (#151)
* Remove `RequestParts::take_method`

* Remove `RequestParts::take_uri`

* Remove `RequestParts::take_version`
2021-08-07 20:24:13 +02:00
David Pedersen
75b5615ccd
Add axum::Error (#150)
Replace `BoxStdError` and supports downcasting
2021-08-07 19:56:44 +02:00
Grzegorz Baranski
4792d0c15c
Make ws::Message an enum for easier frame type matching (#116)
* feat(ws): make Message an enum to allow pattern matching

* fix(examples): update to new websockets `Message`

* fix(ws): remove wildcard imports

* fix(examples/chat): apply clippy's never_loop

* style: `cargo fmt`

* docs:add license notes above parts that are copied

* fix(ws): make CloseCode an alias to u16

* fix: move Message from src/ws/mod.rs to src/extract/ws.rs

* docs: add changelog entry about websocket messages

* fix: remove useless convertions to the same type
2021-08-07 19:47:22 +02:00
David Pedersen
ab927033b3
Support returning any http_body::Body from IntoResponse (#86)
Adds associated `Body` and `BodyError` types to `IntoResponse`. This is required for returning responses with bodies other than `hyper::Body` from handlers. That wasn't previously possible.

This is a breaking change so should be shipped in 0.2.
2021-08-07 18:03:21 +02:00
David Pedersen
4194cf70da
Change WebSocket API to use an extractor (#121)
Fixes https://github.com/tokio-rs/axum/issues/111

Example usage:

```rust
use axum::{
    prelude::*,
    extract::ws::{WebSocketUpgrade, WebSocket},
    response::IntoResponse,
};

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

async fn handler(ws: WebSocketUpgrade) -> impl IntoResponse {
    ws.on_upgrade(handle_socket)
}

async fn handle_socket(mut socket: WebSocket) {
    while let Some(msg) = socket.recv().await {
        let msg = if let Ok(msg) = msg {
            msg
        } else {
            // client disconnected
            return;
        };

        if socket.send(msg).await.is_err() {
            // client disconnected
            return;
        }
    }
}
```
2021-08-07 17:26:23 +02:00
David Pedersen
404a3b5e8a
Add default for RequestParts type param (#148)
Same reason as https://github.com/tokio-rs/axum/pull/146
2021-08-07 17:10:00 +02:00
David Pedersen
045ec57d92
Add RouteDsl::or to combine routes (#108)
With this you'll be able to do:

```rust
let one = route("/foo", get(|| async { "foo" }))
    .route("/bar", get(|| async { "bar" }));

let two = route("/baz", get(|| async { "baz" }));

let app = one.or(two);
```

Fixes https://github.com/tokio-rs/axum/issues/101
2021-08-07 17:09:45 +02:00
David Pedersen
95d7582d28
Fix ServiceExt::handle_error footgun (#120)
As described in
https://github.com/tokio-rs/axum/pull/108#issuecomment-892811637, a
`HandleError` created from `axum::ServiceExt::handle_error` should _not_
implement `RoutingDsl` as that leads to confusing routing behavior.

The technique used here of adding another type parameter to
`HandleError` isn't very clean, I think. But the alternative is
duplicating `HandleError` and having two versions, which I think is less
desirable.
2021-08-07 16:44:12 +02:00
David Pedersen
b5b9db47db
Remove QueryStringMissing as it was no longer being used (#125)
* Remove `QueryStringMissing` as it was no longer being used

* remove it in a few more places
2021-08-07 16:31:51 +02:00
David Pedersen
123b1b3c5e
Remove future re-exports (#133)
These types were moved around in
https://github.com/tokio-rs/axum/pull/130 but re-export from their old
location for backwards compatibility.

This removes the re-exports.
2021-08-07 16:22:53 +02:00
David Pedersen
a0a19c8362
Remove Copy some impls (#132)
https://github.com/tokio-rs/axum/pull/129 was a breaking change, in part
because I had to remove the `Copy` impl from `OnMethod`.

For the sake of future proofing I think we should remove other `Copy`
impls from services as well. We can always bring them back once things
have matured more.

These types no longer implement `Copy`:

- `EmptyRouter`
- `ExtractorMiddleware`
- `ExtractorMiddlewareLayer`
2021-08-07 16:13:56 +02:00
David Pedersen
d7d97a613e Adjust Json docs 2021-08-07 16:10:07 +02:00
Sunli
345163e98d
Common JSON wrapper type for response and request (#140) 2021-08-07 16:07:13 +02:00
David Pedersen
3d45a97db9
Make FromRequest default to use axum::body::Body (#146)
Most users will implement `FromRequest<axum::body::Body>` so making that
the default makes things a bit easier to use.
2021-08-07 12:22:14 +02:00
David Pedersen
904227419c Fix tests for 1.51
They used array `IntoIterator`.
2021-08-07 11:08:20 +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
David Pedersen
811b1d896c
Deprecate extract::UrlParams and extract::UrlParamsMap (#138)
Use `extract::Path` instead. It supports everything the two other do,
and more.
2021-08-06 10:38:38 +02:00
Sunli
a0ac8a5b78
Fixed the implementation of IntoResponse of (HeaderMap, T) and (StatusCode, HeaderMap, T) would ignore headers from T (#137)
Co-authored-by: David Pedersen <david.pdrsn@gmail.com>
2021-08-06 10:31:38 +02:00
Sunli
9fdbd42fba
Implement path extractor (#124)
Fixes #42
2021-08-06 10:17:57 +02:00
David Pedersen
d4ce90e2e6
Move response futures into their own modules (#130)
It cleans up the docs to have the futures in their own modules as users
are unlikely to look at them. Also matches the pattern used in tower
https://docs.rs/tower/0.4.8/tower/util/future/index.html.

Added re-exports to the old locations so its not a breaking change.
2021-08-06 01:15:10 +02:00
David Pedersen
a8eb26b672 Fix typos in rejection messages 2021-08-05 08:36:42 +02:00
David Pedersen
a95b48b70c
Deprecate QueryStringMissing (#119)
Since https://github.com/tokio-rs/axum/pull/117 its no longer used. Will
be removed in 0.2.
2021-08-04 17:58:34 +02:00
Sunli
fb0b3b78eb
Fix Query and Form extractors giving bad request error when query string is empty (#117)
Co-Authored-By: David Pedersen <david.pdrsn@gmail.com>

Co-authored-by: David Pedersen <david.pdrsn@gmail.com>
2021-08-04 17:13:09 +02:00
David Pedersen
5c12328892
Replace hyper::Server with axum::Server in docs (#118)
* Replace `hyper::Server` with `axum::Server` in docs

* Change readme as well
2021-08-04 15:38:51 +02:00
David Pedersen
cffdedc055 Move comments in docs outside code block 2021-08-04 15:07:04 +02:00
David Pedersen
96fac52519 Make docs on required deps more clear 2021-08-04 15:06:47 +02:00
Sunli
7cf8dafdce
Re-export http crate and hyper::Server (#110)
Co-Authored-By: David Pedersen <david.pdrsn@gmail.com>

Co-authored-by: David Pedersen <david.pdrsn@gmail.com>
2021-08-04 12:29:42 +02:00
Jonas Platte
d285dfb568
Tell clippy about MSRV (#114)
* Remove unused import

* Tell clippy about MSRV
2021-08-04 12:15:58 +02:00
Jonas Platte
015f6e0c21
Fix typos found by typos-cli (#113) 2021-08-04 12:09:39 +02:00
David Pedersen
9a6bc4e962
Break up extract.rs (#103)
This breaks up `extract.rs` into several smaller submodules. The public
API remains the same.

This is done in prep for adding more tests to extractors which would get
messy if they were all in the same file.
2021-08-03 21:55:48 +02:00
PatatasDelPapa
715e624d8c
Remove unused imports from example (#104)
Remove unused imports from the first crate documentation example.
2021-08-03 21:55:27 +02:00
Sunli
be68227d73
Use pin-project-lite instead of pin-project (#95) 2021-08-03 09:33:00 +02:00
Sunli
ba74787532
Add support for WebSocket protocol negotiation. (#83) 2021-08-03 08:43:37 +02:00
David Pedersen
6a078ddb71
Fix stripping prefix when nesting at / (#91)
* Fix stripping prefix when nesting at `/`

Fixes https://github.com/tokio-rs/axum/issues/88

* changelog
2021-08-02 22:40:33 +02:00
David Pedersen
a0f6dccc5e Remove dbg! left in by accident 2021-08-02 09:46: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
c232c56de0
Mention required dependencies in docs (#77)
Fixes https://github.com/tokio-rs/axum/issues/70
2021-08-01 21:33:55 +02:00
David Pedersen
69ae7a686a
Fix websockets failing on Firefox (#76)
Axum expected the `Connection` header to be _exactly_ `upgrade`. Turns
out thats a bit too strict as this didn't work in Firefox.

Turns out `Connection` just has to contain `upgrade`. At least that is
what [warp does](https://github.com/seanmonstar/warp/blob/master/src/filters/ws.rs#L46).
2021-08-01 21:00:38 +02:00
jtroo
10bedca796
Fix typos in service docs (#74)
This commit fixes some typos and improves the grammar/structure
of some sections.
2021-08-01 20:55:09 +02:00
David Pedersen
2cf28c6794
Improve error message of MissingExtension rejections (#72)
Now includes the name of missing type.
2021-08-01 15:50:57 +02:00
David Pedersen
6f30d4aa6a
Improve documentation for router (#71)
Fixes #67
2021-08-01 15:42:50 +02:00
David Pedersen
f581e3efb2
Clarify required response body type when routing to tower::Services (#69) 2021-08-01 15:42:12 +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
407aa533d7
Return 405 Method Not Allowed for unsupported method for route (#63)
Fixes https://github.com/tokio-rs/axum/issues/61
2021-07-31 21:05:53 +02:00
songww
49dd1ca49a
Fix docs typo (#58) 2021-07-31 17:17:33 +02:00
David Pedersen
5407247e90
Implement Deref for extractors (#56)
Fixes https://github.com/tokio-rs/axum/issues/54
2021-07-31 14:54:10 +02:00
David Pedersen
d88212c015
Implement Sink and Stream for WebSocket (#52)
Among other things, this makes [`StreamExt::split`](https://docs.rs/futures/0.3.16/futures/stream/trait.StreamExt.html#method.split) accessible so one can read and write at the same time.
2021-07-31 10:51:41 +02:00
Eduardo Canellas
4fbc99c6ef
docs: fix typo (#45) 2021-07-31 00:06:27 +02:00
David Pedersen
6c1279a415 Version 0.1.1 2021-07-30 17:20:38 +02:00
David Pedersen
94d2b5f8a6 Misc readme/docs improvements 2021-07-30 15:51:59 +02:00
David Pedersen
d843f4378b
Make websocket handlers support extractors (#41) 2021-07-30 15:19:53 +02:00
David Pedersen
d927c819d3 Clarify docs around body extractors 2021-07-23 00:27:08 +02:00