Default routing mode change

classic Classic list List threaded Threaded
11 messages Options
Reply | Threaded
Open this post in threaded view
|

Default routing mode change

Arjohn Kampman
Hi all,

I'm currently switching from 1.1.x to 2.0-snapshot. Overall, the changes
between the two versions are really good. Well done!

There's one (recent) change that I was wondering about though: the
change to the default routing mode from BEST to FIRST. Why this change?

I also noted that the Router's javadoc hasn't been updated to reflect
these changes. It still mentions best match as being the default.

Regards,

Arjohn

------------------------------------------------------
http://restlet.tigris.org/ds/viewMessage.do?dsForumId=4447&dsMessageId=2414216
Reply | Threaded
Open this post in threaded view
|

RE: Default routing mode change

jlouvel
Administrator
Hi Arjohn,

Thanks for the positive feedback on Restlet 2.0!

The change on the Router was introduced to have a more predictable default
setting. Currently, only the beginning of an URI has to match in order to
follow the route (typically a ServerResource subclass). For example:

        router.attach("/abc", AbcResource.class)

was matching both "/abc" and "/abc/123" or "/abcefg"... This is useful for
attaching Directory instances or for nested routers, but this isn't the most
common case.

I have just fixed the Javadocs to clearly mention all correct default values
for Router.

Best regards,
Jerome Louvel
--
Restlet ~ Founder and Lead developer ~ http://www.restlet.org
Noelios Technologies ~ Co-founder ~ http://www.noelios.com



-----Message d'origine-----
De : Arjohn Kampman [mailto:[hidden email]]
Envoyé : mardi 3 novembre 2009 21:43
À : [hidden email]
Objet : Default routing mode change

Hi all,

I'm currently switching from 1.1.x to 2.0-snapshot. Overall, the changes
between the two versions are really good. Well done!

There's one (recent) change that I was wondering about though: the
change to the default routing mode from BEST to FIRST. Why this change?

I also noted that the Router's javadoc hasn't been updated to reflect
these changes. It still mentions best match as being the default.

Regards,

Arjohn

------------------------------------------------------
http://restlet.tigris.org/ds/viewMessage.do?dsForumId=4447&dsMessageId=24142
16

------------------------------------------------------
http://restlet.tigris.org/ds/viewMessage.do?dsForumId=4447&dsMessageId=2414337
Reply | Threaded
Open this post in threaded view
|

Re: Default routing mode change

Arjohn Kampman
Jerome Louvel wrote:

> Hi Arjohn,
>
> Thanks for the positive feedback on Restlet 2.0!
>
> The change on the Router was introduced to have a more predictable default
> setting. Currently, only the beginning of an URI has to match in order to
> follow the route (typically a ServerResource subclass). For example:
>
> router.attach("/abc", AbcResource.class)
>
> was matching both "/abc" and "/abc/123" or "/abcefg"... This is useful for
> attaching Directory instances or for nested routers, but this isn't the most
> common case.

Hi Jerome,

I think I misunderstood the meaning of Router.FIRST. I thought it meant
that the first route was used each time, but that wouldn't be a very
useful strategy for a router :-). I now understand that it means that
the first /matching/ route is chosen. Perhaps it would be a good idea to
rename this (and related) constants to Router.FIRST_MATCH to clarify
this?

This might have been discussed before: but did you consider using enums
for these kind of constants? Enums make it a bit easier to find the
possible options in an IDE with auto-code-completion. I had some trouble
finding the constants for Router.setDefaultMatchingMode(...) yesterday.

Finally: is there an easy way to create a router that will only match
complete path segments? I.e.: make "/abc" match "/abc" and "/abc/123",
but not "/abcdefg". I assume that this is one of the most used routing
option, but making it work like this is a challenge.

Arjohn

------------------------------------------------------
http://restlet.tigris.org/ds/viewMessage.do?dsForumId=4447&dsMessageId=2414417
Reply | Threaded
Open this post in threaded view
|

RE: Default routing mode change

jlouvel
Administrator
Hi Arjohn,

Good suggestion regarding the constants naming. I've just renamed routing
mode constants of Router to follow the MODE_*_MATCH pattern such as
MODE_BEST_MATCH instead of BEST. Deprecated older values.

Regarding the enums, we did consider them in several places but they prevent
addition of new constants by the framework or by the developer, especially
without breaking existing code. They also produce extra artifacts in the
Javadocs cluttering them.

For your latest question, I would recommend adding two routes: "/abc" and
"/abc/{path}". Then, it is possible to configure the "path" variable to say
it should match all URI characters including slashes via the
Variable#TYPE_URI_ALL constant, setting the Template#defaultVariable#type
property or adding an entry to Template#variables maps.

