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: Add support for responseType option #376

Open
wants to merge 6 commits into
base: main
Choose a base branch
from

Conversation

Rikusor
Copy link

@Rikusor Rikusor commented Nov 26, 2024

Hello,

This is my first contribution in my life to Open Source project. Please be kind.

In this PR you can find my approach to tackling #29 -- My project needed to get the data as ArrayBuffer from a PDF Document fetcher API, that is why I used it as an example case in read me file.

I took the similar approach as Axios instead of relying on headers, as personally I think this has better type safety and is more transparent to consumers of the library.

@Rikusor Rikusor requested a review from a team as a code owner November 26, 2024 09:28
Copy link

codesandbox-ci bot commented Nov 26, 2024

This pull request is automatically built and testable in CodeSandbox.

To see build info of the built libraries, click here or the icon next to each commit SHA.

@slagiewka
Copy link

this has better type safety and is more transparent to consumers of the library

On one hand it is true. Users calling are made aware of possible return types. This, however, brings no guarantees what is going to be returned.

With this changeset, it would be possible to make a mistake (or force an error) by requesting responseType: 'json'. Any API that returns other data like e.g. text/plain or application/octet-stream will not be aware of such user request. This will fail when response tries to parse itself to JSON client-side.

In terms of type safety, users in such need, will need perform type refinement in order to make sure if the returned value is of that instance anyway. Yes, it would be possible to have a small shim on top of it that adds some type "safety", e.g.:

getArrayBuffer(path: string, request?: GetRequest<CO>): Promise<ArrayBuffer> {
    return this.get<ArrayBuffer>(path, {responseType: 'arraybuffer', ...request});
}

but it would still be wishful thinking.

What I still have not grasped in Axios' approach, is why indeed it's not relying on headers. Content negotiation is a big part of the web. It provides a well-defined flow for how client-server communication works.
Should Accept be used instead of responseType, the client could ask for application/pdf and will get an error if the server cannot provide it.
Furthermore, well known cases can be handled client-side, as are in this library. text/plain can be resolved to response.text(), application/json can be resolved to response.json(). Of course, supporting all MIME types would be impossible, that's where sane fallbacks should happen.

This is where this library drops the ball. The standard is that anything that is not human readable and contains binary data shouldn't be treated as text/plain, therefore response.text() as the default is a problem. Any unknown data should rather be returned to the user as a Blob or ArrayBuffer. Especially when Content-Type falls into any application/* subtype that is not handled explicitly.

If I had any say in this project (which I don't) I would prefer it would pay closer attention to content negotiation. This could allow for non-JSON, non-text responses to be provided to the user.

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.

2 participants