rust web(api)/job/rpc application
current axum >= 0.7.4+
if you are using axum below version 0.7 please use rs-api v1 branch code
- axum: https://crates.io/crates/axum https://github.com/tokio-rs/axum
- tokio: https://crates.io/crates/tokio https://github.com/tokio-rs/tokio
- serde: https://crates.io/crates/serde https://github.com/serde-rs/serde
- redis: https://crates.io/crates/redis https://github.com/redis-rs/redis-rs
- rs-infras: https://github.com/rs-god/rs-infras
- rust cron job: https://github.com/rs-god/rcron
- rust grpc project: https://github.com/daheige/rs-rpc
.
├── config Configuration file reading and initialization
├── handlers Function handler for complex routing rules
│ └── mod.rs
├── main.rs
├── middleware The main middleware is rpc/api middleware
│ └── mod.rs
├── routes Routing rule
│ └── mod.rs
└── services Business logic layer
└── mod.rs
cargo run --bin rs-api
Visit home page: http://localhost:1338/
Hello, World!
POST http://localhost:1338/form
curl --location --request POST 'http://localhost:1338/form' \
--header 'Content-Type: application/x-www-form-urlencoded' \
--data-urlencode 'name=daheige' \
--data-urlencode 'age=30'
response
{
"code": 0,
"message": "ok",
"data": {
"name": "daheige",
"email": "",
"age": 30
}
}
POST http://localhost:1338/users
curl --location --request POST 'http://localhost:1338/users' \
--header 'Content-Type: application/json' \
--data-raw '{"username":"daheige"}'
response
{
"code": 0,
"message": "success",
"data": {
"id": 1337,
"username": "daheige"
}
}
GET http://localhost:1338/empty-array
curl --location --request GET 'localhost:1338/empty-array'
response
{
"code": 0,
"message": "ok",
"data": []
}
GET http://localhost:1338/empty-object
curl --location --request GET 'localhost:1338/empty-object'
response
{
"code": 0,
"message": "ok",
"data": {}
}
GET http://localhost:1338/html
curl --location --request GET 'localhost:1338/html'
response
<h1>hello,rs-api</h1>
from axum::http::HeaderMap
let ua = headers
.get(header::USER_AGENT)
.and_then(|v| v.to_str().ok())
.map(|v| v.to_string())
.unwrap();
println!("user-agent:{}", ua);
// eg: this code
// Content-Type: application/x-www-form-urlencoded
// pub async fn accept_form(Form(input): Form<user::UserForm>) -> impl IntoResponse {
pub async fn accept_form(
headers: HeaderMap,
Form(input): Form<user::UserForm>,
) -> impl IntoResponse {
println!("headers: {:?}", headers);
let ua = headers
.get(header::USER_AGENT)
.and_then(|v| v.to_str().ok())
.map(|v| v.to_string())
.unwrap();
println!("user-agent:{}", ua);
println!("current input:{:?}", input);
(
StatusCode::OK,
Json(super::Reply {
code: 0,
message: "ok".to_string(),
data: Some(input),
}),
)
}
handlers/validate_form.rs
curl --location --request GET 'http://localhost:1338/validate?name='
response:
{
"code": 1001,
"message": "input validation error: [name: can not be empty]",
"data": {}
}
invalid param
curl --location --request GET 'http://localhost:1338/validate'
response:
{
"code": 500,
"message": "param error:Failed to deserialize form",
"data": {}
}
valid param
curl --location --request GET 'http://localhost:1338/validate?name=daheige'
response:
{
"code": 0,
"message": "ok",
"data": "hello,daheige!"
}
handlers/json_or_form.rs
json request:
curl --location --request POST 'http://localhost:1338/json_or_form' \
--header 'Content-Type: application/json' \
--data-raw '{
"foo":"abc"
}'
response:
{
"code": 0,
"message": "ok",
"data": "hello,abc!"
}
form request:
curl --location --request POST 'http://localhost:1338/json_or_form' \
--header 'Content-Type: application/x-www-form-urlencoded' \
--data-urlencode 'foo=abc'
response:
{
"code": 0,
"message": "ok",
"data": "hello,abc!"
}
invalid request
curl --location --request POST 'http://localhost:1338/json_or_form' \
--header 'Content-Type: application/x-www-form-urlencoded' \
--data-urlencode 'foo='
response:
{
"code": 1001,
"message": "input validation error: [foo: can not be empty]",
"data": {}
}
please see handlers/index.rs
exec begin method:GET uri:/empty-object?id=1 path:/empty-object request body:Body(Empty) query:Some("id=1") ua:PostmanRuntime/7.26.8 request_id:f1d720c8-2eab-408a-bd0a-41c924512d7f
exec end,request_id:f1d720c8-2eab-408a-bd0a-41c924512d7f,exec_time:0ms
MIT