Best regards,
Jerome Louvel
--
Restlet ~ Founder and Lead developer ~ http://www.restlet.org
Noelios Technologies ~ Co-founder ~ http://www.noelios.com


-----Message d'origine-----
De : Arjohn Kampman [mailto:[hidden email]]
Envoyé : mercredi 4 novembre 2009 15:13
À : [hidden email]
Objet : Re: Default routing mode change

Jerome Louvel wrote:

> Hi Arjohn,
>
> Thanks for the positive feedback on Restlet 2.0!
>
> The change on the Router was introduced to have a more predictable default
> setting. Currently, only the beginning of an URI has to match in order to
> follow the route (typically a ServerResource subclass). For example:
>
> router.attach("/abc", AbcResource.class)
>
> was matching both "/abc" and "/abc/123" or "/abcefg"... This is useful for
> attaching Directory instances or for nested routers, but this isn't the
most
> common case.

Hi Jerome,

I think I misunderstood the meaning of Router.FIRST. I thought it meant
that the first route was used each time, but that wouldn't be a very
useful strategy for a router :-). I now understand that it means that
the first /matching/ route is chosen. Perhaps it would be a good idea to
rename this (and related) constants to Router.FIRST_MATCH to clarify
this?

This might have been discussed before: but did you consider using enums
for these kind of constants? Enums make it a bit easier to find the
possible options in an IDE with auto-code-completion. I had some trouble
finding the constants for Router.setDefaultMatchingMode(...) yesterday.

Finally: is there an easy way to create a router that will only match
complete path segments? I.e.: make "/abc" match "/abc" and "/abc/123",
but not "/abcdefg". I assume that this is one of the most used routing
option, but making it work like this is a challenge.

Arjohn

------------------------------------------------------
http://restlet.tigris.org/ds/viewMessage.do?dsForumId=4447&dsMessageId=24144
17

------------------------------------------------------
http://restlet.tigris.org/ds/viewMessage.do?dsForumId=4447&dsMessageId=2416460
Reply | Threaded
Open this post in threaded view
|

Re: Default routing mode change

Arjohn Kampman
Jerome Louvel wrote:
> Hi Arjohn,
>
> Good suggestion regarding the constants naming. I've just renamed routing
> mode constants of Router to follow the MODE_*_MATCH pattern such as
> MODE_BEST_MATCH instead of BEST. Deprecated older values.

OK, thanks.

> Regarding the enums, we did consider them in several places but they prevent
> addition of new constants by the framework or by the developer, especially
> without breaking existing code. They also produce extra artifacts in the
> Javadocs cluttering them.

Fair enough. We did a similar evaluation for our project (openrdf
sesame), where we decided to use enums where extensibility isn't an
issue and enum-like classes otherwise. The javadoc clutter isn't too
bad in our case.

> For your latest question, I would recommend adding two routes: "/abc" and
> "/abc/{path}". Then, it is possible to configure the "path" variable to say
> it should match all URI characters including slashes via the
> Variable#TYPE_URI_ALL constant, setting the Template#defaultVariable#type
> property or adding an entry to Template#variables maps.

Thanks for your help with this one.

I'm wondering if and how this mechanism can be simplified a bit by
making the template mechanism more powerful. One option could be to
encode the matching type in the variable string. I can imagine using a
notation like {digit:ssn} or {path:dirs} to respectively encode a
TYPE_DIGIT and a TYPE_URI_PATH variable.

Ant's notation where * matches a segment and ** matches a path could
also be a useful extension. In my case, I could then simply declare the
second route as "/abc/**".

Any thoughts?

Cheers,

Arjohn

------------------------------------------------------
http://restlet.tigris.org/ds/viewMessage.do?dsForumId=4447&dsMessageId=2416507
Reply | Threaded
Open this post in threaded view
|

RE: Default routing mode change

jlouvel
Administrator
Arjohn,

Thanks for the feed-back. Regarding the URI template syntax, it is tempting
to extend it, but there is already work being done to define an URI
Templates specification:
http://code.google.com/p/uri-templates/

It seems far from stable yet and focused on the client-side though. Roy T.
Fielding has been more involved lately in this topic so I expect updates
soon. It definitely requires more time and thought, I guess something for
Restlet 2.1.

Best regards,
Jerome Louvel
--
Restlet ~ Founder and Lead developer ~ http://www.restlet.org
Noelios Technologies ~ Co-founder ~ http://www.noelios.com




-----Message d'origine-----
De : Arjohn Kampman [mailto:[hidden email]]
Envoyé : mercredi 11 novembre 2009 12:33
À : [hidden email]
Objet : Re: Default routing mode change

