Skip to content

Commit

Permalink
Merge pull request #999 from Geod24/rootpath-default
Browse files Browse the repository at this point in the history
Simplify @path handling
  • Loading branch information
s-ludwig committed Mar 27, 2015
2 parents d0c9db3 + 7508df2 commit b0b6a30
Show file tree
Hide file tree
Showing 3 changed files with 35 additions and 47 deletions.
1 change: 1 addition & 0 deletions examples/rest/source/app.d
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,7 @@ interface Example3API
int getMyID(int id);
}

@path("/")
interface Example3APINested
{
/* In this example it will be available under "GET /nested_module/number"
Expand Down
61 changes: 22 additions & 39 deletions source/vibe/web/common.d
Original file line number Diff line number Diff line change
Expand Up @@ -260,7 +260,7 @@ unittest


/**
UDA to defeine the ContentType for methods returning an InputStream or ubyte[]
UDA to define the ContentType for methods returning an InputStream or ubyte[]
*/
ContentTypeAttribute contentType(string data)
{
Expand Down Expand Up @@ -291,11 +291,20 @@ MethodAttribute method(HTTPMethod data)
}

/**
User Defined Attribute interface to force specific URL path n REST interface
for function in question. Path attribute is relative though, not absolute.
UDA to force a specific URL path for REST interfaces.
This attribute can be applied either to an interface itself, in which
case it defines the root path for all methods within it,
or on any function, in which case it defines the relative path
of this method.
Path are always relative, even path on interfaces, as you can
see in the example below.
See_Also: $(D rootPathFromName) for automatic name generation.
Example:
---
@path("/foo")
interface IAPI
{
@path("info2") getInfo();
Expand All @@ -305,8 +314,10 @@ MethodAttribute method(HTTPMethod data)
shared static this()
{
// Tie IAPI.getInfo to "GET /root/foo/info2"
registerRestInterface!IAPI(new URLRouter(), new API(), "/root/");
// now IAPI.getInfo is tied to "GET /root/info2"
// Or just to "GET /foo/info2"
registerRestInterface!IAPI(new URLRouter(), new API());
}
---
*/
Expand All @@ -319,51 +330,23 @@ PathAttribute path(string data)


/**
UDA to define root URL prefix for annotated REST interface.
Empty path means deducing prefix from interface type name (see also rootPathFromName)
Will be deprecated in the next release.
Use @$(D path) instead.
*/
RootPathAttribute rootPath(string path)
PathAttribute rootPath(string path)
{
if (!__ctfe)
assert(false, onlyAsUda!__FUNCTION__);
return RootPathAttribute(path);
}
///
unittest
{
import vibe.http.router;
import vibe.web.rest;

@rootPath("/oops")
interface IAPI
{
int getFoo();
}

class API : IAPI
{
int getFoo()
{
return 42;
}
}

auto router = new URLRouter();
registerRestInterface(router, new API());
auto routes= router.getAllRoutes();

assert(routes[0].pattern == "/oops/foo" && routes[0].method == HTTPMethod.GET);
return PathAttribute(path);
}


/**
Convenience alias
*/
@property RootPathAttribute rootPathFromName()
/// Convenience alias to generate a name from the interface's name.
@property PathAttribute rootPathFromName()
{
if (!__ctfe)
assert(false, onlyAsUda!__FUNCTION__);
return RootPathAttribute("");
return PathAttribute("");
}
///
unittest
Expand Down
20 changes: 12 additions & 8 deletions source/vibe/web/rest.d
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ void registerRestInterface(TImpl)(URLRouter router, TImpl instance, RestInterfac

string url_prefix = settings.baseURL.path.toString();

enum uda = findFirstUDA!(RootPathAttribute, I);
enum uda = findFirstUDA!(PathAttribute, I);
static if (uda.found) {
static if (uda.value.data == "") {
auto path = "/" ~ adjustMethodStyle(I.stringof, settings.methodStyle);
Expand Down Expand Up @@ -129,10 +129,12 @@ void registerRestInterface(TImpl)(URLRouter router, TImpl instance, RestInterfac
ParameterTypeTuple!overload.length == 0,
"Interfaces may only be returned from parameter-less functions!"
);
auto subSettings = settings.dup;
subSettings.baseURL = URL(concatURL(url_prefix, url, true));
registerRestInterface!RT(
router,
__traits(getMember, instance, method)(),
concatURL(url_prefix, url, true)
subSettings
);
} else {
// normal handler
Expand Down Expand Up @@ -180,6 +182,7 @@ void registerRestInterface(TImpl)(URLRouter router, TImpl instance, string url_p
*/
unittest
{
@path("/")
interface IMyAPI
{
// GET /api/greeting
Expand Down Expand Up @@ -287,7 +290,7 @@ class RestInterfaceClient(I) : I
}

URL url = settings.baseURL;
enum uda = findFirstUDA!(RootPathAttribute, I);
enum uda = findFirstUDA!(PathAttribute, I);
static if (uda.found) {
static if (uda.value.data == "") {
url.path = Path(concatURL(url.path.toString(), adjustMethodStyle(I.stringof, settings.methodStyle), true));
Expand Down Expand Up @@ -474,6 +477,7 @@ class RestInterfaceClient(I) : I
///
unittest
{
@path("/")
interface IMyApi
{
// GET /status
Expand Down Expand Up @@ -1251,11 +1255,11 @@ unittest {
enum FuncId = "vibe.web.rest.__unittestLXXXX_XXX.IGithubPR.getPullRequests";
enum msg = ": Path contains ':owner', but not parameter '_owner' defined.";

@rootPath("/repos/")
interface IGithubPR {
@path(":owner/:repo/pulls")
string getPullRequests(string owner, string repo);
}
@path("/repos/")
interface IGithubPR {
@path(":owner/:repo/pulls")
string getPullRequests(string owner, string repo);
}
static assert(getInterfaceValidationError!(IGithubPR)
&& msg == getInterfaceValidationError!(IGithubPR)[FuncId.length..$],
getInterfaceValidationError!(IGithubPR));
Expand Down

0 comments on commit b0b6a30

Please sign in to comment.