REST urls
Madvoc supports REST-alike URLs. Parts of mapped action path may contain macros - text chunk surrounded with ${ and } signs. Macros are used to resolve values from request action path. Values are injected in the action object, similarly as request parameters and attributes gets injected.
Examples
Here is a simple action class
@MadvocAction public class RestAction { Long id; @Action("/user/${id}") public void viewUser() { } }
It's quite obvious: above action method is registered to set of action
paths that starts with /user/
. For example, if request action path
is /user/173
Madvoc will match it to above action method. Second
part of the request will be recognized as macros value. This value will
be injected into the action object using the macro name, id
.
@MadvocAction public class RestAction { Long id; @Action("/user-${id}.jpg") public void viewUserImage() { } }
In this example, Madvoc will match whole set of request action paths:
/user-*.jpg
to this action method. For example, request:
/user-173.jpg
would be served by this method.
In all above examples, @Action
defines absolute action path. This is
not required, i.e. action path with macros is built as usual,
considering package, class and method annotations. However, only
@Action
annotation may contain macros.
Multiple macros
One action path may contain multiple macros - usually separated by at least one character in between.
Matching
Madvoc supports macros matching, too. By defining regular expression or wildcard pattern (default), you can narrow down request paths that invoke some action.
Matching is usually important for the root actions. For example, macro
/${city}
will practically match all requests to one action (except
explicitly defined using e.g. annotations). This means, for example,
that even paths like /favico.ico
or /robots.txt
or even all /*.png
will be mapped to the same action - which is probably something you
didn't want. Therefore we have to filter out requests that we don't
need.
Wildcard matching
By default, paths are matched using wildcards. It's simple and fast.
RegExp matching
For advanced use cases, user may turn on regular expression.
In above examples there are no checking if the macro value is a number -
so, even invalid action paths (e.g. /user/huh
) will be invoked by
mapped action methods.
Madvoc provides regular expression matching of the macro values. RegExp pattern can be defined after the macro name, as in the following example:
@MadvocAction public class RestAction { Long id; @Action("/user/${id:^[0-9]+}") public void viewUser() { } }
This action method is mapped on all request action paths that starts
with /user/
and have a number appended as a macro value. Invalid urls
will be simply ignored and error 404 will be raised.
Here is another result how to filter out all paths that does not contain just letters:
@MadvocAction public class RestAction { String city @Action("/${city:^[a-z]+}") public void city() { } }
Since in root, this macro will successfully filter out requests like
/favico.ico
or all images, and this action will be invoked only for
cities.
Custom matching
Of course, it is possible to create custom path macro definition - one that may be more complex then regular expression, or more specific to your needs. See the code for how :)
Result path
Result path is build from the action path. When action path contains RegExp pattern, resulting path may not be a valid file name (for dispatching to, for example). For such situation we can use replacements in the result, as in following example:
@Action("/user/${id:^[0-9]+}") public String viewUser() { return "#${:method}.ok"; }
Let's analyze the result value. First character is #
, that means
'go back', i.e. strip action method part from the end. Then we are
adding a replacement ${:method}
, that will be replaced with the real
method name. So, the result path of the above action method is:
/user/viewUser.ok
.
REST annotation naming convention
But there are even more REST in Madvoc: REST naming convention. It is just a different convention how action paths are built. Here is an example:
@MadvocAction public class UserAction { @InOut String id; @RestAction("${id}") public void get() {} @RestAction("${id}") public String post() { return "#post"; // don't have to do this } }
With REST naming convention active (by @RestAction
) the method get()
is
going to be mapped to url: /user/${id}
, but only for GET requests.
POST requests get mapped to method post()
and so on. In this approach
one action represents one REST resource.
Resulting paths are going to be: /user/get.jsp
and /user/post.jsp
.
This is common approach for REST apis. Still, you are able to build your own naming convention if you like.
Use REST with JSON Action Result
Madvoc does not provide out-of-box Action result handler that produces the JSON from the result. This is because there are so many ways how object can be serialized, how the response should look etc. We leave all this to you :) But at least you have good tools to make it easy.
When building JSON api with Madvoc you probably should create your own
JSON ActionResult
that will handle action results and convert them into
JSON. So your action may look like:
@MadvocAction public class BookAction { @MyRestAction("${id}") public Book get(@In int bookId) { ... } }
Here we used custom annotation MyRestAction
that defines your own
action result handler for rendering returned values as JSON.
Awesome!