1
0
mirror of https://github.com/actix/examples synced 2024-11-23 14:31:07 +01: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
No known key found for this signature in database
GPG Key ID: 97C636207D3EF933
6 changed files with 123 additions and 1 deletions

7
Cargo.lock generated
View File

@ -2318,6 +2318,13 @@ dependencies = [
"thiserror",
]
[[package]]
name = "guards"
version = "1.0.0"
dependencies = [
"actix-web",
]
[[package]]
name = "h2"
version = "0.2.7"

View File

@ -25,6 +25,7 @@ members = [
"graphql/async-graphql",
"graphql/juniper-advanced",
"graphql/juniper",
"guards",
"http-proxy",
"https-tls/awc-https",
"https-tls/openssl-auto-le",

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
}

View File

@ -12,7 +12,7 @@ Demonstrates how to shutdown the web server in a couple of ways:
### Running The Server
```sh
cd basics/shutdown-server
cd shutdown-server
cargo run --bin shutdown-server
# Starting 8 workers