Opinion on url formatting

Is it better to have a url like /users/36/groups/2 or /users/36/groups/abcdef or /users/charlie/groups/abcdef or /charlie/abcdef where the user names and the group names are unique?

Like a lot of things in programming, I don’t think one is objectively better, or better 100% of the time.

/users/[user_id]/groups/[group_id] seems fairly neutral, but that’s ok. It’s great for when the URL doesn’t need to be pretty, like an admin interface. Basecamp uses a fairly similar structure: /[account_id]/projects/[project_id]/documents/[document_id]

I prefer using /users/[user_name]/groups/[group_name] for public-facing urls.

  1. It’s more expressive, and understandable if someone is reading it, for example as a hyperlink.
  2. I’m pretty sure it’s better for SEO

tl;dr; It’s a judgement call. Do what seems best with your understanding of the project.

But should not user_name and _group_name be unique? Can we put in a non_unique name inside the urls?

You can’t use non-unique identifiers in URLs, because finding the user based on it would be problematic.

If the URL is always /user/[user]/group/[group] and never /user/[user], the user identifier would just need to be unique within that group.

The URL always has to be unique, and the easiest field to use that is unique is ID. If you ensure that another field is also unique, you can use that instead.

I’ve also heard it said the using something like /users/36/groups/2 is easier to attack since an attacker can simply try all the integers to see if something exists and is potentially accessible.

Ya exaclty @JESii. That is why I asked this question. Looking at other websites, they have some random generated urls but good looking but I dont think they ever followed the rails convention.

If you need to use non-unique identifiers, you can always have the “pretty SEO but still use the ID” format of /posts/123-some-slug – One nice benefit of doing it that way, is you can still do Post.find(params[:id]), and it’ll just work – The text part of the URL just gets thrown out.