poem icon indicating copy to clipboard operation
poem copied to clipboard

XML Response is not correctly following serde's attribute.

Open InterStella0 opened this issue 1 year ago • 1 comments

Context

So, I've been trying to produce a sitemap.xml via poem, and the XML response does not use the provided serde attribute. But when i use the quick_xml to string, and return as PlainText, it works normally.

Expected Behavior

<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
   <url><loc>domain.com</loc></url>
   <url><loc>domain.com/A</loc></url>
   <url><loc>domain.com/B</loc></url>
</urlset>

Actual Behavior

<root>
  <namespace>http://www.sitemaps.org/schemas/sitemap/0.9</namespace>
  <urls><loc>domain.com</loc></urls>
  <urls><loc>domain.com/A</loc></urls>
  <urls><loc>domain.com/B</loc></urls>
</root>

Steps to Reproduce the Problem

  1. Define struct with #[serde(...)] usage
  2. Use poem_openapi::payload::Xml as a return type

Full Minimal Code

use poem_openapi::{Object, OpenApi};
use poem_openapi::payload::{PlainText, Xml};
use serde::{Deserialize, Serialize};

#[derive(Object, Serialize, Deserialize)]
struct Url {
    loc: String,
}

#[derive(Object, Serialize, Deserialize)]
#[serde(rename_all = "lowercase", rename = "urlset")]
struct UrlSet {
    #[serde(rename = "@xmlns")]
    namespace: String,
    #[serde(rename = "url")]
    urls: Vec<Url>,
}

fn produce_xml() -> UrlSet{
    let base_url = "domain.com";
    let urls = vec![
        Url{ loc: base_url.to_string() },
        Url{ loc: format!("{}/A", base_url) },
        Url{ loc: format!("{}/B", base_url) },
    ];
    UrlSet {
        namespace: "http://www.sitemaps.org/schemas/sitemap/0.9".to_string(),
        urls,
    }
}

pub struct MiscApi;


#[OpenApi]
impl MiscApi {
    #[oai(path = "/sitemap1.xml", method = "get")]
    async fn sitemap1(&self) -> Xml<UrlSet> {
        let resp = produce_xml();
        Xml(resp)
    }
    #[oai(path = "/sitemap2.xml", method = "get")]
    async fn sitemap2(&self) -> PlainText<String> {
        let resp = produce_xml();
        PlainText(quick_xml::se::to_string(&resp).unwrap_or_default())
    }
}

/sitemap1.xml produces the wrong output /sitemap2.xml produces the correct output

Specifications

  • Version: poem 3.1.7, poem-openapi 5.1.8
  • Platform: Linux (Pop!_OS)

InterStella0 avatar Mar 09 '25 10:03 InterStella0

Have the same issue...

dominiwe avatar Aug 08 '25 20:08 dominiwe