Once, I was working on a project at my company. There was a requirement to extract a single key from a JSON response coming from a backend API and use it in a redirect URL. Android and iOS developers used the same endpoint and completed their part without issues. But the web app I was building didn’t work.
I checked the response model. I was expecting a JSON object—but what I got wasn’t JSON at all. Or so I thought.
I dug into it and opened the Swagger docs. Turns out, the response was valid JSON—but the Content-Type
was set to "text/plain"
instead of "application/json"
. I asked the mobile devs how they handled it. They said they always parse the response manually, regardless of the Content-Type
.
But in the frontend world, we don’t just JSON.parse()
everything. We rely on the response headers to determine the format. If the header says it’s plain text, we treat it as plain text.
I begged the backend dev to change the Content-Type
to "application/json"
—and they did.
When & How to Parse API Responses
APIs can return responses in many formats: JSON, XML, HTML, plain text, SGML, etc. You must not assume the format based on the content. Always check the Content-Type
header first.
Here’s a simple guide:
Content-Type | Description |
---|---|
application/json | JSON data |
application/xml | XML data |
text/plain | Plain text |
text/html | HTML content |
text/sgml | SGML content |
All the following examples are meant to be used inside async functions, since most fetch methods return Promises.
✅ JSON
If Content-Type
is not application/json
, do not treat the response as JSON.
json{
"name": "John",
"age": 30
}
javascriptconst response = await fetch('https://api.example.com/data');
const contentType = response.headers.get('Content-Type');
if (contentType && contentType.includes('application/json')) {
const data = await response.json();
console.log(data.name); // John
}
✅ XML
Client-side:
xml<note>
<to>Furkan</to>
<from>ChatGPT</from>
<message>Hello!</message>
</note>
javascriptconst response = await fetch('https://api.example.com/data');
const text = await response.text();
const parser = new DOMParser();
const xmlDoc = parser.parseFromString(text, "application/xml");
const to = xmlDoc.getElementsByTagName("to")[0].textContent;
console.log(to); // Furkan
Server-side (Node.js):
javascriptconst xml2js = require('xml2js');
const response = await fetch('https://api.example.com/data');
const text = await response.text();
xml2js.parseString(text, (err, result) => {
if (err) throw err;
console.log(result.note.to[0]); // Furkan
});
✅ HTML
html<p>Hello!</p>
<figure>
<img src="https://example.com/image.jpg" alt="Example Image">
<figcaption>Example Image</figcaption>
</figure>
<p>This is an example article.</p>
We assume there’s an <article>
element in the DOM and insert the content there:
javascriptconst response = await fetch('https://api.example.com/html');
const htmlDoc = await response.text();
const article = document.querySelector('article');
article.innerHTML = htmlDoc;
✅ Plain Text
textYou've got mail!
javascriptconst response = await fetch('https://api.example.com/message');
const text = await response.text();
const box = document.getElementById('message-box');
box.textContent = text;
✅ SGML
SGML is rare on the web today. But if the server sends Content-Type: text/sgml
, it should be parsed accordingly.
Example content:
sgml<!DOCTYPE note SYSTEM "note.dtd">
<note>
<to>Furkan</to>
<from>ChatGPT</from>
<message>Hello!</message>
</note>
There’s no native browser support for parsing SGML, so you’d need a third-party parser on the server side. This example is illustrative only:
javascriptconst sgml2js = require('sgml2js');
const response = await fetch('https://api.example.com/sgml');
const sgmlText = await response.text();
const sgmlDoc = sgml2js.parse(sgmlText);
console.log(sgmlDoc.note.to[0]); // Furkan
🔚 Conclusion
Never parse a response without checking its Content-Type
first. That header tells you how to treat the body.
If you want to parse the response as a certain format, make sure the backend sends the correct content type. Otherwise, you’re just guessing—and your app might break silently.
Album of the day: