1
0
mirror of https://github.com/actix/examples synced 2025-06-26 17:17:42 +02:00

add guard example

closes #533
This commit is contained in:
Rob Ede
2022-03-05 14:28:43 +00:00
parent c3fd8e1315
commit b8fc58bec6
6 changed files with 123 additions and 1 deletions

7
guards/Cargo.toml Normal file
View File

@ -0,0 +1,7 @@
[package]
name = "guards"
version = "1.0.0"
edition = "2021"
[dependencies]
actix-web = "4"

34
guards/README.md Normal file
View File

@ -0,0 +1,34 @@
# guards
Shows how to set up custom routing guards.
- Routing different API versions using a header instead of path.
## Usage
### Running The Server
```sh
cd guards
cargo run --bin=guards
```
### Available Routes
#### `GET /api/hello`
Requires the `Accept-Version` header to be present and set to `1` or `2`.
Using [HTTPie]:
```sh
http :8080/api/hello Accept-Version:1
```
Using [cURL]:
```sh
curl 'localhost:8080/api/hello' -H 'accept-version: 1'
```
[HTTPie]: https://httpie.org
[cURL]: https://curl.haxx.se

73
guards/src/main.rs Normal file
View File

@ -0,0 +1,73 @@
use actix_web::{
body::MessageBody,
dev::{ServiceFactory, ServiceRequest, ServiceResponse},
get,
guard::{Guard, GuardContext},
middleware::DefaultHeaders,
web, App, Error, HttpServer, Responder,
};
mod v1 {
use super::*;
pub struct ApiGuard;
impl Guard for ApiGuard {
fn check(&self, ctx: &GuardContext<'_>) -> bool {
ctx.head()
.headers()
.get("Accept-Version")
.map_or(false, |hv| hv.as_bytes() == b"1")
}
}
#[get("/hello")]
pub async fn hello() -> impl Responder {
"Hello World from v1 API!"
}
}
mod v2 {
use super::*;
pub struct ApiGuard;
impl Guard for ApiGuard {
fn check(&self, ctx: &GuardContext<'_>) -> bool {
ctx.head()
.headers()
.get("Accept-Version")
.map_or(false, |hv| hv.as_bytes() == b"2")
}
}
#[get("/hello")]
pub async fn hello() -> impl Responder {
"Hello World from the awesome new v2 API!"
}
}
fn create_app() -> App<
impl ServiceFactory<
ServiceRequest,
Response = ServiceResponse<impl MessageBody>,
Config = (),
InitError = (),
Error = Error,
>,
> {
App::new()
.service(web::scope("/api").guard(v1::ApiGuard).service(v1::hello))
.service(web::scope("/api").guard(v2::ApiGuard).service(v2::hello))
// using this form of API version selection means that we need to send a Vary header so that
// caches won't try to serve the wrong response
.wrap(DefaultHeaders::new().add(("Vary", "Accept-Version")))
}
#[actix_web::main]
async fn main() -> std::io::Result<()> {
HttpServer::new(create_app)
.bind(("127.0.0.1", 8080))?
.run()
.await
}