29 个版本

0.4.0 2023年1月1日
0.3.6 2022年11月25日
0.3.5 2022年10月10日
0.3.2 2022年8月10日
0.1.13 2022年1月26日

#405 in WebAssembly

Download history 5/week @ 2024-03-28 2/week @ 2024-04-04

84 个月下载量

MIT/Apache

13KB
199 代码行

retrofit

一个用于为函数生成 REST API 的库。

目前支持生成 getpost API。

当使用 #[get_api]#[post_api] 宏时,如果是在 wasm 上,则使用 reqwasm 生成请求函数,否则使用 reqwest,并添加一个 rocket 路由。

使用方法

// Initial function
#[post_api]
fn plus(num1: i32, num2: i32) -> i32 {
    num1 + num2
}

// Normal usage
let result = plus(9, 10);

// Calling the function from client side
let result = plus_request(9, 10).await;

// Mounting the route on the server
#[launch]
fn rocket() -> _ {
    rocket::build().mount("/", routes![plus_route])
}

// The same works with GET APIs, but usually POST is recommended because it is more robust and can handle Vecs
#[get_api]
fn minus(num1: i32, num2: i32) -> i32 {
    num1 - num2
}

// State can also be used!
#[post_api(ConnectionPool)]
pub fn get_all_customers(pool: &ConnectionPool) -> Result<Vec<Customer>, Error> {
    Ok(customers::table.limit(i64::MAX)
        .load::<Customer>(&mut pool.get().unwrap())?)
}
// In this example, ConnectionPool is mounted on the rocket server, and does not need to be passed in to the request function

上面的示例在后台生成了大量代码。为了更好地了解 Retrofit 是如何工作的,让我们看看 GET 请求中除去函数后生成的代码。

生成的代码

// From above
#[get_api]
fn minus(num1: i32, num2: i32) -> i32 {
    num1 - num2
}

// Everything below this point is generated.

// Route generated
#[get("/minus/<num1>/<num2>")]
fn minus_route(num1: String, num2: String) -> String {
    serde_json::to_string(
        &minus(
            serde_json::from_str(&num1).unwrap(),
            serde_json::from_str(&num2).unwrap()
        )
    ).unwrap()
}

// Request function generated
async fn minus_request(num1: i32, num2: i32) -> i32 {
    serde_json::from_str(
        &reqwest::get(
            &format!("https://127.0.0.1:8000/{}/{}", 
                "minus", 
                serde_json::to_string(&num1).unwrap(), 
                serde_json::to_string(&num2).unwrap()
            )
        ).await.unwrap()
        .text().await.unwrap()
    ).unwrap()
}

功能标志

server - 包含生成的 Rocket 路由

client - 包含生成的请求函数

这些功能提供了一种在服务器和客户端使用相同代码的方式。默认情况下它们都被启用,但如果你在自己的包中有具有生成 API 的函数,并且使用了客户端/服务器功能标志,你可以在后端和前端导入相同的包,而后端代码将不会与前端代码打包在一起。这对于在前端针对 WASM 并且使用像 Diesel(WASM 上不支持)这样的数据库系统来说很有用。

待办事项

  • 基本的 get_api
  • 添加 serverclient 功能支持(允许排除路由/请求函数)
  • 支持异步函数
  • 添加 post_api
  • 支持引用
  • 支持泛型
  • 支持其他 HTTP 客户端库(surf 等)
  • 支持其他 HTTP 服务器库(warp、actix 等)
  • 支持 Rocket States
  • 为 Rocket States 提供更好的易用性(不需要传递属性,状态不需要是最后一个参数)

依赖

~1.5–2MB
~49K SLoC