我已经用 actix-web 定义了一个端点,如下所示:
#[derive(Deserialize)]
struct RenderInfo {
filename: String,
}
fn render(info: actix_web::Path<RenderInfo>) -> Result<String> {
// ...
}
Run Code Online (Sandbox Code Playgroud)
App::new()
.middleware(middleware::Logger::Default())
.resource("/{filename}", |r| r.get().with(render))
Run Code Online (Sandbox Code Playgroud)
我遇到的问题是原始 HTML 显示在浏览器中而不是被呈现。我认为内容类型设置不正确。
我看到的大多数 actix-web 示例都用于impl Responder返回类型,但我无法弄清楚如何解决造成的类型推断问题。原因似乎与返回基于标准failure::Error类型的文件操作有关。看起来 actix_web 需要实现一个特殊的WebError来阻止错误的意外传播。对于这个特定的例子,我并不在乎,因为它更像是一个内部工具。
我正在尝试使用actix_web来获取并显示网页的内容。HTTP 请求成功完成,我可以查看网页,但我想将正文读入String打印。
我尝试过let my_ip: String = response.body().into();,但收到一条错误消息
error[E0277]: the trait bound `std::string::String: std::convert::From<actix_web::httpmessage::MessageBody<actix_web::client::response::ClientResponse>>` is not satisfied
--> src/main.rs:16:53
|
16 | let my_ip: String = response.body().into();
| ^^^^ the trait `std::convert::From<actix_web::httpmessage::MessageBody<actix_web::client::response::ClientResponse>>` is not implemented for `std::string::String`
|
= help: the following implementations were found:
<std::string::String as std::convert::From<&'a str>>
<std::string::String as std::convert::From<std::borrow::Cow<'a, str>>>
<std::string::String as std::convert::From<std::boxed::Box<str>>>
<std::string::String as std::convert::From<trust_dns_proto::error::ProtoError>>
= note: required because of the requirements on the impl of `std::convert::Into<std::string::String>` for `actix_web::httpmessage::MessageBody<actix_web::client::response::ClientResponse>`
Run Code Online (Sandbox Code Playgroud)
这是我到目前为止所拥有的:
use …Run Code Online (Sandbox Code Playgroud) 我的应用程序基于使用 actix 和 actix-web 的库 (Library-A)。我正在添加第二个库(Library-B),它运行一个 http 服务器,也使用 actix-web。actix::system我为此使用了一个单独的线程。收到 SIGINT 后,仅 Library-B actix 系统关闭,而 Library-A 继续运行。后续 SIGINT 不会关闭正在运行的 actix 系统。
正常关闭两个正在运行的 actix 系统的正确方法是什么?
Library-B 的代码,用于启动新的 actix 系统并运行 http 服务器:
thread::spawn(move || {
let sys = actix::System::new("monitor");
server::new(|| App::new()
.route("/metrics", http::Method::GET, endpoint))
.bind(format!("0.0.0.0:{}", port))
.unwrap()
.start();
sys.run();
println!("Closing monitor actix system");
// --- SIGINT gets me here... how do I shut down gracefully?
});
Run Code Online (Sandbox Code Playgroud)
我为独立图书馆启动一个新系统是否正确?如何优雅地关闭?
这是我的代码。我正在尝试从 Rust subreddit 获取帖子。我将使用 Actix 的内置客户端,但它不适用于 Windows,因此使用reqwest:
use actix_web::{self, middleware, web, App, HttpRequest, HttpServer};
use futures::future::Future;
use reqwest::{
self,
r#async::{Client},
};
fn get_rust_posts(
_req: HttpRequest,
client: web::Data<Client>,
) -> impl Future<Item = String, Error = reqwest::Error> {
client
.get("http://www.reddit.com/r/rust.json")
.send()
.and_then(|mut resp| resp.text())
.map_err(|err| {
println!("Error in get rust posts: {}", err);
err
})
}
fn main() {
let mut server = HttpServer::new(|| {
App::new()
.data(Client::new())
.wrap(middleware::Logger::default())
.service(web::resource("/get/rust/posts").route(web::get().to_async(get_rust_posts)))
});
server.bind(("0.0.0.0", 8000)).unwrap().run().unwrap();
}
Run Code Online (Sandbox Code Playgroud)
[dependencies]
actix-web = "1.0.8"
futures = …Run Code Online (Sandbox Code Playgroud) 在Actix Web Framework 中,如何使用路由属性宏 ( #[http_method("route")]) 将多个 http 方法绑定到一个函数?
例如,我有这个微不足道的端点:
/// Returns a UUID4.
#[get("/uuid")]
async fn uuid_v4() -> impl Responder {
HttpResponse::Ok().json(Uuid {
uuid: uuid::Uuid::new_v4(),
})
}
Run Code Online (Sandbox Code Playgroud)
我想让相同的端点处理HEAD请求,我该怎么做?
我最初的方法是堆叠宏:
/// Returns a UUID4.
#[get("/uuid")]
#[head("/uuid")]
async fn uuid_v4() -> impl Responder {
HttpResponse::Ok().json(Uuid {
uuid: uuid::Uuid::new_v4(),
})
}
Run Code Online (Sandbox Code Playgroud)
但我确实收到了编译错误:
|
249 | async fn uuid_v4() -> impl Responder {
| ^^^^^^^ the trait `actix_web::handler::Factory<_, _, _>` is not implemented for `<uuid_v4 as actix_web::service::HttpServiceFactory>::register::uuid_v4` …Run Code Online (Sandbox Code Playgroud) 我正在使用 Rust 和 actix_web 构建 Web API 服务。
我想测试一条路线并检查收到的响应正文是否符合我的预期。但是我正在努力将接收到的正文ResponseBody<Body>转换为 JSON 或 BSON。被调用的路由实际上返回application/json.
let mut app = test::init_service(App::new()
.data(AppState { database: db.clone() })
.route("/recipes/{id}", web::post().to(add_one_recipe))
).await;
let payload = create_one_recipe().as_document().unwrap().clone();
let req = test::TestRequest::post()
.set_json(&payload).uri("/recipes/new").to_request();
let mut resp = test::call_service(&mut app, req).await;
let body: ResponseBody<Body> = resp.take_body(); // Here I want the body as Binary, String, JSON, or BSON. The response is actually application/json.
Run Code Online (Sandbox Code Playgroud) 我正在尝试为我的 rust 程序制作一个 docker 容器,让我们看看
文件
FROM debian
RUN apt-get update && \
apt-get -y upgrade && \
apt-get -y install git curl g++ build-essential
RUN curl https://sh.rustup.rs -sSf | bash -s -- -y
WORKDIR /usr/src/app
RUN git clone https://github.com/unegare/rust-actix-rest.git
RUN ["/bin/bash", "-c", "source $HOME/.cargo/env; cd ./rust-actix-rest/; cargo build --release; mkdir uploaded"]
EXPOSE 8080
ENTRYPOINT ["/bin/bash", "-c", "echo 'Hello there!'; source $HOME/.cargo/env; cd ./rust-actix-rest/; cargo run --release"]
Run Code Online (Sandbox Code Playgroud)
cmd运行: docker run -it -p 8080:8080 rust_rest_api/dev
但从外部卷曲curl -i -X POST -F …
我正在尝试运行两个应用程序(一个在端口 3006 上进行管理,另一个在端口 8080 上提供数据)。
他们共享数据库池、缓存...
对于actix 1.0,我有这个工作(我不知道这是否是最好的方法):
let server = Server::build()
// FIRST APP
.bind("", "0.0.0.0:3006", move || {
HttpService::build().finish({
App::new()
.wrap(actix_Logger::new(
"WMTS %a %r %s %b %{Referer}i %{User-Agent}i %T",
))
.data(pool.clone())
.data(cache.clone())
.service(
web::scope("/utils")
.route(
"one",
web::get().to(api::one),
)
.route("two", web::get().to(api::two))
)
.service(
web::scope("/data")
.route("get_data", web::get().to(api::get_data)),
)
})
})
.unwrap()
// SECOND APP
.bind("", "0.0.0.0:8080", move || {
HttpService::build().finish(
App::new()
.wrap(actix_Logger::new(
"API %a %r %s %b %{Referer}i %{User-Agent}i %T",
))
.data(pool.clone())
.data(cache.clone())
.service(web::resource("/graphql").route(web::post().to(api::graphql)))
.service(web::resource("/health").route(web::get().to(api::health)))
.service(web::resource("/metrics").route(web::get().to(api::metrics))),
)
})
.unwrap();
server.run()?; …Run Code Online (Sandbox Code Playgroud) 我正在尝试使用actix-web 1.0编写HTTP端点。我已经简化了该函数,以便仅返回传递给该函数的用户,但编译器仍会给出错误。
extern crate actix_web;
extern crate chrono;
extern crate futures;
extern crate listenfd;
#[macro_use]
extern crate serde_derive;
extern crate dotenv;
use actix_web::{error, web, App, Error, HttpResponse, HttpServer};
use futures::future::Future;
#[derive(Debug, Deserialize, Serialize)]
pub struct LoginUser {
pub username: String,
pub password: String,
}
pub fn login(
login_user: web::Json<LoginUser>,
) -> impl Future<Item = HttpResponse, Error = error::BlockingError<Error>> {
web::block(move || {
let login_user = login_user.into_inner();
let user = LoginUser {
username: login_user.username,
password: login_user.password,
};
Ok(HttpResponse::Ok().json(user))
})
}
pub …Run Code Online (Sandbox Code Playgroud) 我试图通过运行以下函数来有意耗尽 API 限制(900 次调用):
#[get("/exhaust")]
pub async fn exhaust(_pool: web::Data<PgPool>, config: web::Data<Arc<Settings>>) -> impl Responder {
let mut handles = vec![];
for i in 1..900 {
let inner_config = config.clone();
let handle = thread::spawn(move || async move {
println!("running thread {}", i);
get_single_tweet(inner_config.as_ref().deref(), "1401287393228038149")
.await
.unwrap();
});
handles.push(handle);
}
for h in handles {
h.join().unwrap().await;
}
HttpResponse::Ok()
Run Code Online (Sandbox Code Playgroud)
我的机器有 16 个内核,所以我希望上面的运行速度比单线程函数快 16 倍,但事实并非如此。事实上,它的运行速度与单线程版本一样慢。
这是为什么?我错过了什么?
注意:这move || async move部分对我来说看起来有点奇怪,但我是按照编译器的建议到达那里的。由于async closures being unstable. 这可能是问题吗?