Trailing slashes

401 views
Skip to first unread message

Jack Snow

unread,
Apr 7, 2013, 9:01:45 PM4/7/13
to api-...@googlegroups.com
I tend to prefer URLs that look like this: http://api.ourapp.com/some/resource
 
However, it is possible that when playing with the API in a REST client, people might enter it like this: http://api.ourapp.com/some/resource/
 
Normally, in a web app, we would just redirect http://api.ourapp.com/some/resource/ to http://api.ourapp.com/some/resource
 
However, not all API clients can understand redirects. What's the best way to deal with this? Should http://api.ourapp.com/some/resource/ always just return a 404?
 
Cheers :)

Kevin Swiber

unread,
Apr 7, 2013, 9:05:28 PM4/7/13
to api-...@googlegroups.com
On the Web API side, I usually just handle both.  Most good URL routers will do this.  Then you can accommodate everyone's preference.  I'd advise against doing HTTP tricks (redirects) and just handle it server-side with no additional round-trip.

-- 
Kevin Swiber
@kevinswiber


Mike Kelly

unread,
Apr 8, 2013, 4:52:42 AM4/8/13
to api-...@googlegroups.com

Afaik, with & without trailing slash are two distinct URLs so you're potentially creating two cache entries for every resource by doing this.

Why not just return a 404 and make this rule explicit in your API? Another thing, if your clients are following links this effectively becomes a non issue.

Cheers,
M

--
You received this message because you are subscribed to the Google Groups "API Craft" group.
To unsubscribe from this group and stop receiving emails from it, send an email to api-craft+...@googlegroups.com.
Visit this group at http://groups.google.com/group/api-craft?hl=en.
For more options, visit https://groups.google.com/groups/opt_out.
 
 

Steve Marshall

unread,
Apr 8, 2013, 6:02:15 AM4/8/13
to api-...@googlegroups.com
On 8 Apr 2013, at 02:05, Kevin Swiber <ksw...@gmail.com> wrote:

On the Web API side, I usually just handle both.  Most good URL routers will do this.  Then you can accommodate everyone's preference.  I'd advise against doing HTTP tricks (redirects) and just handle it server-side with no additional round-trip.

“Most good URL routers will do this”… usually by doing a HTTP redirect, if they’re built properly.

HTTP redirect from non-canonical to canonical is _exactly_ the right way to deal with this. HTTP 308 Permanent Redirect is your friend (or, if you want to support less smart things, HTTP 301, I suppose).

Kevin Swiber

unread,
Apr 8, 2013, 7:26:06 AM4/8/13
to api-...@googlegroups.com
Correct on the caching point. The reason why is to avoid surprises. Think of the client.

Double-correct on link following.

Sent from my iPhone

Kevin Swiber

unread,
Apr 8, 2013, 7:32:14 AM4/8/13
to api-...@googlegroups.com
Saying "the right way" when talking about HTTP is almost funny in certain cases. This isn't about being anyone's interpretation of HTTP "correct." A lot of HTTP client libraries don't auto-follow redirects, and the server is usually smart enough to figure this one out. Give clients a break. It's just a trailing slash.

Sent from my iPhone
--

Mike Kelly

unread,
Apr 8, 2013, 9:01:42 AM4/8/13
to api-...@googlegroups.com

A 404 with a text plain body that says 'try removing the trailing slash in the URL' is fairly self explanatory. Thinking of clients is important but not sure this is a big  deal for them either way so it should be ok to pick the better option for the server.

Petros Ziogas

unread,
Apr 8, 2013, 10:06:40 AM4/8/13
to api-...@googlegroups.com
I would go for client-ease. 

Having in mind that some libraries do not auto-follow redirects I would steer towards a server that can handle both. I understand that this is not much of a hustle for the client, but it is also quite ugly when a whole service breaks because it treats service.com/123 different than service.com/123/.

Who hasn't been frustrated that something didn't work because he didn't notice a 5 word sentence that says smt like "All URLs must end in /." in the speqs. 

chris...@gmail.com

unread,
Apr 8, 2013, 10:17:08 AM4/8/13
to api-...@googlegroups.com
On Mon, 8 Apr 2013, Petros Ziogas wrote:

> Having in mind that some libraries do not auto-follow redirects I would
> steer towards a server that can handle both. I understand that this is not
> much of a hustle for the client, but it is also quite ugly when a whole
> service breaks because it treats service.com/123 different than
> service.com/123/.

I don't get it. These are _clearly_ two different URIs and thus two
different resources so should not respond in the same way.

That people like to think of the slash as a "meaningless" separator
is bunk. It's simply a character in a string.

--
Chris Dent http://burningchrome.com/
[...]

Kevin Swiber

unread,
Apr 8, 2013, 10:41:50 AM4/8/13
to api-...@googlegroups.com

On Apr 8, 2013, at 10:17 AM, chris...@gmail.com wrote:

> On Mon, 8 Apr 2013, Petros Ziogas wrote:
>
>> Having in mind that some libraries do not auto-follow redirects I would
>> steer towards a server that can handle both. I understand that this is not
>> much of a hustle for the client, but it is also quite ugly when a whole
>> service breaks because it treats service.com/123 different than
>> service.com/123/.
>
> I don't get it. These are _clearly_ two different URIs and thus two
> different resources so should not respond in the same way.

Except when they're not _actually_ two different resources. It's an API server implementation detail. The OP says it's a matter of preference, not logical structure. A URI alias is not new technology. We've been rewriting URIs on the server since the dawn of Internets. Not sure what all the hubbub is about.

> That people like to think of the slash as a "meaningless" separator
> is bunk. It's simply a character in a string.

