openapi-ts icon indicating copy to clipboard operation
openapi-ts copied to clipboard

Get response headers

Open mfinelli opened this issue 1 year ago • 19 comments

Description

I'm opening an issue for the discussion here: https://github.com/hey-api/openapi-ts/discussions/371#discussion-6495764

My API spec includes some responses where there is both a (JSON) body as well as some extra information in some of the response headers which is useful to me on the client side. I'm reading the code and it seems that the fetch client only returns the data or an error but not the raw response so that I can pull out the headers manually. Is there some other way to access the raw response and/or response headers?

But it would be even better IMO if the client exposed any headers listed in the openapi spec (so that we can get proper types for them etc).

mfinelli avatar Jul 10 '24 21:07 mfinelli

You can do this with the new Fetch API client, is that an option for you?

mrlubos avatar Jul 10 '24 21:07 mrlubos

I'm using the new fetch api client (I think, I have client: "@hey-api/client-fetch" set in my openapi-ts.config.ts file), but the examples on the page all seem to work with the request headers, but I need access to the response headers. The generated client functions all return types like ...get<GetSomeResponse, GetSomeError> so it's not clear how I can get at the raw response.

mfinelli avatar Jul 10 '24 21:07 mfinelli

@mfinelli the new Fetch API client returns 4 things: data, error, request, and response. Response is the raw object containing your headers. They won't be properly typed, but they are there

mrlubos avatar Jul 10 '24 22:07 mrlubos

Ok, I see how it works now. For anyone else finding this issue I'm able to get the raw response like so:

const { data, error, response } = await yourClientFunction(...);

Then you can pull individual headers like this

response.headers.get("X-Your-Header");

@mrlubos I still think it would be a good idea if the generated client could read the headers from the openapi spec and expose them in a more standard way along with the proper types, but if you disagree then you can close this issue as resolved. Thanks for your help!

mfinelli avatar Jul 11 '24 17:07 mfinelli

@mfinelli It depends on how you imagine the standardised way. My understanding is that getting headers from response is straightforward, minus the missing type support. I'd argue that the more stuff you put in the data field (if that was your proposal), the closer it gets to being a typed response object

mrlubos avatar Jul 11 '24 17:07 mrlubos

I'm not sure that I'd like it in the data object unless the data object had two keys body and headers. My usecase is to add extra information on the server side into some custom headers (e.g., pagination details) without affecting the response body itself which corresponds directly to a model that exists in the database and in the openapi spec (e.g., GET /category returns an array of Category objects, I wouldn't want to try and stuff the pagination information in there too)

mfinelli avatar Jul 11 '24 17:07 mfinelli

If you have any ideas around implementation feel free to propose, I didn't spend too much time thinking about this feature

mrlubos avatar Jul 11 '24 19:07 mrlubos

can you tell me how to get headers from that kind of code using v.0.49 of "@hey-api/openapi-ts"?

image

bielas avatar Jul 18 '24 17:07 bielas

@bielas looks like you're using Angular with the new Fetch API client? See my comment in https://github.com/hey-api/openapi-ts/issues/667#issuecomment-2233629443. I didn't prioritise this use case yet, sorry!

mrlubos avatar Jul 18 '24 17:07 mrlubos

@mrlubos nope, I am using react and default client

bielas avatar Jul 18 '24 17:07 bielas

I am confused then, parseAs is available only in the new Fetch API client?

mrlubos avatar Jul 18 '24 17:07 mrlubos

@mrlubos I am using client version 0.1.3 and hey api version 0.49. Seems that is is possible...

bielas avatar Jul 18 '24 18:07 bielas

How then I should proceed?

bielas avatar Jul 18 '24 18:07 bielas

If you provide me any other solution I can stop using parseAs and go with the other one

bielas avatar Jul 18 '24 18:07 bielas

@bielas here's how you can obtain response headers https://stackblitz.com/edit/hey-api-client-fetch-example?file=src%2FApp.tsx%3AL106

mrlubos avatar Jul 18 '24 18:07 mrlubos

how this is possible to work as open api generated code looks like:

export const downloadSubscription = (options: Options<DownloadSubscriptionData>) => {
	return (options?.client ?? client).get<DownloadSubscriptionResponse, DownloadSubscriptionError>(
		{
			...options,
			url: '/v1/self/trainer/subscription/{subscriptionId}/invoice'
		}
	);
};

export type DownloadSubscriptionResponse = Blob | File;

i am not able to extract it like you do here:

const { data, error, response } = await getPetById({

bielas avatar Jul 18 '24 20:07 bielas

@bielas please create a StackBlitz example, hard to tell from the code, it looks fine to me

mrlubos avatar Jul 18 '24 21:07 mrlubos

@mrlubos I hope you will get my point: https://stackblitz.com/edit/vitejs-vite-kemti5?file=src%2FApp.tsx

bielas avatar Jul 18 '24 21:07 bielas

@bielas I can't reproduce it with that. However, I see you're accessing data in the tap() function. data will not contain the headers, you need the raw response object for that

mrlubos avatar Jul 18 '24 22:07 mrlubos