RejectedSoftware Forums

Sign up

Attaching a @before/@after handler to all methods of a router

Is it possible to attach a @before or @after handler to all exposed
methods of a router interface? Better yet, even including all sub
routers?

Such a handler would need to be a template so it can fit all method
signatures.

Re: Attaching a @before/@after handler to all methods of a router

Am 25.03.2015 um 21:22 schrieb Marc Schütz:

Is it possible to attach a @before or @after handler to all exposed
methods of a router interface? Better yet, even including all sub
routers?

Such a handler would need to be a template so it can fit all method
signatures.

Not directly possible currently. The question is if this would better be
a feature supported by the interface generator, or maybe a general
transformation feature that takes a class as input an outputs a class
that has all function calls properly augmented (with attributes or
directly with code). Could be something for std.functional.

At least for certain use cases, just intercepting the HTTP request and
possibly storing some values in req.params can be a viable alternative
(or, similarly, intercepting the response in case of a
RestInterfaceClient).

Re: Attaching a @before/@after handler to all methods of a router

On Wed, 25 Mar 2015 21:54:07 +0100, Sönke Ludwig wrote:

Am 25.03.2015 um 21:22 schrieb Marc Schütz:

Is it possible to attach a @before or @after handler to all exposed
methods of a router interface? Better yet, even including all sub
routers?

Such a handler would need to be a template so it can fit all method
signatures.

Not directly possible currently. The question is if this would better be
a feature supported by the interface generator, or maybe a general
transformation feature that takes a class as input an outputs a class
that has all function calls properly augmented (with attributes or
directly with code). Could be something for std.functional.

At least for certain use cases, just intercepting the HTTP request and
possibly storing some values in req.params can be a viable alternative
(or, similarly, intercepting the response in case of a
RestInterfaceClient).

Now that 2.067 is out, I will resume my work on the new REST generator. That's definitely something that could fit in.
Do you need the attributed parameter in addition, or do you just want to do some kind of check (like isAuthenticated) ?

Re: Attaching a @before/@after handler to all methods of a router

Am 26.03.2015 um 10:05 schrieb Mathias LANG:

Now that 2.067 is out, I will resume my work on the new REST generator. That's definitely something that could fit in.
Do you need the attributed parameter in addition, or do you just want to do some kind of check (like isAuthenticated) ?

Still, the question is if it's a good idea to pack this as a feature
into the REST generator. I don't want it to become too complex and
it's already quite far in that regard.

BTW, I think this went past me, what's new in the new generator?

Re: Attaching a @before/@after handler to all methods of a router

Am Thu, 26 Mar 2015 09:05:25 GMT
schrieb "Mathias LANG" pro.mathias.lang@gmail.com:

Now that 2.067 is out, I will resume my work on the new REST
generator. That's definitely something that could fit in. Do you need
the attributed parameter in addition, or do you just want to do some
kind of check (like isAuthenticated) ?

My use cases are authentication, authorization, input verification (e.g.
UTF8 validation), and catching exceptions with hypothetical @around
filters.

These require access to input parameters and modification of the
output, or even responding without calling the actual method.

Re: Attaching a @before/@after handler to all methods of a router

On Thu, 26 Mar 2015 11:28:14 +0100, Marc Schütz wrote:

Am Thu, 26 Mar 2015 09:05:25 GMT
schrieb "Mathias LANG" pro.mathias.lang@gmail.com:

Now that 2.067 is out, I will resume my work on the new REST
generator. That's definitely something that could fit in. Do you need
the attributed parameter in addition, or do you just want to do some
kind of check (like isAuthenticated) ?

My use cases are authentication, authorization, input verification (e.g.
UTF8 validation), and catching exceptions with hypothetical @around
filters.

These require access to input parameters and modification of the
output, or even responding without calling the actual method.

I'd say that input verification should be part of the system (like it already is with vibe.web.validation). But UTF-8 validation is a good point, that should be added by default with a good error message and a BAD REQUEST reply.

Regarding exceptions, maybe a non-meta-solution like void delegate(Exception e, HTTPServerResponse res) RestInterfaceSettings.exceptionHandler is sufficient. @around should be still good to have for other use cases or very specific exception catching needs, but most of the time such a callback should be the better choice due to its lightweightness.