I don't think anyone's claiming that a slash is meaningless. The argument is for user experience, not technical accuracy. But this isn't a very big argument, either way. It's an easy test.

1) Do you expose no semantic difference between a URI that ends with a slash and one that doesn't?
2) Are you expecting consumers to create their own client library?

If you answered yes to both these questions, then you _may_ want to consider the user experience argument. That's it. :)

mca

unread,
Apr 8, 2013, 11:21:45 AM4/8/13
to api-...@googlegroups.com
my "top ten list" on this topic:

10) same resource can have multiple identifiers - no biggie there.

9) i usually send _redirects_ to clients that pass me the "wrong" canonical identifier, that helps keep caches clean

8) responses w/ well-designed error representations can go a long way toward easing client-dev pains in this space.

7) relying on in-line hypermedia over code-based URL construction cuts out much of this problem

6) libs/frameworks that fail to follow 3xx responses should be considered harmful, IMO

5) continuing to sidestep this issue by accommodating broken libs/frameworks is not a good long-term strategy

4) in coordinated environments (internal client dev) this is an easy problem to fix - use good libs

3) in un-coordinated environments (unknown third parties using broken libs), you can increase success/reduce pain by including in your API docs a list of recommend libs/frameworks (thereby promoting "good libs")

2) if you're dead serious about all this, make contributions to broken libs/frameworks to help us all out.

1) i'd really like to get a list of these lib/frameworks that don't handle 3xx properly. maybe they can be posted on a page here:https://code.google.com/p/implementing-rest/

Cheers.


André Tavares

unread,
Apr 8, 2013, 11:33:53 AM4/8/13
to api-...@googlegroups.com
Initially, I followed the "redirect" approach. But it made debugging using the Chrome Inspector difficult because, in some cases, the 301 meant I couldn't see the response body. Plus, I thought that it makes more "API sense" to have strict URL->handler mapping and that the slash meant that "something" had to come after it.

This way, an URL could not finish with a slash and, if one was appended, it would go nowhere.

But I also believe that APIs should be as frictionless as possible and, thus, this trailing slash does indeed lead to unnecessary quirks. So, currently, I map the "two" URLs to the same handler via regex. So far, it has worked fine for be both technically and philosophically :)

Kevin Swiber

unread,
Apr 8, 2013, 11:56:17 AM4/8/13
to api-...@googlegroups.com
I think having a list of HTTP client libs and their capabilities is an awesome idea.

Here's a quick "safe" list:
  • Java - java.net.HttpURLConnection
  • .NET - System.Net.HttpWebRequest
  • Python - urllib2.Request
  • Ruby - OpenURI
  • Node.js - request

And here's a quick "unsafe" list:
  • .NET - System.Net.HttpRequest
  • Ruby - Net::HttpRequest
  • Node.js - http.HttpClient
I'm sure there's a ton more.  These are mostly libraries built into platforms.

While the list is cool, having a quick "recommended libraries" section would be solid.

-- 
Kevin Swiber
@kevinswiber

mca

unread,
Apr 8, 2013, 11:58:42 AM4/8/13
to api-...@googlegroups.com
Kevin, do you have contributor access to the implementing-rest wiki? anyone else on this list a contributor and willing to start this as a new wiki page there?

Moore, Jonathan (CIM)

unread,
Apr 8, 2013, 12:00:38 PM4/8/13
to api-...@googlegroups.com
I'll add Apache HttpComponents to the Java list. You can configure whether the client follows redirects or not. In addition, it has a fully-compliant HTTP/1.1 client-side cache module with multiple storage backends. [Disclosure: my team and I contributed the caching module.]


Jon
........
Jon Moore
Comcast Cable



Mickey Killianey

unread,
Apr 10, 2013, 3:34:01 PM4/10/13
to api-...@googlegroups.com
Is there any issue with conflicting nearby resources?  It seems to me that if you have resource A at the URI path:

    /some/path

and you permit clients to use

    /some/path/

as a synonym for it, then if you ever choose to introduce resource B at a path:
 
    /some/path/{arg}

Then you've created the complexity of having to document whether resource A or resource B should respond to empty/zero-length values of {arg}.

Q:  Or is it such a patently horrible idea to have zero-length arguments in a URI that this is a non-issue?

mk

todd

unread,
Apr 13, 2013, 6:04:59 PM4/13/13
to api-...@googlegroups.com
Sorry a bit slow in response to discussion and it has moved in but ...

> service breaks because it treats service.com/123 different than
> service.com/123/.

I don't get it. These are _clearly_ two different URIs and thus two
different resources so should not respond in the same way.

Added to that, I don't get why people are constructing the URL in the first place. Should we be following the link relations? 
 

That people like to think of the slash as a "meaningless" separator
is bunk. It's simply a character in a string.

IMHO that character also gives use the ability to use the collections design through URLs. I use the convention that a trailing slash is a collection and without is an item. 

Ruben Verborgh

unread,
Apr 15, 2013, 6:30:58 AM4/15/13
to api-...@googlegroups.com
On 08 Apr 2013, at 16:17, chris...@gmail.com wrote:

> I don't get it. These are _clearly_ two different URIs and thus two
> different resources so should not respond in the same way.

Note, however, that normalization is mentioned in the URI spec:

Substantial effort to reduce the incidence of false negatives is
often cost-effective for web spiders. Therefore, they implement even
more aggressive techniques in URI comparison. For example, if they
observe that a URI such as

http://example.com/data

redirects to a URI differing only in the trailing slash

http://example.com/data/

they will likely regard the two as equivalent in the future.

Source: http://tools.ietf.org/html/rfc3986#section-6.2.4

Best,

Ruben
Reply all
Reply to author
Forward
0 new messages