-
Notifications
You must be signed in to change notification settings - Fork 338
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
fix responding with application/json #604
Conversation
CHANGELOG.md
Outdated
@@ -22,6 +22,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), | |||
- Prism is correctly handling the `csv` collection format argument property in OAS2 documents #577 | |||
- Prism is correctly returning the response when the request has `*/*` as Accept header #578 | |||
- Prism is correctly returning a single root node with the payload for XML data #578 | |||
- Prism is correctly serializing application/json responses |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These changelog messages are not as effective at communicating what happened.
"Prism is" we dont need this because we know its Prism
"correctly" we know we fixed something this in in the fixed section
What was fixed? What was it doing before? What is the scenario in which application/json scenarios were broken?
People read changelogs to find out if a specific situation that they might have noticed has been fixed, but this is not giving them that information. It's just kinda vaguely saying "something about json works better than before"
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The correct changeling here would be a line explaining that Prism is now giving higher priority to application/json
Accept content type, and it's not a "fallback" format anymore.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Moreover this is not in the right section, it should go in the Unreleased
part
packages/http-server/src/server.ts
Outdated
@@ -41,6 +41,10 @@ export const createServer = (operations: IHttpOperation[], opts: IPrismHttpServe | |||
}); | |||
|
|||
server.addHook('onSend', (request, reply, payload, done) => { | |||
if (reply.getHeader('content-type') === 'application/json') { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What is the reasoning for this? If the api designer has defined the header as application/json
why do we want to force the utf8 charset on there?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What about support for application/{dataType}+json
or application/json; charset=cp1250
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@philsturgeon, @StefanDywersant, charset=utf-8
was already enforced by fastify
with its default application/json
serializer. We sometimes returned application/json
without charset=utf-8
because... the response was wrongly serialized by some other serializer (like instead of a serializer for JSON, the data was serialized with a serializer for XML). application/{whatever}+json
is here https://github.com/stoplightio/prism/blob/master/packages/http-server/src/serializers.ts#L9
Also, haven't found other charset than utf-8 logic in the code
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What about support for application/{dataType}+json
This scenario is already supported in the serialiser. I would not bother about the charset
— it is actually something that is inferred by the browser most of the times. I am quite sure there was also a proposal to remove it completely from the content type header.
examples: | ||
application/json: | ||
schema: | ||
nullable: true |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This test might just show that no body is output when schema is a null, maybe the more standard type: string
would create more confidence that this test is doing what we want for the reasons we want.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I agree with @philsturgeon here and more importantly 204
responses do not have content and so Fastify will delete it no matter if you're trying to send it to the client, so let's change this to a regular 200.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Couple of changes requested, but this is going in the right direction.
@StefanDywersant I am starting to agree with you and @lag-of-death that the current serialiser package is giving us more headache than solving us problems — so I think you were right and we'll probably look for a better solution soon.
In mean time, let's stick with what we have right now.
@@ -11,6 +11,13 @@ export default [ | |||
}, | |||
serializer: JSON.stringify, | |||
}, | |||
{ | |||
regex: { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You do not need to create a new section, you can simply modify the one at line 9 and add application/json
in the array
packages/http-server/src/server.ts
Outdated
@@ -41,6 +41,10 @@ export const createServer = (operations: IHttpOperation[], opts: IPrismHttpServe | |||
}); | |||
|
|||
server.addHook('onSend', (request, reply, payload, done) => { | |||
if (reply.getHeader('content-type') === 'application/json') { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What about support for application/{dataType}+json
This scenario is already supported in the serialiser. I would not bother about the charset
— it is actually something that is inferred by the browser most of the times. I am quite sure there was also a proposal to remove it completely from the content type header.
examples: | ||
application/json: | ||
schema: | ||
nullable: true |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I agree with @philsturgeon here and more importantly 204
responses do not have content and so Fastify will delete it no matter if you're trying to send it to the client, so let's change this to a regular 200.
/check-email: | ||
get: | ||
responses: | ||
"204": |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ditto, do not use 204 here.
"204": | |
"200": |
@@ -22,7 +22,7 @@ mock -p 4010 | |||
curl -i -X GET http://localhost:4010/todos -H "accept: application/xml, application/json" | |||
====expect==== | |||
HTTP/1.1 200 OK | |||
content-type: application/json | |||
content-type: application/json; charset=utf-8 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's ok to return just application/json
CHANGELOG.md
Outdated
@@ -22,6 +22,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), | |||
- Prism is correctly handling the `csv` collection format argument property in OAS2 documents #577 | |||
- Prism is correctly returning the response when the request has `*/*` as Accept header #578 | |||
- Prism is correctly returning a single root node with the payload for XML data #578 | |||
- Prism is correctly serializing application/json responses |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The correct changeling here would be a line explaining that Prism is now giving higher priority to application/json
Accept content type, and it's not a "fallback" format anymore.
Fixes #599
Checklist
What is the current behavior? What is the new behavior?
Handling
application/json
in Accept header is inconsistent.This PR implements a small-footprint solution. But we should really consider a solution similar to the one proposed in: #568
The issue:
We receive: Accept:
application/json, text/plain
Fastify looks into the serializers and sees that there is no serializer for
application/json
, but foundstext/plain
serializer and uses this. This is wrong. This happens because ourapplication/json
serializer is a fallback serializer (when no serializer inserializers
(https://github.com/stoplightio/prism/blob/master/packages/http-server/src/serializers.ts) is found)Why the added charset=utf8?
This is to solve the inconsistency we have. This was also addressed in #568, but didn't make it to
master
.An example of the inconsistency from
master
:prism/packages/http-server/src/__tests__/server.oas.spec.ts
Lines 309 to 319 in 887e2d0
prism/packages/http-server/src/__tests__/server.oas.spec.ts
Lines 323 to 332 in 887e2d0
So, in the first example we have
application/json; charset=utf-8
, but in the second one onlyapplication/json
.And why is this happening? Because #568 (comment)