koajs / koa

Expressive middleware for node.js using ES2017 async functions
https://koajs.com
MIT License
35.11k stars 3.22k forks source link

[feat] Support Web (WHATWG) stream, Blob and Response #1777

Closed hax closed 2 months ago

hax commented 11 months ago

Describe the feature

Currently response.body= or ctx.body= support buffers, strings and Nodejs streams. I suggest we also add support to Web stream, Blob and Response (currently just fallback to json which break users expectation), maybe also all async iterables, Nodejs already have those APIs in global.

This is my workaround, it works but it's better to support them in the core.

app.use(async (ctx, next) => {
    await next();
    // Note: need to clear type before set body, or the type might always be json
    // See Koa impl: https://github.com/koajs/koa/blob/dbf4b8f41286befd53dfd802740f2021441435bf/lib/response.js#L134-L190
    if (ctx.body instanceof ReadableStream) {
        ctx.type = "";
        ctx.body = Readable.fromWeb(ctx.body);
    } else if (ctx.body instanceof Blob) {
        const blob = ctx.body;
        ctx.type = blob.type;
        ctx.length = blob.size;
        ctx.body = Readable.fromWeb(blob.stream());
    } else if (ctx.body instanceof Response) {
        const response = ctx.body;
        ctx.status = response.status;
        ctx.type = "";
        // Note: don't clear all headers so the headers added by middlewares still effective
        for (const [name, value] of response.headers) ctx.set(name, value);
        if (response.redirected) ctx.redirect(response.url);
        else ctx.body = Readable.fromWeb(response.body);
    }
    // maybe we could also support all async iterables
    // else if (ctx.body[Symbol.asyncIterator]) {
    //   ctx.type = ""; ctx.body = Readable.from(ctx.body);
    // }
});

Checklist

fengmk2 commented 11 months ago

@hax Cool! Please send us a pull request, we love to merge it!

iwanofski commented 11 months ago

I support this, especially if its additive only (i.e. no breaking)

image72 commented 3 months ago

@fengmk2 have any plan to support this feature?

fengmk2 commented 2 months ago

@fengmk2 have any plan to support this feature?

@hax has given the implementation code and you are welcome to submit a pull request.

TommyDew42 commented 2 months ago

Will have a PR for it soon

kravorkid commented 2 months ago

@fengmk2 i've done a PR for this i'm open to suggestions for improvement 😉