I have an HTTP endpoint in rust using poem::openapi. I would like a single handler for a variable segment path.
#[OpenApi]
impl NvApi {
#[oai(path = "/:namespace/:id", method = "get")]
async fn get(
&self,
nv: Data<&SharedHandle>,
namespace: Path<String>,
id: Path<String>,
) -> Result<GetResponse, poem::Error> {
log::debug!("get {}/{}", namespace.as_str(), id.as_str());
...
...
...
}
I would like the code above to handle paths like /mynamespace/mydomain/myid
as well as /mynamespace/myid
- an arbitrary number of segments loaded into the namespace variable but always loading the trailing segment into the 'id' variable.
I've seen references to "*path" in the poem repo but can't find any docs or examples of wildcard. I'd like to use the pattern above as my SharedHandle impl is needed.
This is not directly possible.
The path parser in poem
breaks after encountering a wildcard token which means it cannot be used to match in the middle of a path.
The best workaround would be to use a regex that matches all path segments except the final segment. In code, that would hypothetically appear as:
#[oai(path = "/:namespace<.+(?=/)>/:id", method = "get")]
async fn get(&self, ...) ...
but poem
uses the regex
crate which does not support lookaheads (needed to ignore the last slash).
Instead, you will have to use a regex with no lookaheads and manually remove the trailing slash:
#[OpenApi]
impl Api {
#[oai(path = "/:namespace<.+/>:id", method = "get")]
async fn get(
&self,
...
namespace: Path<String>,
id: Path<String>,
) -> ... {
// GET /a/b/c
println!("{}", namespace.to_string()); // a/b/
println!("{}", id.to_string()); // c
...
}
}