diff --git a/web/vibe/web/internal/rest/common.d b/web/vibe/web/internal/rest/common.d index 4cd7bd1096..15e5be5a9d 100644 --- a/web/vibe/web/internal/rest/common.d +++ b/web/vibe/web/internal/rest/common.d @@ -116,10 +116,7 @@ import std.traits : hasUDA; import vibe.internal.meta.uda : findFirstUDA; this.settings = settings ? settings.dup : new RestInterfaceSettings; - if (is_client) { - assert(this.settings.baseURL != URL.init, - "RESTful clients need to have a valid RestInterfaceSettings.baseURL set."); - } else if (this.settings.baseURL == URL.init) { + if (this.settings.baseURL == URL.init && !is_client) { // use a valid dummy base URL to be able to construct sub-URLs // for nested interfaces this.settings.baseURL = URL("http://localhost/"); @@ -135,9 +132,14 @@ import std.traits : hasUDA; this.basePath = concatURL(this.basePath, uda.value.data); } } - URL bu = this.settings.baseURL; - bu.pathString = this.basePath; - this.baseURL = bu.toString(); + + if (this.settings.baseURL != URL.init) + { + URL bu = this.settings.baseURL; + bu.pathString = this.basePath; + this.baseURL = bu.toString(); + } + else this.baseURL = this.basePath; computeRoutes(); computeSubInterfaces(); diff --git a/web/vibe/web/internal/rest/jsclient.d b/web/vibe/web/internal/rest/jsclient.d index c2157c24da..61659f7260 100644 --- a/web/vibe/web/internal/rest/jsclient.d +++ b/web/vibe/web/internal/rest/jsclient.d @@ -36,6 +36,11 @@ class JSRestClientSettings /*package(vibe.web.web)*/ void generateInterface(TImpl, R)(ref R output, RestInterfaceSettings settings, JSRestClientSettings jsgenset, bool parent) { + static void fmtParam(F)(ref F f, ref const PathPart p) + { + if (!p.isParameter) f.serializeToJson(p.text); + else f.formattedWrite("toRestString(%s)", p.text); + } // TODO: handle attributed parameters and filter out internal parameters that have no path placeholder assigned to them import std.format : formattedWrite; @@ -97,15 +102,21 @@ class JSRestClientSettings // url assembly fout.put("var url = "); if (route.pathHasPlaceholders) { - // extract the server part of the URL auto burl = URL(intf.baseURL); - burl.pathString = "/"; - fout.serializeToJson(burl.toString()[0 .. $-1]); + if (burl.host.length) { + // extract the server part of the URL + burl.pathString = "/"; + fout.serializeToJson(burl.toString()[0 .. $-1]); + fout.put(" + "); + } // and then assemble the full path piece-wise - foreach (p; route.fullPathParts) { + + // if route.pathHasPlaceholders no need to check route.fullPathParts.length + // because it fills in module vibe.web.internal.rest.common at 208 line only + fmtParam(fout, route.fullPathParts[0]); + foreach (p; route.fullPathParts[1..$]) { fout.put(" + "); - if (!p.isParameter) fout.serializeToJson(p.text); - else fout.formattedWrite("toRestString(%s)", p.text); + fmtParam(fout, p); } } else { fout.formattedWrite(`"%s"`, concatURL(intf.baseURL, route.pattern)); diff --git a/web/vibe/web/rest.d b/web/vibe/web/rest.d index c9bdc3254a..56a83043e0 100644 --- a/web/vibe/web/rest.d +++ b/web/vibe/web/rest.d @@ -470,7 +470,7 @@ HTTPServerRequestDelegate serveRestJSClient(I)(RestInterfaceSettings settings) if (is(I == interface)) { import std.digest.md : md5Of; - import std.digest.digest : toHexString; + import std.digest : toHexString; import std.array : appender; auto app = appender!string(); @@ -505,6 +505,12 @@ HTTPServerRequestDelegate serveRestJSClient(I)(string base_url) settings.baseURL = URL(base_url); return serveRestJSClient!I(settings); } +/// ditto +HTTPServerRequestDelegate serveRestJSClient(I)() +{ + auto settings = new RestInterfaceSettings; + return serveRestJSClient!I(settings); +} /// unittest { @@ -524,6 +530,7 @@ unittest { router.get("/myapi.js", serveRestJSClient!MyAPI(restsettings)); //router.get("/myapi.js", serveRestJSClient!MyAPI(URL("http://api.example.org/"))); //router.get("/myapi.js", serveRestJSClient!MyAPI("http://api.example.org/")); + //router.get("/myapi.js", serveRestJSClient!MyAPI()); // if want to request to self server //router.get("/", staticTemplate!"index.dt"); listenHTTP(new HTTPServerSettings, router);