Jerome Louvel wrote:
> Hi Arjohn,
>
> Good suggestion regarding the constants naming. I've just renamed routing
> mode constants of Router to follow the MODE_*_MATCH pattern such as
> MODE_BEST_MATCH instead of BEST. Deprecated older values.

OK, thanks.

> Regarding the enums, we did consider them in several places but they
prevent
> addition of new constants by the framework or by the developer, especially
> without breaking existing code. They also produce extra artifacts in the
> Javadocs cluttering them.

Fair enough. We did a similar evaluation for our project (openrdf
sesame), where we decided to use enums where extensibility isn't an
issue and enum-like classes otherwise. The javadoc clutter isn't too
bad in our case.

> For your latest question, I would recommend adding two routes: "/abc" and
> "/abc/{path}". Then, it is possible to configure the "path" variable to
say
> it should match all URI characters including slashes via the
> Variable#TYPE_URI_ALL constant, setting the Template#defaultVariable#type
> property or adding an entry to Template#variables maps.

Thanks for your help with this one.

I'm wondering if and how this mechanism can be simplified a bit by
making the template mechanism more powerful. One option could be to
encode the matching type in the variable string. I can imagine using a
notation like {digit:ssn} or {path:dirs} to respectively encode a
TYPE_DIGIT and a TYPE_URI_PATH variable.

Ant's notation where * matches a segment and ** matches a path could
also be a useful extension. In my case, I could then simply declare the
second route as "/abc/**".

Any thoughts?

Cheers,

Arjohn

------------------------------------------------------
http://restlet.tigris.org/ds/viewMessage.do?dsForumId=4447&dsMessageId=24165
07

------------------------------------------------------
http://restlet.tigris.org/ds/viewMessage.do?dsForumId=4447&dsMessageId=2416520
Reply | Threaded
Open this post in threaded view
|

Re: Default routing mode change

Arjohn Kampman
Jerome Louvel wrote:

> Arjohn,
>
> Thanks for the feed-back. Regarding the URI template syntax, it is tempting
> to extend it, but there is already work being done to define an URI
> Templates specification:
> http://code.google.com/p/uri-templates/
>
> It seems far from stable yet and focused on the client-side though. Roy T.
> Fielding has been more involved lately in this topic so I expect updates
> soon. It definitely requires more time and thought, I guess something for
> Restlet 2.1.

Thanks for the pointer. Unfortunately, this particular initiative seems
to become more client-oriented with each update. Perhaps this isn't the
best route to follow for the restlet framework?

I did some googling for URI template approaches and found an interesting
solution for .NET:
http://hyperthink.net/blog/uritemplate-match/
http://msdn.microsoft.com/en-us/library/system.uritemplate.aspx

