1 个不稳定版本
0.1.0 | 2022年5月31日 |
---|
#84 in #state-machine
155KB
3.5K SLoC
ux-webmachine
Rust 中的异步 Web 机器
https://github.com/uglyog/webmachine-rust.git 的分支
Webmachine-Ruby (https://github.com/webmachine/webmachine-ruby) 的 Rust 版本。
ux-webmachine 是 webmachine 的 Ruby 版本的移植。它实现了一个有限状态机,用于处理 HTTP 协议,提供语义 HTTP 处理(基于 webmachine 项目的 图表)。它基本上是一个 HTTP 工具包,用于使用 Hyper Rust 包构建对 HTTP 友好的应用程序。
Webmachine-rust 与 Hyper 一起工作,位于 Hyper 处理程序和您的应用程序代码之间。它提供一个资源结构体,带有回调,以处理状态机在针对请求执行时所需的决策。以下是这个序列。
请求 -> Hyper 处理程序 -> Webmachine 分发器 -> Webmachine 资源 -> 您的应用程序代码 -> Webmachine 响应 -> Hyper -> 响应
特性
- 为您处理内容协商、条件请求和响应代码的困难部分。
- 提供一个资源结构体,具有扩展点,让您描述有关您特定资源的相关信息。
未实现的功能
目前,以下来自 webmachine-ruby 的功能尚未实现:
- 可视化调试器
- 流式响应体
实现缺陷
此实现有以下缺陷:
- 自动解码请求体和编码响应体。
- 没有简单的机制来生成具有不同内容类型(例如 JSON 与 XML)的体。
- 没有简单的机制来处理资源中的子路径。
- 动态确定资源上允许的方法。
开始使用 Hyper
遵循 Hyper 包的入门文档来为您的服务器设置 Hyper 服务。您需要定义一个 Webmachine 分发器,该分发器将资源路径映射到您的 webmachine 资源(WebmachineResource)。每个 WebmachineResource 定义了实现资源所需的回调(通过闭包)和值。Webmachine 分发器实现了 Hyper Service 特性,因此您可以将它传递给 make_service_fn
。
注意:此示例使用 maplit 包提供 btreemap
宏和 log 包提供日志宏。
use hyper::server::Server;
use webmachine_rust::*;
use webmachine_rust::context::*;
use webmachine_rust::headers::*;
use serde_json::{Value, json};
use std::io::Read;
use std::net::SocketAddr;
use hyper::service::make_service_fn;
use std::convert::Infallible;
// setup the dispatcher, which maps paths to resources. The requirement of make_service_fn is
// that it has a static lifetime
fn dispatcher() -> WebmachineDispatcher<'static> {
WebmachineDispatcher {
routes: btreemap!{
"/myresource" => WebmachineResource {
// Methods allowed on this resource
allowed_methods: vec!["OPTIONS", "GET", "HEAD", "POST"],
// if the resource exists callback
resource_exists: callback(&|_, _| true),
// callback to render the response for the resource
render_response: callback(&|_, _| {
let json_response = json!({
"data": [1, 2, 3, 4]
});
Some(json_response.to_string())
}),
// callback to process the post for the resource
process_post: callback(&|_, _| /* Handle the post here */ Ok(true) ),
// default everything else
.. WebmachineResource::default()
}
}
}
}
async fn start_server() -> Result<(), String> {
// Create a Hyper server that delegates to the dispatcher
let addr = "0.0.0.0:8080".parse().unwrap();
let make_svc = make_service_fn(|_| async { Ok::<_, Infallible>(dispatcher()) });
match Server::try_bind(&addr) {
Ok(server) => {
// start the actual server
server.serve(make_svc).await;
Ok(())
},
Err(err) => {
error!("could not start server: {}", err);
Err(format!("could not start server: {}", err))
}
}
}
示例实现
以下是一个使用此crate的项目示例:请查看Pact参考实现中的Pact Mock Server。
依赖项
约13–24MB
约366K SLoC