Связь адреса и ответа в Rust
Обработчик это асинхронная функция, которая готовит ответ для одного запроса. Ее результат может быть статической строкой, динамическим текстом или другим типом, который библиотека умеет превратить в ответ по сети.
Создайте проект Cargo и из корня выполните команды добавления зависимостей:
cargo add axum
cargo add tokio --features macros,rt-multi-thread,time
Первый крейт дает таблицу маршрутов и прием запросов, второй включает атрибут главной функции и сеть для асинхронного цикла. Версии подберет сама команда.
Свяжем корневой адрес с функцией, которая возвращает короткий текст, и запустим прием на локальном порту:
use axum::{Router, routing::get};
#[tokio::main]
async fn main() {
let app = Router::new().route("/", get(root));
let listener = match tokio::net::TcpListener::bind("127.0.0.1:3000").await {
Ok(l) => l,
Err(e) => {
eprintln!("{}", e);
return;
}
};
match axum::serve(listener, app).await {
Ok(()) => {}
Err(e) => eprintln!("{}", e),
}
}
async fn root() -> &'static str {
"ok"
}
После запуска откройте в браузере адрес
http://127.0.0.1:3000/ и увидите
текст ok. Сбой привязки порта
попадает в ветку ошибки сопоставления.
Второй адрес можно добавить в ту же таблицу другой функцией ответа:
use axum::{Router, routing::get};
#[tokio::main]
async fn main() {
let app = Router::new()
.route("/", get(root))
.route("/ping", get(ping));
let listener = match tokio::net::TcpListener::bind("127.0.0.1:3000").await {
Ok(l) => l,
Err(e) => {
eprintln!("{}", e);
return;
}
};
match axum::serve(listener, app).await {
Ok(()) => {}
Err(e) => eprintln!("{}", e),
}
}
async fn root() -> &'static str {
"ok"
}
async fn ping() -> &'static str {
"pong"
}
Дан путь:
/health
Добавьте его в таблицу и верните текст
up из отдельной асинхронной
функции.
Скажите, что произойдет при запросе к адресу, которого нет в таблице.
Дан путь:
/
Измените текст ответа на ready
и опишите, как разобрать сбой цикла
приема через исход.