-
Notifications
You must be signed in to change notification settings - Fork 3
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: add swagger ui for both axum and actix (#3)
- Loading branch information
Showing
8 changed files
with
373 additions
and
4 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,6 +1,8 @@ | ||
mod web_development; | ||
mod web_development_actix; | ||
mod web_development_axum; | ||
|
||
pub fn run() { | ||
println!("Days 16-18: Web Development"); | ||
let _ = web_development::main(); | ||
// let _ = web_development_actix::main(); | ||
let _ = web_development_axum::main(); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,88 @@ | ||
use axum::{ | ||
routing::get, | ||
Router, Json, extract::{Query, Path}, | ||
}; | ||
use serde::{Deserialize, Serialize}; | ||
use std::net::SocketAddr; | ||
use tokio::net::TcpListener; | ||
|
||
/// Represents a user in the system | ||
#[derive(Serialize, Deserialize)] | ||
struct User { | ||
id: u32, | ||
name: String, | ||
} | ||
|
||
/// Represents query parameters for filtering users | ||
#[derive(Deserialize)] | ||
struct UserFilter { | ||
name: Option<String>, | ||
} | ||
|
||
/// Handles GET request to retrieve all users | ||
/// | ||
/// # Arguments | ||
/// | ||
/// * `query` - Query parameters for filtering users | ||
/// | ||
/// Returns a JSON array of filtered users in the system | ||
async fn get_users(Query(query): Query<UserFilter>) -> Json<Vec<User>> { | ||
let users = vec![ | ||
User { id: 1, name: "Alice".to_string() }, | ||
User { id: 2, name: "Bob".to_string() }, | ||
User { id: 3, name: "Charlie".to_string() }, | ||
User { id: 4, name: "Bobby Pickle".to_string() }, | ||
]; | ||
|
||
let filtered_users: Vec<User> = users.into_iter() | ||
.filter(|user| { | ||
query.name.as_ref().map_or(true, |name| user.name.to_lowercase().contains(&name.to_lowercase())) | ||
}) | ||
.collect(); | ||
|
||
Json(filtered_users) | ||
} | ||
|
||
/// Handles GET request to retrieve a specific user by ID | ||
/// | ||
/// # Arguments | ||
/// | ||
/// * `path` - A Path extractor containing the user ID | ||
/// | ||
/// Returns a JSON object of the requested user | ||
async fn get_user(Path(user_id): Path<u32>) -> Json<User> { | ||
// In a real application, we would fetch the user from a database | ||
let user = User { id: user_id, name: format!("User {}", user_id) }; | ||
Json(user) | ||
} | ||
|
||
/// Handles POST request to create a new user | ||
/// | ||
/// # Arguments | ||
/// | ||
/// * `user` - JSON payload representing the new user | ||
/// | ||
/// Returns the created user | ||
async fn create_user(Json(user): Json<User>) -> Json<User> { | ||
// In a real application, we would save the user to a database | ||
Json(user) | ||
} | ||
|
||
/// Starts the web server and configures the routes | ||
#[tokio::main] | ||
pub async fn main() { | ||
const HOST: &str = "127.0.0.1"; | ||
const PORT: u16 = 8080; | ||
// Run to get all users http://127.0.0.1:8080/api/v1/users | ||
// Run to get user with id 1 http://127.0.0.1:8080/api/v1/users/1 | ||
// Run to get filter user http://127.0.0.1:8080/api/v1/users?name=Alice | ||
println!("Starting web server at http://{}:{}", HOST, PORT); | ||
|
||
let app = Router::new() | ||
.route("/api/v1/users", get(get_users).post(create_user)) | ||
.route("/api/v1/users/:id", get(get_user)); | ||
|
||
let addr = SocketAddr::from(([127, 0, 0, 1], PORT)); | ||
let listener = TcpListener::bind(addr).await.unwrap(); | ||
axum::serve(listener, app).await.unwrap(); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,8 @@ | ||
mod web_development_actix_swaggerui; | ||
mod web_development_axum_swaggerui; | ||
|
||
pub fn run() { | ||
println!("Days 19-21: Web Development with Swagger UI"); | ||
// let _ = web_development_actix_swaggerui::main(); | ||
let _ = web_development_axum_swaggerui::main(); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,134 @@ | ||
// use actix_web::{web, App, HttpResponse, HttpServer, Responder}; | ||
// use serde::{Deserialize, Serialize}; | ||
// use utoipa::OpenApi; | ||
// use utoipa_swagger_ui::SwaggerUi; | ||
|
||
// /// Represents a user in the system | ||
// #[derive(Serialize, Deserialize, utoipa::ToSchema)] | ||
// struct User { | ||
// id: u32, | ||
// name: String, | ||
// } | ||
|
||
// /// Represents query parameters for filtering users | ||
// #[derive(Deserialize, utoipa::IntoParams, utoipa::ToSchema)] | ||
// struct UserFilter { | ||
// name: Option<String>, | ||
// } | ||
|
||
// /// Handles GET request to retrieve all users | ||
// /// | ||
// /// # Arguments | ||
// /// | ||
// /// * `query` - Query parameters for filtering users | ||
// /// | ||
// /// Returns a JSON array of filtered users in the system | ||
// #[utoipa::path( | ||
// get, | ||
// path = "/api/v1/users", | ||
// params(UserFilter), | ||
// responses( | ||
// (status = 200, description = "List of users", body = Vec<User>) | ||
// ) | ||
// )] | ||
// #[allow(dead_code)] | ||
// async fn get_users(query: web::Query<UserFilter>) -> impl Responder { | ||
// let users = vec![ | ||
// User { id: 1, name: "Alice".to_string() }, | ||
// User { id: 2, name: "Bob".to_string() }, | ||
// User { id: 3, name: "Charlie".to_string() }, | ||
// User { id: 4, name: "Bobby Pickle".to_string() }, | ||
// ]; | ||
|
||
// let filtered_users: Vec<User> = users.into_iter() | ||
// .filter(|user| { | ||
// query.name.as_ref().map_or(true, |name| user.name.to_lowercase().contains(&name.to_lowercase())) | ||
// }) | ||
// .collect(); | ||
|
||
// HttpResponse::Ok().json(filtered_users) | ||
// } | ||
|
||
// /// Handles GET request to retrieve a specific user by ID | ||
// /// | ||
// /// # Arguments | ||
// /// | ||
// /// * `path` - A Path extractor containing the user ID | ||
// /// | ||
// /// Returns a JSON object of the requested user or a 404 if not found | ||
// #[utoipa::path( | ||
// get, | ||
// path = "/api/v1/users/{id}", | ||
// params( | ||
// ("id" = u32, Path, description = "User ID") | ||
// ), | ||
// responses( | ||
// (status = 200, description = "User found", body = User), | ||
// (status = 404, description = "User not found") | ||
// ) | ||
// )] | ||
// #[allow(dead_code)] | ||
// async fn get_user(path: web::Path<u32>) -> impl Responder { | ||
// let user_id = path.into_inner(); | ||
// // In a real application, we would fetch the user from a database | ||
// let user = User { id: user_id, name: format!("User {}", user_id) }; | ||
// HttpResponse::Ok().json(user) | ||
// } | ||
|
||
// /// Handles POST request to create a new user | ||
// /// | ||
// /// # Arguments | ||
// /// | ||
// /// * `user` - JSON payload representing the new user | ||
// /// | ||
// /// Returns the created user with a 201 status code | ||
// #[utoipa::path( | ||
// post, | ||
// path = "/api/v1/users", | ||
// request_body = User, | ||
// responses( | ||
// (status = 201, description = "User created", body = User) | ||
// ) | ||
// )] | ||
// #[allow(dead_code)] | ||
// async fn create_user(user: web::Json<User>) -> impl Responder { | ||
// // In a real application, we would save the user to a database | ||
// HttpResponse::Created().json(user.into_inner()) | ||
// } | ||
|
||
// #[derive(OpenApi)] | ||
// #[openapi( | ||
// paths(get_users, get_user, create_user), | ||
// components(schemas(User, UserFilter)) | ||
// )] | ||
// struct ApiDoc; | ||
|
||
// /// Starts the web server and configures the routes | ||
// #[actix_web::main] | ||
// pub async fn main() -> std::io::Result<()> { | ||
// const HOST: &str = "127.0.0.1"; | ||
// const PORT: u16 = 8080; | ||
// // Run to get all users http://127.0.0.1:8080/api/v1/users | ||
// // Run to get user with id 1 http://127.0.0.1:8080/api/v1/users/1 | ||
// // Run to get filter user http://127.0.0.1:8080/api/v1/users | ||
// // Access Swagger UI at http://127.0.0.1:8080/swagger-ui/ | ||
// println!("Starting web server at http://{}:{}", HOST, PORT); | ||
// println!("Access Swagger UI at http://{}:{}/swagger-ui/", HOST, PORT); | ||
|
||
// HttpServer::new(|| { | ||
// App::new() | ||
// .service( | ||
// web::scope("/api/v1") | ||
// .route("/users", web::get().to(get_users)) | ||
// .route("/users/{id}", web::get().to(get_user)) | ||
// .route("/users", web::post().to(create_user)) | ||
// ) | ||
// .service( | ||
// SwaggerUi::new("/swagger-ui/{_:.*}") | ||
// .url("/api-docs/openapi.json", ApiDoc::openapi()) | ||
// ) | ||
// }) | ||
// .bind((HOST, PORT))? | ||
// .run() | ||
// .await | ||
// } |
Oops, something went wrong.