Skip to content

[Feature Request] Is there a way to handle binary response? #390

Open

Description

@hanayashiki

I find it possible to pass request body in binary, but is it also possible to handle binary response, e.g. converting them to blob?
Thanks in advance.

Activity

  1. hanayashiki commented on Mar 22, 2023

    @hanayashiki
    Author

    Anyway, there must be a way to scramble with plugins. This is my way to get around with the limitation.

    const blobPlugin = (): ZodiosPlugin => {
      const exampleBlob = new Blob();
    
      return {
        name: 'blob',
        request: async (api, config) => {
          const endpoint = api.find((e) => e.method === config.method && e.path === config.url);
    
          if (!endpoint) return config;
    
          // We have to guess whether the response schema is `z.instanceof(Blob)` because the info is not reflected
          let isLikelyInstanceOfBlob = false;
    
          try {
            if (endpoint.response.safeParse(exampleBlob).success) {
              isLikelyInstanceOfBlob = true;
            }
          } catch (e) {}
    
          if (!isLikelyInstanceOfBlob) return config;
    
          return {
            ...config,
            responseType: 'blob',
          };
        },
      };
    };

    Then you simply define your endpoint with response: z.instanceof(Blob) to achieve both blob handling and type-safety

  2. ecyrbe commented on Mar 23, 2023

    @ecyrbe
    Owner

    if you need a blob result, you don't need a plugin, just do :

    client.download({ responseType: 'blob', });

    if you pefer using your plugin, don't attach it globally but only on the route you need it, so no need to safeParse a fake blob:

    client.use('download', blobPlugin());
  3. hanayashiki commented on Mar 23, 2023

    @hanayashiki
    Author

    if you need a blob result, you don't need a plugin, just do :

    client.download({ responseType: 'blob', });

    if you pefer using your plugin, don't attach it globally but only on the route you need it, so no need to safeParse a fake blob:

    client.use('download', blobPlugin());

    Thank you for your advice. My concern is this should probably done in the API Definition level instead of the client. Because the binary response is actually determined by the API contract instead of the client or server.

    About the guessing, probably Zod should implement z.instanceof using a class object instead of a z.custom (which results in an impenetrable z.ZodEffects), just like z.string, z.number, z.object, etc, giving instanceof first class support. If so, the plugin would be perfect

    And I wonder where is

    client.download({ responseType: 'blob', });

    in the documentatation. Am I missing anything?

  4. ecyrbe commented on Mar 23, 2023

    @ecyrbe
    Owner

    There is not yet exemples for binary downloads in the docs. it can definitely be added.

    Blob download is just described in client options:
    http://www.zodios.org/docs/client#request-options

    i agree, that we could leverage the api binary option to force a blob or stream.
    will think about a way to declare both for zodios v11

  5. stale commented on Apr 22, 2023

    @stale

    This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.

  6. reopened this on Apr 29, 2023
  7. stale commented on May 29, 2023

    @stale

    This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.

  8. added
    pinnedissues that should not be closed by bot
    on May 30, 2023
  9. jcdb95 commented on Sep 25, 2023

    @jcdb95

    Is there an update on this example? passing { responseType: 'blob' } as a second parameter of a method generated from an API is not working for me.

  10. hanayashiki commented on Sep 25, 2023

    @hanayashiki
    Author

    Is there an update on this example? passing { responseType: 'blob' } as a second parameter of a method generated from an API is not working for me.

    guess you have to write a middleware yourself

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    pinnedissues that should not be closed by bot

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions