Ky: Set the `accept` header when shortcut methods are called

Created on 17 Jan 2019  路  7Comments  路  Source: sindresorhus/ky

Issuehunt badges

Mentioned it in https://github.com/sindresorhus/got/pull/695#issuecomment-453865817

One thing that got does, which I think it awesome, and which we don't have in ky, is setting the accept header when .json() is called.

@sholladay What's the benefit of sending this header? It works already without.

selrond earned $20.00 by resolving this issue!

Rewarded on Issuehunt enhancement low priority

Most helpful comment

In simple cases, setting the accept header will make no difference. But for complex apps, there are sometimes situations where a server is willing and able to respond with two different representations for the same URL and being explicit about it can be useful. An intuitive example of this could be an error response returned for https://my-site.com/admin, where we are not logged in or don't have admin privileges. Should the server return a friendly HTML login page or a JSON error or something else? Who knows if a human is looking at the response or if it's a script. And the HTML view might be much more expensive to render, for example.

By default, with no accept header, the server has to guess what the client might want. hapi servers return JSON by default, whereas Apache and NGINX return HTML. There's no universal standard for this. Instead, we have content negotiation. The client can advertise that it wants JSON specifically, which makes sense for ky(url).json() because it's going to try to parse the response as JSON.

All that said, in practice, this will probably have little impact. APIs usually just return JSON no matter what and websites won't magically be converted to JSON just because ky asks for it. The case where multiple representations are available is relatively uncommon. But I use accept: text/html to ensure that only browsers get redirects to /login and friendly error pages, among other things. It's very nice to have when you _do_ need it. It's the correct thing to do, but low priority, in my opinion.

All 7 comments

From the MDN:

The Accept request HTTP header advertises which content types, expressed as MIME types, the client is able to understand.

In simple cases, setting the accept header will make no difference. But for complex apps, there are sometimes situations where a server is willing and able to respond with two different representations for the same URL and being explicit about it can be useful. An intuitive example of this could be an error response returned for https://my-site.com/admin, where we are not logged in or don't have admin privileges. Should the server return a friendly HTML login page or a JSON error or something else? Who knows if a human is looking at the response or if it's a script. And the HTML view might be much more expensive to render, for example.

By default, with no accept header, the server has to guess what the client might want. hapi servers return JSON by default, whereas Apache and NGINX return HTML. There's no universal standard for this. Instead, we have content negotiation. The client can advertise that it wants JSON specifically, which makes sense for ky(url).json() because it's going to try to parse the response as JSON.

All that said, in practice, this will probably have little impact. APIs usually just return JSON no matter what and websites won't magically be converted to JSON just because ky asks for it. The case where multiple representations are available is relatively uncommon. But I use accept: text/html to ensure that only browsers get redirects to /login and friendly error pages, among other things. It's very nice to have when you _do_ need it. It's the correct thing to do, but low priority, in my opinion.

@issuehunt has funded $20.00 to this issue.


I'm gona try to tackle this one

Just to make sure, here's what I understand needs to be done:

When calling one of these (shortcut) methods

ky.post
ky.put
ky.patch
ky.head
ky.delete

there needs to be Accept: application/json header set by default.

Did I understand it correctly?

Yup.

@sindresorhus has rewarded $18.00 to @selrond. See it on IssueHunt

  • :moneybag: Total deposit: $20.00
  • :tada: Repository reward(0%): $0.00
  • :wrench: Service fee(10%): $2.00
Was this page helpful?
0 / 5 - 0 ratings