How do you structure your URL routes? - asp.net-mvc

Is there a specific pattern that developers generally follow? I never really gave it much thought before in my web applications, but the ASP.NET MVC routing engine pretty much forces you to at least take it into consideration.
So far I've liked the controller/action/index structure (e.g. Products/Edit/1), but I'm struggling with more complex urls.
For instance, let's say you have a page that lists all the products a user has in their account. How would you do it? Off the top of my head I can think of the following possibilities for a listing page and an edit page:
User/{user id}/Products/List, User/{user id}/Products/Edit/{product id}
User/{user id}/Products, User/{user id}/Products/{product id}
Products?UserID={user id}, Products/Edit/{product id}
I'm sure there are plenty of others that I'm missing. Any advice?

I like RESTful, user friendly and hackable URLs.
What does this mean? Lets start with user friendly URLs. To me a user friendly URL is something easy to type and easy to remember /Default.aspx?action=show&userID=140 doesn't meet any of these requirements. A URL like `/users/troethom´ seems logical though.
This leads to the next point. A hackable URL is an URL that the user can modify and still get presented with a result. If the URL is hackable and the URL for my profile is /users/troethom it would be safe to remove my user name to get a list of users (/users).
Using RESTful URLs is pretty similar to the ideas behind my other suggestions. You are designing URLs for a user and not for a machine and therefore the URL has to relate to the content and not the the technical back-end of your site. An URL as ´/users´ makes more sense than ´/users/list´ and an URL as ´/category/programming/javascript´ (representing the subcategory 'javascript' in the category 'programming' is better than ´/category/show/12´.
It is indeed more difficult to omit IDs, but in my world it is worth the effort.
Also consult the Understanding URIs section on W3C´s Common HTTP Implementation Problems. It has a list of common pitfalls when designing URIs. Another good resource is Resourceful Vs Hackable Search URLs.

You may want to take a look at the question "Friendly url scheme?".
Particularly, Larry.Smithmier's answer provided a list of common URL schemes when using MVC in ASP.NET.

Also, you may consider using different verbs to reuse the same routes for different actions. For example, a GET request to "Products/Edit/45" would display the product editor, whereas a POST to the same url would update the product. You can use the AcceptVerb attribute to accomplish this:
[AcceptVerb("GET")]
public ActionResult Edit(int id)
{
ViewData["Product"] = _products.Get(id);
return View();
}
[AcceptVerb("POST")]
public ActionResult Edit(int id, string title, string description)
{
_products.Update(id, title, description);
TempData["Message"] = "Changes saved successfully!";
return RedirectToAction("Edit", new { id });
}

Bill de hÓra wrote a very good essay entitled Web resource mapping criteria for frameworks that is well worth a read.

To add to troethom's comments, RESTful generally also means that, for example, to create a new user you would PUT a representation to /users/newusername
RESTful basically uses the 5 standard HTTP Methods (GET, PUT, POST, DELETE, HEAD) for controlling/accessing content.
Ok, this isn't easy for a web browser, but you can always use overloaded POST (post to /users/username with a representation of a user to change some of the details, etc.
Its a good way of doing things, I'd reccommend reading RESTFul Web services to get a better understanding :D (and it's a darn good book!)

I've seen two main accepted ways to approach this topic...
One is described in the MvcContrib project documentation
and the other one is described in a blog post by Stephen Walther (which I personally prefer).

Related

URL design: is it bad practice to use consecutive numbering in URLs for user-submitted items?

I'm working on a website where users can submit items (in this case, proposals). The simplest URL design would be something like website.com/proposal/1, website.com/proposal/2, etc. (perhaps with a slug appended) but I've never seen this done in practice.
Is this URL design really as rare as I think it is and if so, why?
This URL design is not uncommon.
It is used, for example, by
stackoverflow.com (for each post):
https://stackoverflow.com/questions/1/
https://stackoverflow.com/questions/2/
https://stackoverflow.com/questions/3/
Drupal.org (for each user):
https://www.drupal.org/user/1
https://www.drupal.org/user/2
https://www.drupal.org/user/3
But there are various cases when not to use this design, for example
when all/some URLs should not be easy to guess (example: YouTube, for unlisted but sharable videos)
when URLs should not contain opaque/unneeded parts (example: Wikipedia)
when it should be private which URLs/pages were created before/after
when it should be private how many URLs/pages of this kind exist

What are the pro/cons if I expose entities keys in url?

