Search code examples
rustopenapirust-tokiorust-poem

How to access request component using Poem


I'm trying to access the headers, url path, query parameters and other http information associated with a request received by my poem server. The server uses poem-openapi and tokio to receive and process requests. Here's the driving code from main.rs:

// Create the routes and run the server.
let addr = format!("{}{}", "0.0.0.0:", RUNTIME_CTX.parms.config.http_port);
let ui = api_service.swagger_ui();
let app = Route::new()
    .nest("/v1", api_service)
    .nest("/", ui)
    .at("/spec", spec)
    .at("/spec_yaml", spec_yaml);

// ------------------ Main Loop -------------------
// We expect the certificate and key to be in the external data directory.
let key = RUNTIME_CTX.tms_dirs.certs_dir.clone() + TMSS_KEY_FILE;
let cert = RUNTIME_CTX.tms_dirs.certs_dir.clone() + TMSS_CERT_FILE;
poem::Server::new(
    TcpListener::bind(addr).rustls(
        RustlsConfig::new().fallback(
            RustlsCertificate::new()
                .key(std::fs::read(key)?)
                .cert(std::fs::read(cert)?),
        ),
    ),
)
.name(SERVER_NAME)
.run(app)
.await

Multiple endpoints work just fine, but I'm having a hard time accessing detailed request information in my asynchronous endpoint code that looks something like this:

impl MyApi {
    #[oai(path = "/myapp/endpoint", method = "post")]
    async fn get_new_ssh_keys(&self, req: Json<MyReq>) -> Json<MyResp> {
        let resp = match MyResp::process(&req) { ... } }

I tried using poem::web::FromRequest, poem_openapi::param::Header and other interfaces, but the documentation is a bit sparse. One concrete question is how do I access the http headers in the endpoint code? Thanks.


Solution

  • You would extract the &HeaderMap:

    use poem::http::HeaderMap;
    
    async fn get_new_ssh_keys(&self, headers: &HeaderMap, req: Json<MyReq>) -> Json<MyResp> {
                                  // ^^^^^^^^^^^^^^^^^^^
    

    The only types that can be used as parameters in your handlers are those that implement FromRequest. You can consult the implementations listed in the docs to determine what you can use (poem_openapi::param::Header is not one of them). More info is in the Extractors section of the main docs.

    Likewise for URL, query, etc. there are the &Uri and Query extractors. If you're needing so much basic information from the request though, I'd suggest extracting the full &Request which will have all that data (except the body I believe).