Koa XML Body Parser Middleware
raw JSON →koa-xml-body is a Koa middleware designed to parse XML request bodies, making the parsed data available on `ctx.request.body`. The current stable version is 3.0.0, published approximately 3 years ago, which is compatible with Koa 2.x and 3.x, while Koa 1.x users should opt for `koa-xml-body@1.x`. It internally uses `xml2js` for the actual XML parsing, exposing its configuration options via the `xmlOptions` property. Key differentiators include its explicit focus on XML content types (e.g., `application/xml`, `text/xml`), robust error handling customization through an `onerror` callback, and seamless integration with other body parsers by carefully managing `ctx.request.body`. Its release cadence is generally tied to bug fixes or Koa compatibility updates rather than rapid feature additions, suggesting a maintenance-oriented status.
Common errors
error HTTP Status 413: Payload Too Large ↓
limit option when initializing the middleware: app.use(xmlParser({ limit: '5mb' })) to accommodate larger XML payloads. error Error: Non-whitespace before first tag. ↓
content-type header to confirm it is application/xml or text/xml. error TypeError: Cannot read properties of undefined (reading 'body') ↓
Content-Type header is set to application/xml or text/xml. Check for preceding body parsing middleware that might have already consumed or processed the request stream. Add a console.log(ctx.request.body) to debug when it becomes undefined. Warnings
breaking Version 3.x of `koa-xml-body` is designed for Koa 2.x and newer. Users on Koa 1.x must use `koa-xml-body@1.x` to maintain compatibility and avoid runtime errors. ↓
gotcha By default, `koa-xml-body` will throw an error if XML parsing fails and no `onerror` option is provided. This can lead to unhandled exceptions and server crashes in production environments. ↓
gotcha The default `limit` for the XML body size is 1MB. Requests exceeding this limit will result in a `413 Payload Too Large` error, which might be insufficient for applications handling large XML documents. ↓
gotcha When integrating `koa-xml-body` with other generic body parsers (like `koa-bodyparser` or `koa-body`), the order of middleware matters. `koa-xml-body` should generally be placed before other body parsers if you specifically want it to handle XML, but it is designed to integrate well, carefully checking `ctx.request.body`. ↓
Install
npm install koa-xml-body yarn add koa-xml-body pnpm add koa-xml-body Imports
- koaXmlBody wrong
import { koaXmlBody } from 'koa-xml-body'; // Not a named export for the default functioncorrectimport koaXmlBody from 'koa-xml-body'; - xmlParser wrong
import xmlParser from 'koa-xml-body'; // Incorrect for CommonJS environments, use require()correctconst xmlParser = require('koa-xml-body'); - koaXmlBodyWithOptions wrong
app.use(require('koa-xml-body', { limit: '5mb' })); // Options are passed as an argument to the function, not as a second argument to requirecorrectimport koaXmlBody from 'koa-xml-body'; app.use(koaXmlBody({ limit: '5mb', xmlOptions: { explicitArray: false } }));
Quickstart
import Koa from 'koa';
import koaXmlBody from 'koa-xml-body';
const app = new Koa();
// Apply the XML body parser middleware with custom options
app.use(koaXmlBody({
limit: '2mb', // Set a higher limit if expecting larger XML payloads
encoding: 'utf8', // Ensure correct encoding is used
xmlOptions: {
explicitArray: false, // Prevents single child elements from being wrapped in arrays
ignoreAttrs: true, // Ignores XML attributes and only parses element values
},
key: 'parsedXml', // Store parsed XML in ctx.request.parsedXml instead of ctx.request.body
onerror: (err, ctx) => {
console.error('XML parsing error:', err.message);
ctx.status = 400;
ctx.body = 'Invalid XML format.';
},
}));
app.use(async (ctx) => {
if (ctx.method === 'POST' && ctx.is('application/xml')) {
// Access the parsed XML body based on the 'key' option
const xmlData = ctx.request.parsedXml;
if (xmlData) {
console.log('Received XML:', JSON.stringify(xmlData, null, 2));
ctx.body = { status: 'success', received: xmlData };
} else {
ctx.status = 400;
ctx.body = { status: 'error', message: 'No XML body received or parsed.' };
}
} else {
ctx.body = 'Send an XML POST request to this endpoint.';
}
});
const port = 3000;
app.listen(port, () => {
console.log(`Koa server listening on http://localhost:${port}`);
});
// Example usage with curl:
// curl -X POST -H "Content-Type: application/xml" -d '<root><item id="1">Value1</item><item id="2">Value2</item></root>' http://localhost:3000