Today my article on extending Umbraco has been published on the Umbraco Advent calendar site and on a comment Ismail asked if one could have used the umbRequestHelper.GetApiUrl
method to build the Url to the backoffice API instead of hardcoding it into the $http
request. Since it would quite a long explanation which wouldn't fit in the comment, I'm posting it here instead.
The umbRequestHelper.GetApiUrl method
This method is used to simplify the creation of Url to the backoffice web api, and it creates them based on a JavaScript dictionary Umbraco.Sys.ServerVariables[umbracoUrls]
that is created on the server, directly using the MVC routing engine to get the correct url for controllers. Once a custom controller has been registered in the umbracoUrls
dictionary, using the method is pretty easy. You just call it by specifying the apiName
(which is the key with which you register your controller in the dictionary) and the actionName
within the controller (and a query
paramter if needed). For example, if you want the url for the GetLanguages
action of the NuTranslation API you just do:
umbRequestHelper.getApiUrl("nuTranslation","GetLanguages")
Setting the key in the umbracoUrls dictionary
But for it to work you need to first set the url in the umbracoUrls
dictionary. And here comes the tricky bit.
This has to be done inside as handler for the ServerVariablesParser.Parsing
event, where you just ask to the UrlHelper
to get you the url of a given controller. Here is a simplified version of the code.
public class NuTransationApplication : ApplicationEventHandler
{
protected override void ApplicationStarted(UmbracoApplicationBase umbracoApplication, ApplicationContext applicationContext)
{
ServerVariablesParser.Parsing += ServerVariablesParser_Parsing;
}
private void ServerVariablesParser_Parsing(object sender, Dictionary<string, object> serverVars)
{
if (HttpContext.Current == null) throw new InvalidOperationException("HttpContext is null");
var urlHelper = new UrlHelper(new RequestContext(new HttpContextWrapper(HttpContext.Current), new RouteData()));
umbracoUrls["nuTranslation"] = urlHelper.GetUmbracoApiServiceBaseUrl<NuTranslationController>("Index");
}
}
To make sure it all goes well, in a production level solution you should probably add some more error checking. You can see a complete version on NuTranslation github repo.
If you now call the getApiUrl("nuTranslation","GetLanguages")
it will return /umbraco/BackOffice/Api/NuTranslation/GetLanguages
.
Now if you rename the controller you won't have to update the frontend as well, and you won't have to remember the exact route to API controllers.