我正在尝试构建一个具有多个端点的 REST API。某些端点之间的相关性可能比其他端点更多,因此我想在多个文件中实现它们。我有点爱上了poem,因为它的简单性,但如果有人可以展示一个框架,以更简单的方式解决我的问题(并且性能不是这个应用程序的优先事项),我愿意放弃它.
我的希望是我可以多个实现
Endpoint
结构体中的方法。在我所做的尝试中,我要么收到错误conflicting implementations of trait
,要么收到错误cannot find attribute
。有关错误的更多详细信息,请参阅 some_endpoints.rs
的实现。这是一个可能产生我看到的错误的最小示例:
// main.rs
use poem::{listener::TcpListener, Route};
use poem_openapi::{OpenApi, OpenApiService};
pub struct Endpoints;
#[OpenApi]
impl Endpoints {}
mod some_endpoints;
mod more_endpoints;
#[tokio::main]
async fn main() -> Result<(), std::io::Error> {
let api = OpenApiService::new(Endpoints, "My app", "1.0");
let docs = api.swagger_ui();
let app = Route::new()
.nest("/api", api)
.nest("/", docs);
poem::Server::new(TcpListener::bind("127.0.0.1:3000"))
.run(app)
.await
}
// some_endpoints.rs
use super::Endpoints;
use poem_openapi::OpenApi;
use poem_openapi::payload::PlainText;
// If `#[OpenApi]` here, I get the following errors:
// error[E0119]: conflicting implementations of trait `OpenApi` for type `Endpoints`
// conflicting implementation for `Endpoints`
#[OpenApi]
impl Endpoints {
/// Some dummy endpoints
///
// If `#[OpenApi]` is commented out above, I get the following errors:
// error: cannot find attribute `oai` in this scope
#[oai(path = "/dummy", method = "get")]
async fn dummy(&self) -> PlainText<&'static str> {
PlainText("Hello, world!")
}
}
// more_endpoints.rs
// This is basically a copy of `some_endpoints.rs`, and can be left out of
// this example if `Endpoint` can be first defined in `main.rs`.
# Cargo.toml
# ...
[dependencies]
poem = "1.3.55"
poem-openapi = { version = "2.0.26", features = ["swagger-ui"] }
tokio = { version = "1", features = ["full"] }
我找到了答案 - 隐藏在文档中显而易见的地方。
这个示例展示了如何组合多个结构。
在我发布的原始问题中,它看起来像:
// main.rs
use poem::{listener::TcpListener, Route};
use poem_openapi::OpenApiService;
mod more_endpoints;
mod some_endpoints;
#[tokio::main]
async fn main() -> Result<(), std::io::Error> {
let all_endpoints = (some_endpoints::Endpoints, more_endpoints::Endpoints);
let api = OpenApiService::new(all_endpoints, "My app", "1.0");
let docs = api.swagger_ui();
let app = Route::new().nest("/api", api).nest("/", docs);
poem::Server::new(TcpListener::bind("127.0.0.1:3000"))
.run(app)
.await
}
// some_endpoints.rs
use poem_openapi::OpenApi;
use poem_openapi::payload::PlainText;
pub struct Endpoints;
#[OpenApi]
impl Endpoints {
/// Some dummy endpoints
///
#[oai(path = "/dummy", method = "get")]
async fn dummy(&self) -> PlainText<&'static str> {
PlainText("Hello, world!")
}
}