blob: 8e0bf001446bcc17a6129b5bef3dec26e99471a7 [file] [log] [blame]
<!--
/***************************************************************************************************************************
* Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
* specific language governing permissions and limitations under the License.
***************************************************************************************************************************/
-->
@RestMethod(path)
<p>
The {@link oajr.annotation.RestMethod#path() @RestMethod(path)} annotation allows
you to define URL path patterns to match against.
These patterns can contain variables of the form <l>"{xxx}"</l> that can be passed in directly to the
Java methods as extra parameters.
</p>
<p>
In the following example, 3 separate GET request handlers are defined with different path patterns.
Note how the variables are passed in as additional arguments on the method, and how those arguments are
automatically converted to the specified class type...
</p>
<p class='bpcode w800'>
<jc>// Default method</jc>
<ja>@RestMethod</ja>(name=<jsf>GET</jsf>, path=<js>"/*"</js>)
<jk>public void</jk> doGetDefault() {
...
}
<jc>// Method with path pattern</jc>
<ja>@RestMethod</ja>(name=<jsf>GET</jsf>, path=<js>"/xxx"</js>)
<jk>public void</jk> doGetNoArgs(...) {
...
}
<jc>// Method with path pattern with arguments</jc>
<ja>@RestMethod</ja>(name=<jsf>GET</jsf>, path=<js>"/xxx/{foo}/{bar}/{baz}/{bing}"</js>)
<jk>public void</jk> doGetWithArgs(<ja>@Path</ja>(<js>"foo"</js>) String foo, <ja>@Path</ja>(<js>"bar"</js>) <jk>int</jk> bar, <ja>@Path</ja>(<js>"baz"</js>) MyEnum baz, <ja>@Path</ja>(<js>"bing"</js>) UUID bing) {
...
}
</p>
<p>
By default, path patterns are matched using a best-match heuristic.
When overlaps occur, URLs are matched from most-specific to most-general order:
</p>
<p class='bpcode w800'>
<jc>// Try first </jc>
<ja>@RestMethod</ja>(name=<jsf>GET</jsf>, path=<js>"/foo/bar"</js>)
<jk>public void</jk> method1() {
...
}
<jc>// Try second</jc>
<ja>@RestMethod</ja>(name=<jsf>GET</jsf>, path=<js>"/foo/{bar}"</js>)
<jk>public void</jk> method2(...) {
...
}
<jc>// Try third</jc>
<ja>@RestMethod</ja>(name=<jsf>GET</jsf>, path=<js>"/foo/*"</js>)
<jk>public void</jk> method3(...) {
...
}
<jc>// Try last</jc>
<ja>@RestMethod</ja>(name=<jsf>GET</jsf>, path=<js>"/*"</js>)
<jk>public void</jk> method4(...) {
...
}
</p>
<p>
The match heuristic behavior can be overridden by the
{@link oajr.annotation.RestMethod#priority() @RestMethod(priority)} annotation
property.
However, in practice this is almost never needed.
</p>
<p>
Paths that end with <js>"/*"</js> will do a prefix match on the incoming URL.
Any remainder after the match can be accessed through
{@link oajr.RequestPath#getRemainder()} or parameters with the
<c><ja>@Path</ja>(<js>"/*"</js>)</c> annotation.
On the other hand, paths that don't end with <js>"/*"</js> (e.g. <js>"/"</js> or <js>"/foo"</js>) will
require an exact URL match, and if any remainder exists, a 404 (not found) error will be thrown.
</p>
<p>
The following example shows the distinction.
</p>
<p class='bpcode w800'>
<ja>@RestMethod</ja>(name=<jsf>GET</jsf>, path=<js>"/*"</js>)
<jk>public void</jk> doGet(<ja>@Path</ja>(<js>"/*"</js>) String remainder) {
<jc>// URL path pattern can have remainder accessible through req.getRemainder().</jc>
}
<ja>@RestMethod</ja>(name=<jsf>PUT</jsf>, path=<js>"/"</js>)
<jk>public void</jk> doPut() {
<jc>// URL path pattern must match exactly and will cause a 404 error if a remainder exists.</jc>
}
</p>
<p>
Annotations are provided for easy access to URL parameters with automatic conversion to any {@doc PojoCategories parsable} type.
For example, the following example can process the URL <l>"/urlWithParams?foo=foo&amp;bar=[1,2,3]&amp;baz=067e6162-3b6f-4ae2-a171-2470b63dff00"</l>...
</p>
<p class='bpcode w800'>
<jc>// Example GET request with access to query parameters</jc>
<ja>@RestMethod</ja>(name=<jsf>GET</jsf>, path=<js>"/urlWithParams"</js>)
<jk>public</jk> String doGetWithParams(<ja>@Query</ja>(<js>"foo"</js>) String foo, <ja>@Query</ja>(<js>"bar"</js>) <jk>int</jk> bar, <ja>@Query</ja>(<js>"baz"</js>) UUID baz) <jk>throws</jk> Exception {
<jk>return</jk> <js>"GET /urlWithParams?foo="</js>+foo+<js>"&amp;bar="</js>+bar+<js>"&amp;baz="</js>+baz;
}
</p>
<ul class='seealso'>
<li class='jf'>{@link oajr.RestContext#REST_path}
<li class='ja'>{@link oaj.http.annotation.Path}
<li class='jc'>{@link oajr.RequestPath}
</ul>