Hm... coming to think of it, there is a much simpler solution that requires no additions at all:

class MyRestInterface {
    @before!foo("bar"):

    void getSomething(int _bar);
    void getSomethingElse(int _bar);
}

Re: Attaching a @before/@after handler to all methods of a router

On Thu, 26 Mar 2015 10:38:51 +0100, Sönke Ludwig wrote:

Am 26.03.2015 um 10:05 schrieb Mathias LANG:

Now that 2.067 is out, I will resume my work on the new REST generator. That's definitely something that could fit in.
Do you need the attributed parameter in addition, or do you just want to do some kind of check (like isAuthenticated) ?

Still, the question is if it's a good idea to pack this as a feature
into the REST generator. I don't want it to become too complex and
it's already quite far in that regard.

BTW, I think this went past me, what's new in the new generator?

Complex in terms of code, or complex in terms of use ?

The new generator is still an experiment, and I expect a lot of discussions ;)

Here's an example on how you would use it:

import std.stdio, std.traits;

struct Context { string ip; }

interface MyAPI { void test(); }

class MyAPIImpl : RESTServer!(MyAPI, MyAPIImpl) {
override:
        void test(HTTPServerRequest ctx) {
                writeln(ctx.ip);
        }
}

// In the client
void main() {
        auto c = new RestInterfaceClient!MyAPI();
        c.test();
}

This allow to get a context (HTTPServerRequest / HTTPServerResponse) without relying on @before. It is also supposed to allow you to create more complete use case / framework on top of it, but that last part needs more though.

Note: It will only be available with 2.067, because compilers bugs.

Re: Attaching a @before/@after handler to all methods of a router

On Thu, 26 Mar 2015 14:31:58 GMT, Mathias LANG wrote:

On Thu, 26 Mar 2015 10:38:51 +0100, Sönke Ludwig wrote:

Am 26.03.2015 um 10:05 schrieb Mathias LANG:

Now that 2.067 is out, I will resume my work on the new REST generator. That's definitely something that could fit in.
Do you need the attributed parameter in addition, or do you just want to do some kind of check (like isAuthenticated) ?

Still, the question is if it's a good idea to pack this as a feature
into the REST generator. I don't want it to become too complex and
it's already quite far in that regard.

BTW, I think this went past me, what's new in the new generator?

Complex in terms of code, or complex in terms of use ?

More in terms of API complexity. Implementation complexity is rather high, too, of course, but that's another matter. But sine we have @before:, I think we can safely stop thinking about any extensions in this direction.

The new generator is still an experiment, and I expect a lot of discussions ;)

Here's an example on how you would use it:

import std.stdio, std.traits;

struct Context { string ip; }

interface MyAPI { void test(); }

class MyAPIImpl : RESTServer!(MyAPI, MyAPIImpl) {
override:
        void test(HTTPServerRequest ctx) {
                writeln(ctx.ip);
        }
}

// In the client
void main() {
        auto c = new RestInterfaceClient!MyAPI();
        c.test();
}

This allow to get a context (HTTPServerRequest / HTTPServerResponse) without relying on @before. It is also supposed to allow you to create more complete use case / framework on top of it, but that last part needs more though.

Note: It will only be available with 2.067, because compilers bugs.

To be frank, I really dislike that approach. The nice thing about the current approach where the HTTP part is almost completely hidden from the service implementation is that it can be used locally, too. With this change, you'd basically always have to use a REST connection to talk to it, even if just locally from the same process. It also makes it very easy to break the REST idiom by looking at req.session or similar (at least you have to jump through some hoops to do that now).

Re: Attaching a @before/@after handler to all methods of a router

On Thu, 26 Mar 2015 14:54:17 GMT, Sönke Ludwig wrote:

To be frank, I really dislike that approach. The nice thing about the current approach where the HTTP part is almost completely hidden from the service implementation is that it can be used locally, too. With this change, you'd basically always have to use a REST connection to talk to it, even if just locally from the same process. It also makes it very easy to break the REST idiom by looking at req.session or similar (at least you have to jump through some hoops to do that now).

I hopened https://github.com/rejectedsoftware/vibe.d/issues/1040 to discuss this in details.