-
-
Notifications
You must be signed in to change notification settings - Fork 488
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
Do not set content-type on body-less requests #1826
Do not set content-type on body-less requests #1826
Conversation
🦋 Changeset detectedLatest commit: 1812aff The changes in this PR will be included in the next version bump. This PR includes changesets to release 2 packages
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
docs/openapi-fetch/api.md
Outdated
or when instantiating the client. Setting `Content-Type` to `null` will omit the header, however the native fetch API | ||
will likely set it to `text/plain` in this case. |
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.
Not sure we really need to mention the null
thing anymore, when this behaves properly now. 🤷♂️
Opinions?
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.
Yeah just remove it 🔪
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.
BTW Just a thought... I wonder whether allowing the bodySerializer
to return {contentType: "...", body: ...}
wouldn't be the best way to allow transport customization 🤔
const BODIES = [{ prop: "a" }, {}, "", "str", null, false, 0, 1, new Date("2024-08-07T09:52:00.836Z")] as const; | ||
const METHOD_BODY_COMBINATIONS = BODY_ACCEPTING_METHODS.flatMap(([method]) => | ||
BODIES.map((body) => [method, body] as const), | ||
); |
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.
@kerwanp Guessing from #1825 (comment) you won't like this 🤣
Happy to ditch the methods, but I'd rather keep the various bodies as this was broken until #1825.
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.
Aha I'm not against this when behavior have to be different between cases, the pattern you use looks good to me! The methods constants could be moved at the top of the file to be reused in other tests.
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.
Until they are actually reused in other tests, they IMO make more sense when they are collocated with the test itself. It's just less scrolling to understand how they are used. Anyway this is just my opinion I've grown over the years, nothing I would fight for.
I guess we are in agreement that this file already does too much and deserves some larger refactoring and splitting. Let's maybe open a separate issue and discuss a bit what the desired structure could look like?
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.
Great work! Same thing as the other pull request, I'll let @drwpow review this
// the fetch implementation won't allow sending a body without content-type, | ||
// so it invents one up and sends it, hopefully this will be consistent across | ||
// local environments and won't make the tests flaky | ||
expect(contentType).toBe("text/plain;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.
Yeah this one is a bit scary, it's a potential IWOMM scenario.
It seems the test ensure that the default content-type is basically removed?
Maybe we can simply do something like this?
expect(contentType).toBe("text/plain;charset=UTF-8"); | |
expect(contentType).not.toBe("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.
Yeah, that sounds better. Good idea.
const BODIES = [{ prop: "a" }, {}, "", "str", null, false, 0, 1, new Date("2024-08-07T09:52:00.836Z")] as const; | ||
const METHOD_BODY_COMBINATIONS = BODY_ACCEPTING_METHODS.flatMap(([method]) => | ||
BODIES.map((body) => [method, body] as const), | ||
); |
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.
Aha I'm not against this when behavior have to be different between cases, the pattern you use looks good to me! The methods constants could be moved at the top of the file to be reused in other tests.
@@ -859,6 +855,138 @@ describe("client", () => { | |||
}); | |||
}); | |||
|
|||
describe("content-type", () => { | |||
const BODY_ACCEPTING_METHODS = [["PUT"], ["POST"], ["DELETE"], ["OPTIONS"], ["PATCH"]] as const; |
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.
nit: Is there a reason to have two dims arrays here?
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 is what the each method officially expects. It's a list of param sets where each set can consist of multiple params. The API supports a flat array, where [x]
is treated as [[x]]
, but I don't really fancy these magical interfaces and prefer to be explicit. Imagine what happens when x
is actually an array?
See Martin’s comments/questions on tests. The implementation seems to solve the original issue. But in order to approve/merge we’ll need a |
I'll address this once I'm back from my vacation. Thanks! |
@drwpow should this really be a |
So I did 😄! Thank you, yes this should be a minor (“breaking”) release. |
e2779cd
to
502cc70
Compare
Unfamiliar combination 😄 , but here you go. |
Thanks! This is actually following standard semver. Pre-1.0, the minor almost always signals breaking changes. Technically you can choose to either put features in minor releases or patches, but I choose the latter so a minor predictably means some breaking change. |
502cc70
to
fdeecfe
Compare
This didn't make sense to me, until I stopped looking at (and releasing 🤦 ) a wrong package. (openapi-typescript v7). Rebased and hopefully ready for merging. |
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.
Great addition and tests, thank you!
`Content-Type` is omitted, allowing the browser to set it automatically with the correct message part boundary. | ||
|
||
You can also set `Content-Type` manually through `headers` object either in the fetch options, | ||
or when instantiating the client. |
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 forget if I said this already, but thanks for adding this! Little docs improvements go a long way and are always welcome ❤️
The documentation states
It seems like I actually can't set the header manually anymore. I have a fetch options object {
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
},
bodySerializer: (body: Record<string, string | number | boolean | undefined | null>) => {
return new URLSearchParams(
Object.entries(body).map(([key, value]) => [String(key), String(value)])
).toString();
},
} ...but the EDIT: Weirdly, this seems to happen since |
Changes
Resolves #1694
Important: This PR touches the same code as #1825 and in-fact includes the same fix by itself. I recommend merging #1825 first.
This PR prevents Content-Type header from being set on requests with no body. This is required to ensure compatibility with strict server impls. such as fastify.
How to Review
Checklist
docs/
updated (if necessary)pnpm run update:examples
run (only applicable for openapi-typescript)