1
0
mirror of https://github.com/actix/examples synced 2025-01-22 14:05:55 +01:00
examples/guards/src/main.rs
2022-03-06 00:15:19 +00:00

94 lines
2.4 KiB
Rust

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
}
#[cfg(test)]
mod tests {
use actix_web::test::{self, TestRequest};
use super::*;
#[actix_web::test]
async fn api_versioning() {
let app = test::init_service(create_app()).await;
let req = TestRequest::with_uri("/api/hello").insert_header(("Accept-Version", "1"));
let res = test::call_and_read_body(&app, req.to_request()).await;
assert_eq!(res, "Hello World from v1 API!");
let req = TestRequest::with_uri("/api/hello").insert_header(("Accept-Version", "2"));
let res = test::call_and_read_body(&app, req.to_request()).await;
assert_eq!(res, "Hello World from the awesome new v2 API!");
}
}