You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
I want to officially announce that Routerify is no longer being actively maintained (if it is not already obvious). The project has been inactive for three years, signaling it's time for a change. I recommend Axum as an alternative. Axum offers a similar API to Routerify, is actively developed, and has a broader community support.
Why Choose Axum?
Active Development: Axum has strong community support and ongoing development, unlike Routerify's current state.
Similar API: Transitioning to Axum is smooth due to the similar design and functionality.
Robust Ecosystem: Axum integrates well with the Tower and Hyper ecosystem, providing access to a wide range of middleware and utilities.
Transition Example
To help illustrate the transition, I've created a simple TODO app example in both Routerify and Axum. This comparison highlights the similarities and demonstrates Axum's ergonomic design.
Axum Example:
use axum::{Router,
http::{HeaderName,Method,StatusCode},
extract::{FromRef,Path,Query,State},
handler::{get, post, delete},
response::{IntoResponse,Response},
body::BodyJson,};use tower_http::{
cors::{Any,CorsLayer},
trace::TraceLayer,};use std::sync::Arc;use tokio::sync::Mutex;use serde::{Deserialize,Serialize};fnok(message:implToString) -> Response<Body>{Response::builder().status(StatusCode::OK).body(Body::from(message.to_string())).unwrap()}#[derive(Clone)]structAppState{todos:Arc<Mutex<Vec<Todo>>>,}#[derive(Serialize,Deserialize,Clone)]structTodo{id:u32,title:String,completed:bool,}asyncfnget_todos(State(state):State<AppState>) -> implIntoResponse{let todos = state.todos.lock().await;ok(serde_json::to_string(&todos))}asyncfnadd_todo(State(state):State<AppState>,Json(todo):Json<Todo>) -> implIntoResponse{letmut todos = state.todos.lock().await;
todos.push(todo);()}asyncfndelete_todo(State(state):State<AppState>,Path(id):Path<u32>,) -> implIntoResponse{letmut todos = state.todos.lock().await;
todos.retain(|todo| todo.id != id);()}fnrouter() -> Router{let state = AppState{todos:Arc::new(Mutex::new(Vec::new())),};let router = Router::new().route("/",get(get_todos)).route("/"post(add_todo)).route("/:id"delete(delete_todo)).layer(TraceLayer::new_for_http()).layer(CorsLayer::new().allow_origin(Any).allow_methods(vec![Method::GET, Method::POST, Method::PUT, Method::DELETE, Method::OPTIONS,
])).with_state(state);let service = router.into_make_service();let addr = format!("{}:{}", address, port);let listener = tokio::net::TcpListener::bind(addr.as_str()).await.unwrap();ifletErr(e) = axum::serve(listener, service).await{error!(%e);}}
Routerify Example:
#[derive(Clone)]structAppState{todos:Arc<Mutex<Vec<Todo>>>,}#[derive(Serialize,Deserialize,Clone)]structTodo{id:u32,title:String,completed:bool,}asyncfnget_todos(req:Request<Body>) -> Result<Response<Body>,Infallible>{let state = req.data::<AppState>().unwrap();let todos = state.todos.lock().await;let todos_json = serde_json::to_string(&*todos).unwrap();Ok(Response::new(Body::from(todos_json)))}asyncfnadd_todo(mutreq:Request<Body>) -> Result<Response<Body>,Infallible>{let state = req.data::<AppState>().unwrap();let todo:Todo = serde_json::from_slice(&hyper::body::to_bytes(req.body_mut()).await.unwrap()).unwrap();letmut todos = state.todos.lock().await;
todos.push(todo);Ok(Response::new(Body::from("Todo added")))}asyncfndelete_todo(req:Request<Body>) -> Result<Response<Body>,Infallible>{let state = req.data::<AppState>().unwrap();let id:u32 = req.param("id").unwrap().parse().unwrap();letmut todos = state.todos.lock().await;
todos.retain(|todo| todo.id != id);Ok(Response::new(Body::from("Todo deleted")))}fnrouter() -> Router<Body,Infallible>{let state = AppState{todos:Arc::new(Mutex::new(Vec::new())),};Router::builder().data(state).get("/todos", get_todos).post("/todos", add_todo).delete("/todos/:id", delete_todo).middleware(routerify_cors::enable_cors_all()).middleware(routerify_query::query_parser()).build().unwrap()}#[tokio::main]asyncfnmain(){let router = router();let service = RouterService::new(router).unwrap();let addr = SocketAddr::from(([127,0,0,1],3000));let server = Server::bind(&addr).serve(service);println!("App is running on: {}", addr);ifletErr(err) = server.await{eprintln!("Server error: {}", err);}}
Moving Forward
I encourage you to explore Axum and consider it for your future projects. Its active development and community support offer a robust foundation for building web applications in Rust.
Thank you to everyone who has supported Routerify. I look forward to seeing how you all will leverage Axum to continue building amazing Rust applications. ❤️
reacted with thumbs up emoji reacted with thumbs down emoji reacted with laugh emoji reacted with hooray emoji reacted with confused emoji reacted with heart emoji reacted with rocket emoji reacted with eyes emoji
-
Hello Routerify Users,
I want to officially announce that Routerify is no longer being actively maintained (if it is not already obvious). The project has been inactive for three years, signaling it's time for a change. I recommend Axum as an alternative. Axum offers a similar API to Routerify, is actively developed, and has a broader community support.
Why Choose Axum?
Transition Example
To help illustrate the transition, I've created a simple TODO app example in both Routerify and Axum. This comparison highlights the similarities and demonstrates Axum's ergonomic design.
Axum Example:
Routerify Example:
Moving Forward
I encourage you to explore Axum and consider it for your future projects. Its active development and community support offer a robust foundation for building web applications in Rust.
Thank you to everyone who has supported Routerify. I look forward to seeing how you all will leverage Axum to continue building amazing Rust applications. ❤️
Best,
Sean
Beta Was this translation helpful? Give feedback.
All reactions