This is also the only server-oriented implementation that I found. I had
expected to find more :-(

--
Arjohn

------------------------------------------------------
http://restlet.tigris.org/ds/viewMessage.do?dsForumId=4447&dsMessageId=2416602
Reply | Threaded
Open this post in threaded view
|

Re: Default routing mode change

Ben R Vesco
In reply to this post by Arjohn Kampman
>> Regarding the enums, we did consider them in several places but they prevent
>> addition of new constants by the framework or by the developer, especially
>> without breaking existing code. They also produce extra artifacts in the
>> Javadocs cluttering them.


Regarding enums and extensibility, this pattern works quite well:

interface MatchMode;

enum RouterMatchMode implements MatchMode {
    BEST,
    CUSTOM,
    FIRST,
    LAST,
    NEXT,
    RANDOM,
    ;
}

void Router::setDefaultMatchingMode(MatchMode mode);

Then a developer wanting to extend the match mode need only implement
the marker interface MatchMode on their new enum and they are
interchangable with those provided by the library. This implementation
style also makes it easier to extend the match modes because you don't
have to sit around thinking and double checking, "now should my new
mode be index 5 or is that used by one in the lib already?"

<twoCents>
    For me, robust design patterns that prevent foul play and
encourage responsible design are always preferable to saving some room
in the docs.
</twoCents>

------------------------------------------------------
http://restlet.tigris.org/ds/viewMessage.do?dsForumId=4447&dsMessageId=2416635
Reply | Threaded
Open this post in threaded view
|

Re: Default routing mode change

Tim Peierls
On Wed, Nov 11, 2009 at 11:40 AM, Ben R Vesco <[hidden email]> wrote:
>> Regarding the enums, we did consider them in several places but they prevent
>> addition of new constants by the framework or by the developer, especially
>> without breaking existing code.

Framework users wouldn't be able to add RouterMatchMode values (but see below), but framework developers most certainly could. The enum facility was designed so that changes to an enum type would not break binary compatibility. One of our key design goals in JSR 201 was to ensure that it would be possible to add values to an enum without requiring recompilation of existing clients of the enum type.

 
They also produce extra artifacts in the Javadocs cluttering them.

Compare the int constants in Router to any of the nested enums in the standard library (e.g., java.Text.Normalizer.Form), and I think it's clear that putting the values in a separate artifact is a *good* thing. It makes the enclosing type easier to read, because you don't have to wade through a lot of constants before getting to the point of the class.

Effective Java, 2nd edition, Item 30 has a passionate endorsement of enums over int constants.

 
Regarding enums and extensibility, this pattern works quite well:

interface MatchMode;

enum RouterMatchMode implements MatchMode {
   BEST,
   CUSTOM,
   FIRST,
   LAST,
   NEXT,
   RANDOM,
   ;
}

void Router::setDefaultMatchingMode(MatchMode mode);

Then a developer wanting to extend the match mode need only implement
the marker interface MatchMode on their new enum and they are
interchangable with those provided by the library. This implementation
style also makes it easier to extend the match modes because you don't
have to sit around thinking and double checking, "now should my new
mode be index 5 or is that used by one in the lib already?"

For more about this approach, see EJ2ed, Item 34: Emulate extensible enums with interfaces.

This could be a huge win for Restlet.

--tim
Reply | Threaded
Open this post in threaded view
|

RE: Default routing mode change

jlouvel
Administrator

Hi all,

 

Thanks for the valuable design feed-back. This indirectly relates to the lack of usage of interfaces in the Restlet API and the pros/cons of this design choice. I think this is important to keep those concerns in mind and reevaluate them in the next major API version (3.0). I’ve entered a new task:

 

“Reconsider usage of enumerations”

http://restlet.tigris.org/issues/show_bug.cgi?id=956

 

Best regards,
Jerome Louvel
--
Restlet ~ Founder and Lead developer ~ http://www.restlet.org
Noelios Technologies ~ Co-founder ~
http://www.noelios.com

 

 

 

 

De : [hidden email] [mailto:[hidden email]] De la part de Tim Peierls
Envoyé : jeudi 12 novembre 2009 16:18
À : [hidden email]
Objet : Re: Default routing mode change

 

On Wed, Nov 11, 2009 at 11:40 AM, Ben R Vesco <[hidden email]> wrote:

>> Regarding the enums, we did consider them in several places but they prevent
>> addition of new constants by the framework or by the developer, especially
>> without breaking existing code.

 

Framework users wouldn't be able to add RouterMatchMode values (but see below), but framework developers most certainly could. The enum facility was designed so that changes to an enum type would not break binary compatibility. One of our key design goals in JSR 201 was to ensure that it would be possible to add values to an enum without requiring recompilation of existing clients of the enum type.

 

 

They also produce extra artifacts in the Javadocs cluttering them.

 

Compare the int constants in Router to any of the nested enums in the standard library (e.g., java.Text.Normalizer.Form), and I think it's clear that putting the values in a separate artifact is a *good* thing. It makes the enclosing type easier to read, because you don't have to wade through a lot of constants before getting to the point of the class.

 

Effective Java, 2nd edition, Item 30 has a passionate endorsement of enums over int constants.

 

 

Regarding enums and extensibility, this pattern works quite well:


interface MatchMode;

enum RouterMatchMode implements MatchMode {
   BEST,
   CUSTOM,
   FIRST,
   LAST,
   NEXT,
   RANDOM,
   ;
}

void Router::setDefaultMatchingMode(MatchMode mode);

Then a developer wanting to extend the match mode need only implement
the marker interface MatchMode on their new enum and they are
interchangable with those provided by the library. This implementation
style also makes it easier to extend the match modes because you don't
have to sit around thinking and double checking, "now should my new
mode be index 5 or is that used by one in the lib already?"

 

For more about this approach, see EJ2ed, Item 34: Emulate extensible enums with interfaces.

 

This could be a huge win for Restlet.

 

--tim

Reply | Threaded
Open this post in threaded view
|

RE: Default routing mode change

Jerome Louvel-3
Hi all,

We are going to move forward with an important Restlet API refactoring for 3.0 M1 (planned for end of this month) discussed in this thread.

The goal is to introduce proper Java enumerations in order to replace the String constants used all over the framework.

This is a long-time request that we finally have the opportunity to address in the 3.x dev cycle (which allows use to significantly break backward API compatibility, providing a clear upgrade path though).

Thanks,
Jerome

------------------------------------------------------
http://restlet.tigris.org/ds/viewMessage.do?dsForumId=4447&dsMessageId=3072648