Giter Site home page Giter Site logo

Route specific middleware about crow HOT 9 CLOSED

crowcpp avatar crowcpp commented on May 18, 2024
Route specific middleware

from crow.

Comments (9)

The-EDev avatar The-EDev commented on May 18, 2024

ok some news, middlewares are defined with the App, and are then tied to the connection itself through do_accept() (http_server.h - 188), the defined middlewares then get their helper called in the handle() function (http_connection.h - 318) and complete_request() (http_connection.h - 348), it could be possible to check if a middleware is defined for a route or even switch them to be per route, but that's one big task.

from crow.

The-EDev avatar The-EDev commented on May 18, 2024

Alright, so using the current middleware configuration with routes is next to impossible. But there might be some merit to a simpler idea: Have a pre-handler and a post-handler for each route. construct your middleware, and then assign its pre and post handler's to the route's own, then call them inside the router. This solution does have the problem of being a bit more messy and not letting you use get() for context, but unfortunately I'm not experienced enough to tackle anything related to the black_magic namespace..

from crow.

dranikpg avatar dranikpg commented on May 18, 2024

It should really be no that complex. Yes, black_magic instead of type_traits is a bit annoying :(

A handler is simply called in routing.h:

[f](const request&, response& res, Args... args) {
    res = response(f(args...));
    res.end();
});

Which means that we can wrap its functor with accoriding middleware:

template<typename T, typename... MDS>
auto middlewares(T f, MDS... mds) {
    return [f = std::move(f), mds = std::make_tuple(std::forward<MDS>(mds)...)] 
            (const crow::request& req) -> decltype(f()) {
        std::apply([&req](auto ...x){(x.before_handle(req), ...);}, mds);
        auto res = f();
        std::apply([&req](auto ...x){(x.after_handle(req), ...);}, mds);
        return res;
    };
}

makes the following work

CROW_ROUTE(app, "/") (middlewares(([](){
        return std::string("Hello world");
    }), RequestMiddlware{}));

Now we just have to change handler.h a bit to make the response available.

The last part are contexts. Those should shared accross different handlers. Crow has to store them somehow.

What solution comes to mind? Let's list them in the Crow<> varargs anyway, but add an optional (by inheriting some LocalMiddleware):

using call_type = std::false_type // or true_type for global;

which will tell Crow to skip them for global requests. We'll fish them out for handlers, again, using type magic.

You seem to be pretty active in other issues. What do you think of it? I'll give it a try in the nearest future.
What do you think of dropping C++11 support and going 14-17? It would help with a lot of issues in the future.

from crow.

dranikpg avatar dranikpg commented on May 18, 2024

So I've looked at the code more in detail.
We'd basically have to apply the <Middlewares...> pack to the Router and to all (Tagged)Rules.
Those Rules create their own handlers by hiding them behind a std::function. The best place to add middleware invocation is there because all type information is preserved up to this point. We don't even need a wrapper - we can just extend the operator()(Func&& f) to accept a middleware pack.

All the SFINAE stuff could be moved to a helper function. Besides that, it currently doesn't allow to accept both a request and a response which could be fixed.

The codebase will become more complex, but we'll get route based middleware without runtime overhead 😃

from crow.

The-EDev avatar The-EDev commented on May 18, 2024

@dranikpg Thanks for taking interest in this issue.

Admittedly a lot of the stuff you talked about went over my head, it like knowing a hammer exists but having no idea how to swing it. I'll still do my best to help.


What do you think of dropping C++11 support and going 14-17? It would help with a lot of issues in the future.

As helpful as this would be, I want to stay away from dropping compatibility until either other libraries (like sqlpp17) are ready, or statistics show almost nobody still using C++11. It's also worth mentioning that Crow still compiles for and uses some features of C++14 and C++17 if they are available. But only when a C++11 alternative is available.


The codebase will become more complex

As long as the user's code remains similar in terms of complexity, I don't think this would be that big of a deal.


I'd like to thank you once more for the help you're providing, and apologize for my lack of experience. I'm eager to see your work in action.

from crow.

dranikpg avatar dranikpg commented on May 18, 2024

@The-EDev Hi! I've filed a PR for this issue, would you mind checking it out 😅 I haven't tested it with MSCV as for now

from crow.

The-EDev avatar The-EDev commented on May 18, 2024

Hello @dranikpg, I've already taken a look at your PR briefly and it seems to be great in terms of code quality, concepts, execution, and even documentation. Thank you very much for the incredible work you've done!!

Unfortunately it'll take me some time to look at and test it in depth. Between an issue that took me 3 weeks of research and testing to fix, which burned me out more than I'd like to admit, and personal matters that are critical. I'm not able to work on Crow beyond leaving comments and organizing issues/PRs.

One thing I'd like to note (for the future) is that you can have multiple comments in 1 GitHub review, you don't need a new review for every comment :).

Thank you very much for your work once more, and how thoroughly you explained it, I promise to look at and merge it ASAP.

from crow.

dranikpg avatar dranikpg commented on May 18, 2024

Oh, I just flagged it to be ready for review and wanted to let you know 😓 By no means do I want you to hurry - I really appreciate you keeping the project alive. I've only noticed by the end that I've used the wrong button - I recollected it into a single review - sorry for all the emails 😬

from crow.

The-EDev avatar The-EDev commented on May 18, 2024

no worries 😁

from crow.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.