Vaadin URL route templates marked sometimes as cool new feature.
I've just started with Vaadin, knowing the principle of routes, but what is the main purpose for those route templates ?
kind regard
Dominik
The route templates give more flexibility for parameter position and requirements over the basic HasUrlParameter<T> that only handles parameters at the end of the route.
In particular, it allows you to use multiple parameters for the same route or to have URL structures where the parameter is not at the end, e.g products/123/edit where 123 is the parameter that identifies a product id.
For samples and information see https://vaadin.com/docs/latest/flow/routing/templates
Related
Am new to using Umbraco. I need to create Urls with an an optional parameter on the end e.g.
mysite.com/people/john
mysite.com/people/jane
etc
however by default Umbraco appears to require a separate page for each person. Is there a built method in Umbraco that will allow me to define the last part of the Url as an optional parameter or do I have to write a custom route for it?
Thanks
You have a couple of options here.
Use IIS URL Rewriting to rewrite your URLs under the hood and rewrite /people/john to /people/?person=john say. Then you can pick up the person from the query string on the page.
Write a custom URL Finder that looks for the URLs and does some stuff under the hood, like get the people page, and then set a context item with the person name in for you to use in your views etc.
You could write a custom route for it. Custom routing in Umbraco is slightly different to in normal MVC. Here is a blog post detailing how you can do it: http://shazwazza.com/post/custom-mvc-routes-within-the-umbraco-pipeline/
I'm learning how to do routing in MVC. It seems to me that the routing API only solves half the problem. I can easily see how to map incoming URLs to controller actions and params. However, it is not obvious to me how to generate these routed URLs in the source code of my pages.
For example, in one of my views, I use this code to get the route URL:
<a class="listingResult" href="#Url.RouteUrl("ListingSEO", new { id = Model.Listing.ID, seoName = ListingController.SeoName(Model.Listing.Title) })">
This seems like poor coding practice to me for several reasons:
If the route changes in the future, I may have many places in my View code that will need updating.
The View now requires knowledge of the ListingController (maybe this is not a big deal?)
I've lost strong typing on my input params, and if I misspell the param names, my code is broken, but this doesn't generate compile warnings.
How do I observe good coding standards when I am generating route URLs? The alternative seems to be putting static functions in the controller to generate routes, which would at least address concerns #1 and #3. If I worked with you and you saw the code above, how unhappy would you be?
My recommendations:
Generate URLs in the ViewModel, not the View: This will keep your views cleaner and logic free. You can pass the UrlHelper instance from the controller to the ViewModel, which will also help for my next point...
Use a strongly-typed URL generation technique: Such as delegate-based, expression-based or code generation.
One of the purposes of using named routes is to abstract the controller/action. Your named routes shouldn't really change. At the most, you'd just change the controller/action they hit, but that happens seamlessly behind the scenes because you're using named routes.
Your view requires knowledge of the controller because you've added a dependency on it. This is bad for a number of reasons. There's many different ways you could handle this that wouldn't require a dependency on the controller, depending on what it is you're actually doing here, but at the very least, you should simply use a utility class, so at least it wouldn't be controller-specific.
The route params are intentionally not strongly-typed, because routes are flexible by design. You can pass anything you want to the action, with or without a parameter to catch it (you can use something like Request to get at it without a param).
I am in the process of generating a URL dynamically in my cshtml page.
What is the difference between Url.RouteUrl() & Url.Action()?
Which one should I use to generate the URL & what difference do both have in terms of implementation ?
Thanks in advance.
RouteUrl generated the url based on route name. If you have multiple routes with similar parameters the Action method may pick a wrong one - it works based on the order of route definitions. This may take place when your routes have optional parameters.
If you want to make sure that a certain route url will be used you need to call RouteUrl passing this route name. Route names are unique and clearly identifies a route.
One more difference is that Action is MVC specific (it uses controller and action names), while RouteUrl is generic is and can be used without MVC (you can have routing in WebForms).
Url.RouteUrl allows you to specify a particular route by name. This will force the usage of that route. Url.Action will simply pick the first route that matches the criteria.
I am trying to construct a route that routes to a specific product page.
The product exists in a category. Categories may also exist in categories. I am trying to construct the URL like
my-site.com/products/category/category/category/product
The amount of categories is able to change but the last parameter will always be the name of the product.
Is there any way to construct a route for this?
A solution exactly for you
I faced the same problem in the past and solved it a bit differently to what others will advise you here. Most of solutions will talk about *catch-all parameter. In your case this means that you'd have to parse the product out yourself. Manually. Because catch-all parameter may only be the last parameter in route definition.
Catch-all anywhere in the route
If you think of it carefully, you can actually realise that catch all parameter can actually be defined anywhere in the route as long as you have all other segments present. So I've written such route class that does all that and successfully runs in production on a heavy traffic website.
My blog post has all the information about it as well as all the code that will solve your problem:
Custom Asp.net MVC route class with catch-all segment anywhere in the URL
This makes it possible for you to define your route as:
products/{*categories}/{productId}
If you think of the catch-all parameter even further you could also get to the point that a single route definition could have several catch-all parameters as long as at least one segment between them is static. But my class isn't able to do this, because your scenario with just one arbitrary segment set is much more common.
I have a Rails app that needs to expose values from a database as a web service - since I'm using Rails 2.x, I'm going with REST (or at least try). Assuming my resource is Bananas, for which I want to expose several sub-characteristics, consider this:
- /banana -> give a summary of the first 10 bananas, in full (all characteristics)
- /banana/?name=<name> -> give all characteristics for banana named <name>
- /banana/?number=<number> -> give all characteristics for banana number <number>
- /banana/?name=<name>/peel -> give peel data for banana named <name>
- /banana/?number=<number>/length -> give length data for banana number <number>
I don't want to search for ID, only name or number. And I have about 7 sub-characteristics to expose. Is this RESTful?
Thanks for any feedback!
What Wahnfrieden is talking about is something called Hypermedia as the Engine of Application State (HATEOAS) - a central constraint of REST as defined by Fielding.
In a nutshell, REST application clients never construct URIs themselves. Instead, they follow URIs provided by the application. So, URI templates such as the ones you're asking about are irrelevent at best. You can make them conform to a system if you'd like, but REST says nothing about how your URIs need to look. You could, if you wanted to, arrange it so that every resource in your system was available from http://example.com/{hash}.
Publishing URI templates, such as the ones you're talking about in your question, introduces tight coupling between your application and clients - something REST is trying to prevent.
The problem with understanding hypermedia-driven applications is that almost nobody implements or documents their "RESTful" systems this way.
It might help to think about the interaction between a human and server via a browser. The human only knows about content and links that the server provides through the browser. This is how a RESTful system should be built. If your resources aren't exposing links, they're probably not RESTful.
The advantage is that if you want to change your URI system, for example, to expose the Banana "Peel" attribute through a query parameter instead of a nested URL, you can do it anytime you'd like and no client code needs to be changed because they're not constructing links for themselves.
For an example of a system that embraces the hypertext-driven constraint in REST, check out the Sun Cloud API.
I would use these:
/banana
/banana/blah
/banana/123
/banana/blah/peel (and /banana/123/peel)
/banana/blah/length (and /banana/123/length)
First, common practice for ReSTful URIs is /object_name/id/verb, with some of those absent (but in that order). Of course, this is neither required nor expected.
If all your names aren't made of digits, you don't have to explicitly have name in /banana/name/blah. In fact, if anything, it would be better to have id as identifier: /banana/id/123/peel. Hope this helps.
Parameters should only be used for form submission.
Also, URI naming schemas is totally unrelated to REST. The point of REST is to make related resources discoverable via hypertext, not out-of-band conventions, and only from a limit number of entry points. So your /bananas/ entry point might provide the summary info for 10 bananas, but it must also provide the URI for each of those bananas' details resources, as well as the URI to get the summary for the next 10 bananas. Anything else is just RPC.
It is good practice in REST to not use query parameters because query parameters donĀ“t belong to a URL and in REST all resources should be addressable through a URL.
In your example /banana/?name=name should be /banana/name because you are referring a concrete resource.
Even I think /banana/?number=number/length is not good REST style, because you are selecting an attribute through a URL when you should retrieve the whole state with /banana/name . A difference could be /customers/1024/address to get the Customer 1024 address record.
HTH.
A more opt form for the route in url having query string is the plural form, as it is possible that multiple items are returned in the result. In this case, bananas, like bananas?color=yellow, sounds more appropriate.
On the other hand, the singular form banana, like banana/123, is good when fetching a specific resource's representation when its identifier is known and query string is not required.