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

Internal sub-request #23

Open
evert opened this issue Mar 25, 2018 · 10 comments
Open

Internal sub-request #23

evert opened this issue Mar 25, 2018 · 10 comments

Comments

@evert
Copy link

evert commented Mar 25, 2018

Dear Koa devs,

Super happy with Koa. We've been using it for over a year.

I'm facing an issue where I want to do an 'internal subrequest'. What this means is that a real HTTP request comes in, and I want to write a middleware that creates a brand new (fake) HTTP request and return the result.

This middleware will then take the result and do some post-processing before returning it.

Is there a standard way to solve this problem with Koa? I want to avoid doing a 'real' HTTP request on the local server, because it seems like a lot of overhead. I don't really want to invoke the TCP/HTTP stack, although my prototype does use that approach.

Any pointers here are welcome!

@fl0w
Copy link

fl0w commented Mar 25, 2018

I'm having issues relating question to a use case which in turn makes the question weird. What problem are you trying to solve?

In any case, either you just write a middleware which you use first (and thus last), or if you want to use native http server you could wrap app.middleware maybe?

@evert
Copy link
Author

evert commented Mar 25, 2018

There's a few different use-cases possible, but the one I'm solving right now is that I'm working on an API that uses HAL. HAL has a feature to allow embedding of other resources.

What I want to do is intercept a request and automatically do this. Basically I want to make a 'fake' GET request that goes through the entire stack, take the response and embed the result in the true parent-request.

I've ran into a few cases like this in the past. This was PHP, but it might give a bit more context. In the PHP case I implemented a CalDAV server. In some cases you'll want to for example get some information about a specific user (identified by uri). Users are also represented as HTTP resources, so to do this, it made the most sense to just fake a HTTP request and get the user information through a local GET request. That way I could keep the 'thing' that exposes user information completely separate from the middleware that needed it.

There's also cases where I might need to see what a HTTP request would yield if it were made. For instance, I have a need to do internal HEAD requests and see what Content-Types come, and which Allow headers.

After some research I guess what I think I need to do is construct a fake 'Koa Context', maybe using a package such as node-mocks-http, but I wanted to see if the Koa authors also consider this the sanest way to do this.

Thanks for looking into this!

@jmealo
Copy link

jmealo commented Apr 25, 2018

NGINX supports this if you don't mind pushing it up the stack. (see: openresty and ledge)

@evert
Copy link
Author

evert commented Apr 25, 2018

Interesting, but yea I really don't want to have to do that =)

I think the node-mocks-http package will get me there though. I haven't had a chance to test this, but I'd also imagine that I'd need something similar for HTTP2 Push anyway.

@likegun
Copy link

likegun commented May 14, 2018

@evert Something like this?

    var Koa = require('koa');
    var Router = require('koa-router');
    
    var app = new Koa();
    var router = new Router();
    
    async function getUser(ctx, next) {...}
    router.get('/user/:id', getUser);

    router.get('/user/:id/someinformation', async () => {
        const fakeContext = //get fake context somehow
        await getUser(fakeContext);
        const user = fakeContext.body;
        //...rest code
    })
    
    app
    .use(router.routes())
    .use(router.allowedMethods());

@RWOverdijk
Copy link

Has anyone solved this? I want to translate websocket events to requests so I can reuse the same code for both websockets and API calls, but I haven;t been able to figure out how to do this besides actually calling localhost with for example fetch.

@evert
Copy link
Author

evert commented Jul 4, 2019

Node-mocks-http can do this. I ended up taking a more drastic approach and write my own koa-inspired framework fixing a few other things that were hard to do

@RWOverdijk
Copy link

@evert Thanks.

@robertkraig
Copy link

robertkraig commented Nov 27, 2019

There are usecases, but in another framework, you might check https://stackoverflow.com/questions/16520691/consuming-my-own-laravel-api, where you may have a maintenance method which does some thing, or.. you may have a cli workflow which needs to automate the creation of a few things. Instead of having to write all that same logic somewhere else considering the interconnectedness of typical codebases, you can just instantiate a new request internally and it never has to hit the network, it simply calls within the runtime of the nodejs process. I think it's mostly useful for tooling & writing utilities which do things.

@evert
Copy link
Author

evert commented Nov 27, 2019

My usecase was doing bulk requests and doing programmatic HTTP/2 push. This is what I came up with if anyone is interested:

https://github.com/curveball/core

@jonathanong jonathanong transferred this issue from koajs/koa Apr 28, 2020
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

No branches or pull requests

6 participants