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

feat(openapi-fetch): Allow returning Response from onRequest callback #2091

Open
wants to merge 1 commit into
base: main
Choose a base branch
from

Conversation

p-dubovitsky
Copy link

@p-dubovitsky p-dubovitsky commented Jan 4, 2025

Changes

This PR closes #2072 by adding ability to return Response from onRequest middleware hook. This allows middleware to short-circuit the request chain by returning a response directly, which is useful for cases such as deduplicating or caching responses to avoid unnecessary network requests.

How to Review

Please check that:

  • Early Response from onRequest properly skips remaining middleware chain
  • Test coverage is sufficient
  • Documentation clearly explains new functionality

Key implementation details:

  • No changes to existing middleware behavior
  • When Response is returned:
    • The request is not sent to the server
    • Subsequent onRequest handlers are skipped
    • onResponse handlers are skipped

Checklist

  • Unit tests updated
  • docs/ updated (if necessary)
  • pnpm run update:examples run (only applicable for openapi-typescript)

@p-dubovitsky p-dubovitsky requested a review from a team as a code owner January 4, 2025 14:33
@p-dubovitsky p-dubovitsky requested a review from gzm0 January 4, 2025 14:33
Copy link

netlify bot commented Jan 4, 2025

👷 Deploy request for openapi-ts pending review.

Visit the deploys page to approve it

Name Link
🔨 Latest commit fad2a50

Copy link

changeset-bot bot commented Jan 4, 2025

🦋 Changeset detected

Latest commit: fad2a50

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 3 packages
Name Type
openapi-fetch Patch
openapi-react-query Patch
swr-openapi Patch

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

Copy link
Contributor

@gzm0 gzm0 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice! (and sorry for the somewhat tardy review).

Mostly nits on tests, and one doubt in the example that we probably should address.

onResponse({ request, response }) {
if (response.ok) {
const key = getCacheKey(request);
cache.set(key, response);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are you sure we do not need to clone the response here? The response we return is (probably) going to be consumed by the caller.

IIUC, clone() will throw if the response has already been used:

clone() throws a TypeError if the response body has already been used.

(https://developer.mozilla.org/en-US/docs/Web/API/Response/clone)

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, I think you're right. Thanks for your consideration!

response = result;
break;
} else {
throw new Error("onRequest: must return new Request() or Response() when modifying the request");
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this error message was wrong an now it feels even more wrong :-/ (IIUC you must not return new Request() but mutate the request in place and return it, unclear to me why returning the request is even necessary...).

Probably not blocking for this PR, but a fix would be appreciated.

Copy link
Contributor

@drwpow drwpow Jan 25, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah I’m keen to just remove this (not necessarily in this PR, just in general); this is not true in some cases. It was meant to provide a friendlier error for folks, but I actually think just letting the platform surface the error is more helpful, rather than us getting in the way

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure I understood you correctly. Do you want to throw an error without a message or something else?


test("can return response directly from onRequest", async () => {
const customResponse = Response.json({});
const client = createObservedClient<paths>();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
const client = createObservedClient<paths>();
const client = createObservedClient<paths>({}, () => throw new Error("unexpected call to fetch"));

This way, we make sure we really do not call fetch.


test("skips subsequent onRequest handlers when response is returned", async () => {
let onRequestCalled = false;
const customResponse = Response.json({});
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: Inline below? You don't actually need the reference for this test.


test("skips onResponse handlers when response is returned from onRequest", async () => {
let onResponseCalled = false;
const customResponse = Response.json({});
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same: Inline below?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice tests!

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks!

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

Successfully merging this pull request may close these issues.

Allow returning Response from onRequest callback
3 participants