mirror of
https://github.com/robertwayne/axum-htmx
synced 2024-11-25 20:59:35 +01:00
Docs
This commit is contained in:
parent
13fb55de9a
commit
39e6f9028b
3 changed files with 49 additions and 16 deletions
36
README.md
36
README.md
|
@ -23,6 +23,7 @@
|
||||||
- [Getting Started](#getting-started)
|
- [Getting Started](#getting-started)
|
||||||
- [Extractors](#extractors)
|
- [Extractors](#extractors)
|
||||||
- [Responders](#responders)
|
- [Responders](#responders)
|
||||||
|
- [Auto Caching Management](#auto-caching-management)
|
||||||
- [Request Guards](#request-guards)
|
- [Request Guards](#request-guards)
|
||||||
- [Examples](#examples)
|
- [Examples](#examples)
|
||||||
- [Example: Extractors](#example-extractors)
|
- [Example: Extractors](#example-extractors)
|
||||||
|
@ -76,6 +77,8 @@ any of your responses.
|
||||||
| `HX-Trigger-After-Settle` | `HxResponseTrigger` | `axum_htmx::serde::HxEvent` |
|
| `HX-Trigger-After-Settle` | `HxResponseTrigger` | `axum_htmx::serde::HxEvent` |
|
||||||
| `HX-Trigger-After-Swap` | `HxResponseTrigger` | `axum_htmx::serde::HxEvent` |
|
| `HX-Trigger-After-Swap` | `HxResponseTrigger` | `axum_htmx::serde::HxEvent` |
|
||||||
|
|
||||||
|
### Vary Responders
|
||||||
|
|
||||||
Also, there are corresponding cache-related headers, which you may want to add to
|
Also, there are corresponding cache-related headers, which you may want to add to
|
||||||
`GET` responses, depending on the htmx headers.
|
`GET` responses, depending on the htmx headers.
|
||||||
|
|
||||||
|
@ -85,7 +88,7 @@ you need to add `Vary: HX-Request`. That causes the cache to be keyed based on a
|
||||||
composite of the response URL and the `HX-Request` request header - rather than
|
composite of the response URL and the `HX-Request` request header - rather than
|
||||||
being based just on the response URL._
|
being based just on the response URL._
|
||||||
|
|
||||||
Refer to [caching htmx docs section](https://htmx.org/docs/#caching) for details.
|
Refer to [caching htmx docs section][htmx-caching] for details.
|
||||||
|
|
||||||
| Header | Responder |
|
| Header | Responder |
|
||||||
|-------------------------|---------------------|
|
|-------------------------|---------------------|
|
||||||
|
@ -94,10 +97,27 @@ Refer to [caching htmx docs section](https://htmx.org/docs/#caching) for details
|
||||||
| `Vary: HX-Trigger` | `VaryHxTrigger` |
|
| `Vary: HX-Trigger` | `VaryHxTrigger` |
|
||||||
| `Vary: HX-Trigger-Name` | `VaryHxTriggerName` |
|
| `Vary: HX-Trigger-Name` | `VaryHxTriggerName` |
|
||||||
|
|
||||||
|
Look at the [Auto Caching Management](#auto-caching-management) section for
|
||||||
|
automatic `Vary` headers management.
|
||||||
|
|
||||||
|
## Auto Caching Management
|
||||||
|
|
||||||
|
__Requires feature `auto-vary`.__
|
||||||
|
|
||||||
|
Manual use of [Vary Reponders](#vary-responders) adds fragility to the code,
|
||||||
|
because of the need to manually control correspondence between used extractors
|
||||||
|
and the responders.
|
||||||
|
|
||||||
|
We provide a [middleware](crate::AutoVaryLayer) to address this issue by
|
||||||
|
automatically adding `Vary` headers when corresponding extractors are used.
|
||||||
|
For example, on extracting [`HxRequest`], the middleware automatically adds
|
||||||
|
`Vary: hx-request` header to the response.
|
||||||
|
|
||||||
|
Look at the usage [example][auto-vary-example].
|
||||||
|
|
||||||
## Request Guards
|
## Request Guards
|
||||||
|
|
||||||
__Requires features `guards`.__
|
__Requires feature `guards`.__
|
||||||
|
|
||||||
In addition to the extractors, there is also a route-wide layer request guard
|
In addition to the extractors, there is also a route-wide layer request guard
|
||||||
for the `HX-Request` header. This will redirect any requests without the header
|
for the `HX-Request` header. This will redirect any requests without the header
|
||||||
|
@ -207,10 +227,11 @@ fn router_two() -> Router {
|
||||||
## Feature Flags
|
## Feature Flags
|
||||||
|
|
||||||
<!-- markdownlint-disable -->
|
<!-- markdownlint-disable -->
|
||||||
| Flag | Default | Description | Dependencies |
|
| Flag | Default | Description | Dependencies |
|
||||||
|----------|----------|------------------------------------------------------------|---------------------------------------------|
|
|-------------|----------|------------------------------------------------------------|---------------------------------------------|
|
||||||
| `guards` | Disabled | Adds request guard layers. | `tower`, `futures-core`, `pin-project-lite` |
|
| `auto-vary` | Disabled | A middleware to address [HTMx caching issue][htmx-caching] | `futures`, `tokio`, `tower` |
|
||||||
| `serde` | Disabled | Adds serde support for the `HxEvent` and `LocationOptions` | `serde`, `serde_json` |
|
| `guards` | Disabled | Adds request guard layers. | `tower`, `futures-core`, `pin-project-lite` |
|
||||||
|
| `serde` | Disabled | Adds serde support for the `HxEvent` and `LocationOptions` | `serde`, `serde_json` |
|
||||||
<!-- markdownlint-enable -->
|
<!-- markdownlint-enable -->
|
||||||
|
|
||||||
## Contributing
|
## Contributing
|
||||||
|
@ -233,3 +254,6 @@ cargo +nightly test --all-features
|
||||||
- **[Apache License, Version 2.0](/LICENSE-APACHE)**
|
- **[Apache License, Version 2.0](/LICENSE-APACHE)**
|
||||||
|
|
||||||
at your option.
|
at your option.
|
||||||
|
|
||||||
|
[htmx-caching]: https://htmx.org/docs/#caching
|
||||||
|
[auto-vary-example]: https://github.com/robertwayne/axum-htmx/blob/main/examples/auto-vary.rs
|
||||||
|
|
|
@ -1,3 +1,6 @@
|
||||||
|
//! A middleware to automatically add a `Vary` header when needed to address
|
||||||
|
//! [HTMx caching issue](https://htmx.org/docs/#caching)
|
||||||
|
|
||||||
use std::{
|
use std::{
|
||||||
sync::Arc,
|
sync::Arc,
|
||||||
task::{Context, Poll},
|
task::{Context, Poll},
|
||||||
|
@ -19,10 +22,24 @@ use crate::{
|
||||||
headers::{HX_REQUEST_STR, HX_TARGET_STR, HX_TRIGGER_NAME_STR, HX_TRIGGER_STR},
|
headers::{HX_REQUEST_STR, HX_TARGET_STR, HX_TRIGGER_NAME_STR, HX_TRIGGER_STR},
|
||||||
HxError,
|
HxError,
|
||||||
};
|
};
|
||||||
|
#[cfg(doc)]
|
||||||
|
use crate::{HxRequest, HxTarget, HxTrigger, HxTriggerName};
|
||||||
|
|
||||||
const MIDDLEWARE_DOUBLE_USE: &str =
|
const MIDDLEWARE_DOUBLE_USE: &str =
|
||||||
"Configuration error: `axum_httpx::vary_middleware` is used twice";
|
"Configuration error: `axum_httpx::vary_middleware` is used twice";
|
||||||
|
|
||||||
|
/// Addresses [HTMx caching issue](https://htmx.org/docs/#caching)
|
||||||
|
/// by automatically adding a corresponding `Vary` header when [`HxRequest`], [`HxTarget`],
|
||||||
|
/// [`HxTrigger`], [`HxTriggerName`] or their combination is used.
|
||||||
|
#[derive(Clone)]
|
||||||
|
pub struct AutoVaryLayer;
|
||||||
|
|
||||||
|
/// Tower service for [`AutoVaryLayer`]
|
||||||
|
#[derive(Clone)]
|
||||||
|
pub struct AutoVaryMiddleware<S> {
|
||||||
|
inner: S,
|
||||||
|
}
|
||||||
|
|
||||||
pub(crate) trait Notifier {
|
pub(crate) trait Notifier {
|
||||||
fn sender(&mut self) -> Option<Sender<()>>;
|
fn sender(&mut self) -> Option<Sender<()>>;
|
||||||
|
|
||||||
|
@ -65,9 +82,6 @@ define_notifiers!(
|
||||||
HxTriggerNameExtracted
|
HxTriggerNameExtracted
|
||||||
);
|
);
|
||||||
|
|
||||||
#[derive(Default, Clone)]
|
|
||||||
pub struct AutoVaryLayer;
|
|
||||||
|
|
||||||
impl<S> Layer<S> for AutoVaryLayer {
|
impl<S> Layer<S> for AutoVaryLayer {
|
||||||
type Service = AutoVaryMiddleware<S>;
|
type Service = AutoVaryMiddleware<S>;
|
||||||
|
|
||||||
|
@ -76,11 +90,6 @@ impl<S> Layer<S> for AutoVaryLayer {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone)]
|
|
||||||
pub struct AutoVaryMiddleware<S> {
|
|
||||||
inner: S,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<S> Service<Request> for AutoVaryMiddleware<S>
|
impl<S> Service<Request> for AutoVaryMiddleware<S>
|
||||||
where
|
where
|
||||||
S: Service<Request, Response = Response> + Send + 'static,
|
S: Service<Request, Response = Response> + Send + 'static,
|
||||||
|
|
|
@ -7,7 +7,7 @@ pub use error::*;
|
||||||
|
|
||||||
#[cfg(feature = "auto-vary")]
|
#[cfg(feature = "auto-vary")]
|
||||||
#[cfg_attr(feature = "unstable", doc(cfg(feature = "auto-vary")))]
|
#[cfg_attr(feature = "unstable", doc(cfg(feature = "auto-vary")))]
|
||||||
mod auto_vary;
|
pub mod auto_vary;
|
||||||
pub mod extractors;
|
pub mod extractors;
|
||||||
#[cfg(feature = "guards")]
|
#[cfg(feature = "guards")]
|
||||||
#[cfg_attr(feature = "unstable", doc(cfg(feature = "guards")))]
|
#[cfg_attr(feature = "unstable", doc(cfg(feature = "guards")))]
|
||||||
|
@ -18,7 +18,7 @@ pub mod responders;
|
||||||
#[cfg(feature = "auto-vary")]
|
#[cfg(feature = "auto-vary")]
|
||||||
#[cfg_attr(feature = "unstable", doc(cfg(feature = "auto-vary")))]
|
#[cfg_attr(feature = "unstable", doc(cfg(feature = "auto-vary")))]
|
||||||
#[doc(inline)]
|
#[doc(inline)]
|
||||||
pub use auto_vary::AutoVaryLayer;
|
pub use auto_vary::*;
|
||||||
#[doc(inline)]
|
#[doc(inline)]
|
||||||
pub use extractors::*;
|
pub use extractors::*;
|
||||||
#[cfg(feature = "guards")]
|
#[cfg(feature = "guards")]
|
||||||
|
|
Loading…
Reference in a new issue