Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Koa always overwrite Content-Type for JSON responses #1120

Open
brunoabreu opened this issue Jan 11, 2018 · 9 comments
Open

Koa always overwrite Content-Type for JSON responses #1120

brunoabreu opened this issue Jan 11, 2018 · 9 comments

Comments

@brunoabreu
Copy link

const Koa = require('koa');
const app = new Koa();
app.use(ctx => {
  ctx.set('Content-Type', 'application/vnd.myapi.v1+json');
  ctx.body = {message: 'hello'};
});
app.listen(3000);

When running this code I aways get Content-Type: application/json; charset=utf-8.

I can make it work if I write the header after setting the body. It only affects json responses. I'm not sure if that's a bug, but I couldn't find any information about that behavior in documentation.

@fl0w
Copy link
Contributor

fl0w commented Jan 11, 2018

Yes, setting body is basically a switch statement, where the default case is to assume value is json, which removes content-type and sets it to application/json.

koa/lib/response.js

Lines 179 to 181 in 6baa411

// json
this.remove('Content-Length');
this.type = 'json';

I'm not sure about intent but this might be a feature.
It's an easy fix by just checking setType (as most/all other cases does), but it's a breaking fix as users may be relying on this behaviour.

@jonathanong
Copy link
Member

seems like a bug where it overwrites the content type when the content type is set and has +json in it.

@uzil
Copy link

uzil commented Feb 2, 2018

Check if body has value of type object, and if the header contains +json preserve the user given header.
Is this the desired implementation of fix for this bug?

fl0w added a commit to fl0w/koa that referenced this issue Feb 2, 2018
@nerdyman
Copy link

nerdyman commented May 14, 2018

Is there a merged fix for this? I'm making an API JSON API compliant but having to manually declare type for every response is a hassle.

@tiendq
Copy link

tiendq commented Jul 12, 2018

what's issue that keep the PR not merged?

@TehShrike
Copy link

For reference, the PR in question is #1131

@jeppech
Copy link

jeppech commented Feb 15, 2020

I'm just gonna note this here, for others to use, as I had a hard time finding a solution.

A temporary "fix" to this, is to set a stringified JSON body, instead of a json object. Then the header will not be overridden, as we'll hit this condition where the setType assertion is made.

ctx.body = JSON.stringify(data)

@cjaccino
Copy link

There may be more nuance required than what is above, but Koa shouldn't overwrite a valid media type that has a structured syntax suffix like +json.
The practice undermines alignment with other of the IETF's proposed standards, such as rfc7807: Problem Details for HTTP APIs.

A bit on why.
When a client sends a message with a structured data payload, it will typically use application/json, application/xml or similar as the Content-Type. The recipient will be able to validate the payload syntactically, but it nothing to understand the message semantically. It has inadequately satisfied REST's Self-Descriptive Messages constraint. The message processor must make assumptions or examine the payload heuristically. Since the majority of applications assume that a URI points to no more than one document or resource representation, this has not been too much of a problem for most.

Use of a more descriptive media types provides a parade of benefits. It can enable a far more expressive web, reduce guesswork in message processing, and provide for more graceful evolution of applications that handle structured data.

Koa is amazing for being so flexible. It should make this possible, too.

For reference,

@mrl5
Copy link

mrl5 commented Nov 11, 2021

hello, I just want to confirm a workaround for the issue that @brunoabreu already wrote in his first post:

I can make it work if I write the header after setting the body.

I tested it with version 2.11.0

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

10 participants