I know with symfony2 is very trivial get pretty urls through routing system and I love it. But when the routes parameters are based only in slugs I've got to find by slug.
$em->getRepository('Bundle:Entity')->findOneBySlug($slug);
I thinking about combine both parameters like stackoverflow http://mysite.com/articles/234/the-title. Mantaining the slug parameter only for SEO proposes and find directly with the entity id (234).
$em->getRepository('Bundle:Entity')->find($id);
What are the pro / cons using this strategy. I'm right way?
I would go as you suggested and use both an unique identifier and a slug, because you do not have to worry about unique slugs this way.
But one thing you should is check if the slug is valid.
So do not use URLs like this: /articles/{id}/{unchecked-slug}, because if you do that you can reach the same article with an unlimited number of different/evil URLs, i.e. /articles/123/the-correct-title and /artcle/123/some-dirty-words.
So i would suggest using something like this:
$em->getRepository('Bundle:Entity')->findOneBy(array('slug' => $slug, 'id' => $id);
I am not a SEO expert, but I do not think, that shorter URLs are THAT important, as long as it contains useful words, that may be part of a search.
From a pure SEO perspective, you want to have a shorter URL since they tend to attract more clicks and are easier to share. However, catering to only SEO would be a mistake IMHO.
Adding a unique identifier to the string would be a smart thing to do, and would make things easier to lookup and maintain. I would suggest putting the unique identifier at the end of the URL string to maximize the "SEO effect".
Keywords in the URL might be a ranking signal, but really they drive up the CTR if the keywords found in the URL match the user's query. When that happens, the keywords in the URL become bolded in the Search Results Page (SERP). By putting the ID at the end of the URL, you're helping to ensure that the keywords in the slug have a better chance of appearing to the user, which means a better chance of being bolded, which hopefully leads to more CTR.
Here's what I would suggest:
http://example.com/articles/the-title-234
No one has suggested it so far, so I'll offer what WordPress does. If there is already a permalink in the database that is identical to the one being supplied, you simply concatenate a counter at the end.
http://example.com/blog/my-article
becomes
http://example.com/blog/my-article-2
becomes
http://example.com/blog/my-article-3
The method eywu suggested is second best, but only because you still have the full ID in the permalink. No one wants to remember that, and it has no meaning to search engines.

ColdFusion - What's the best URL naming convention to use?

I am using ColdFusion 9.
I am creating a brand new site that uses three templates. The first template is the home page, where users are prompted to select a brand or a specific model. The second template is where the user can view all of the models of the selected brand. The third template shows all of the specific information on a specific model.
A long time ago... I would make the URLs like this:
.com/Index.cfm // home page
.com/Brands.cfm?BrandID=123 // specific brand page
.com/Models.cfm?ModelID=123 // specific model page
Now, for SEO purposes and for easy reading, I might want my URLs to look like this:
.com/? // home page
.com/?Brand=Worthington
.com/?Model=Worthington&Model=TX193A
Or, I might want my URLs to look like this:
.com/? // home
.com/?Worthington // specific brand
.com/?Worthington/TX193A // specific model
My question is, are there really any SEO benefits or easy reading or security benefits to either naming convention?
Is there a best URL naming convention to use?
Is there a real benefit to having a URL like this?
http://stackoverflow.com/questions/7113295/sql-should-i-use-a-junction-table-or-not
Use URLs that make sense for your users. If you use sensible URLs which humans understand, it'll work with search engines too.
i.e. Don't do SEO, do HO. Human Optimisation. Optimise your pages for the users of your page and in doing so you'll make Google (and others) happy.
Do NOT stuff keywords into URLs unless it helps the people your site is for.
To decide what your URL should look like, you need to understand what the parts of a URL are for.
So, given this URL: http://domain.com/whatever/you/like/here?q=search_terms#page-frament.
It breaks down like this:
http
what protocol is used to deliver the page
:
divides protocol from rest of url
//domain.com
indicates what server to load
/whatever/you/like/here
Between the domain and the ? should indicate which page to load.
?
divides query string from rest of url
q=search_terms
Between the ? and the # can be used for a dynamic search query or setting.
#
divides page fragment from rest of the url
page-frament
Between the # and the end of line indicates which part of the page to focus on.
If your system setup lets you, a system like this is probably the most human friendly:
domain.com
domain.com/Worthington
domain.com/Worthington/TX193A
However, sometimes a unique ID is needed to ensure there is no ambiguity (with SO, there might be multiple questions with the same title, thus why ID is included, whilst the question is included because it's easier for humans that way).
Since all models must belong to a brand, you don't need both ID numbers though, so you can use something like this:
domain.com
domain.com/123/Worthington
domain.com/456/Worthington/TX193A
(where 123 is the brand number, and 456 is the model number)
You only need extra things (like /questions/ or /index.cfm or /brand.cfm or whatever) if you are unable to disambiguate different pages without them.
Remember: this part of the URL identifies the page - it needs to be possible to identify a single page with a single URL - to put it another way, every page should have a unique URL, and every unique URL should be a different page. (Excluding the query string and page fragment parts.)
Again, using the SO example - there are more than just questions here, there are users and tags and so on too. so they couldn't just do stackoverflow.com/7275745/question-title because it's not clearly distinct from stackoverflow.com/651924/evik-james - which they solve by inserting /questions and /users into each of those to make it obvious what each one is.
Ultimately, the best URL system to use depends on what pages your site has and who the people using your site are - you need to consider these and come up with a suitable solution. Simpler URLs are better, but too much simplicity may cause confusion.
Hopefully this all makes sense?
Here is an answer based on what I know about SEO and what we have implemented:
The first thing that get searched and considered is your domain name, and thus picking something related to your domain name is very important
URL with query string has lower priority than the one that doesn't. The reason is that query string is associated with dynamic content that could change over time. The search engine might also deprioritize those with query string fearing that it might be used for SPAM and diluting the result of SEO itself
As for using the URL such as
http://stackoverflow.com/questions/7113295/sql-should-i-use-a-junction-table-or-not
As the search engine looks at both the domain and the path, having the question in the path will help the Search Engine and elevate the question as a more relevant page when someone typing part of the question in the search engine.
I am not an SEO expert, but the company I work for has a dedicated dept to managing the SEO of our site. They much prefer the params to be in the URI, rather than in the query string, and I'm sure they prefer this for a reason (not simply to make the web team's job slightly trickier... all though there could be an element of that ;-)
That said, the bulk of what they concern themselves with is the content within and composition of the page. The domain name and URL are insignificant compared to having good, relevant content in a well defined structure.

How do you structure a restful route with several GET constraints?

Suppose you are working on an API, and you want nice URLs. For example, you want to provide the ability to query articles based on author, perhaps with sorting.
Standard:
GET http://example.com/articles.php?author=5&sort=desc
I imagine a RESTful way of doing this might be:
GET http://example.com/articles/all/author/5/sort/desc
Am I correct? Or have I got this REST thing all wrong?
I'm afraid your question really misses the point of REST. From a purely theoretical perspective there is absolutely no advantage or disadvantage to either of those urls from a REST perspective. In practice, those urls may behave differently with different caches, and certainly server frameworks are going to parse them differently. Despite what you hear from the framework developers, there is no such thing as a RESTful URL.
From the perspective of REST those two URLs are simply identifiers that can be dereferenced. If you want to start building REST apis that will benefit from the characteristics described in the dissertation, you need to start thinking in terms of content that is returned when you dereference the URL and how that content is linked together using URLs embedded in the content.
I realize this does not help you much in trying to resolve what you consider to be your problem. What I can tell you is that one of the major intents of REST is to allow your URLs to be completely under the control of the server and can change without impacting your client applications. Therefore, my recommendation is to pick whatever url structure works most easily with the framework you are using to serve the resource representations. Certainly do not look to the REST dissertation to tell you what is the right and wrong way of formatting your URLs and anyone who tells you that your URLs are not RESTful is confused. Probably what they are telling you is the server framework, they are used to using for creating RESTful interfaces, requires URLs to be structured this way.
It's not what your URI looks like that matters, it is what you do with it that matters.
Using a query string is not more or less RESTful than using path components. The URI Generic Syntax (RFC 3986, January 2005) defines that they're just as important in identifying the resource. So yes, as others point out, it's not important to REST. (Note that in the obsoleted-by-RFC-3986 RFC 2396, the query string was not defined to be identifying the resource, but rather a string of information to be interpreted by the resource.)
However, URI design is important, because as an owner of a URI namespace (i.e. the holder of the domain name where the URIs will live) you want the URIs to be long lived. As wise men have stated earlier: Cool URIs don't change!
The choice of using query strings vs path components depends on how your resources are identified, and how they will be identified in years to come. If there's a hierarchy that stands out, then it might be that this should be reflected in the URI, at least if that hierarchy is relatively permanent, and that things don't move around all the time.
It's also important to note that the actual URIs are only meaningful to two parties:
Servers, who need to forge and parse URIs
Human beings who might see a URI in passing might learn things from the URI.
By contrast, client applications are usually not allowed to do URI introspection. So your choice of query strings vs path components boils down to what you think you can live with ten (or 100) years from now.
You are mostly right. The thing with REST api's is to focus on the nouns.
What does the noun all do in this case? Wouldn't you expect your API to always return all articles, unless you filter it?
I would make sort a query string parameters, further, I would make any and all filtering query string parameters. If you look at how Stack is implemented when you click on the "Newest" questions link, you get a query string to filter the questions.
So perhaps something like:
GET http://example.com/aritcles/authors/5?sort=desc
But also think about what happens with each URL:
GET http://example.com/aritcles/ might return all current articles
GET http://example.com/aritcles/authors/ What does this url do? does it return all authors of all articles, or does it return all the articles for all authors (which is essentially the same functionality of the URL above.)
GET http://example.com/aritcles/authors/5/ might return all articles by author 5, or does it return author 5's information?
I would maybe change it to:
http://example.com/aritcles returns all articles
http://example.com/aritcles/5 returns all articles from author 5
http://example.com/authors returns all authors
http://example.com/authors/5 returns information for author 5
Alan is mostly right but his URLs are misleading. I believe the correct routes / urls should reflect the following behavior:
[GET] http://domain.com/articles #=> returns all articles (index action)
[GET] http://domain.com/articles/5 #=> returns article ID 5 (show action)
[GET] http://domain.com/authors/#=> returns all authors (index action)
[GET] http://domain.com/authors/5 #=> returns author ID 5 (show action)
[GET] http://domain.com/authors/5/articles OR http://domain.com/articles/authors/5 #=> depending on the hierarchy of your routes (both belong to the index action)
Best regards,
DBA

Is this RESTful?

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.

Resources