PITIful RESTful URLs

RDX
RDX
Aug 22, 2014 · 4 min read

If REST is done right, we end up with simplified URLs for resources. Here are some common mistakes made when designing RESTful URLs.

You should definitely check out the presentation Teach a Dog to REST (Pet Store API). It taught me a lot about simple, scalable API design. It takes around 30 endpoints and converts them into two URLs while still maintaining all functionality.

/items/year/2010/mon/05/day/01

We need to filter some items by Year, Month and Day, and decided to do it in the most RESTful way possible. Except:

RESTful URLs are not SEO URLs.

Here are problems with the above approach:

Good APIs (not just REST) provide only one way of doing a thing.

Teams end up writing a lot of code to parse all these semantics involved with Paths. But this is merely a re-invention of query parameters.

TL;DR — Don’t model query parameters as Path parameters. Query parameters allows you to change the order or number of parameters, forget about having to handle different methods, and results in a clear API specification.

/items/year:2010/month:05/day:01

The practice of using special delimiters in Path parameters. This comes with all the problems as the above, and one more: Most REST frameworks use colon as a special notation for Path parameters (e.g. /users/:id). And having a “:” in the Path creates complex and messy routing rules.

TL;DR — Don’t use special delimiters in paths. And use query parameters already.

/items/active
/items/pending
/items/drafts

Special Sub-Paths. Used to filter resources by state. At first glance they look like parameter-less scopes offering functional value, but the parameter “status” here is actually invisible but implied. This again carries same problems as the above.

If two different URLs return the same data structure, then reconsider if they are the same

TL;DR — Try to merge different paths if they return the same data structure, unless they are computationally expensive.

/articles/
/article/1

Using different plural/singular form for resources. This results in URLs like /people and /person/1 due to differing inflection rules in English grammar.

TL;DR — Stick to only one of plural or singular forms

/orgs/1234/teams
/orgs/1234/teams/1

The practice of Nesting every Relationship in the URL.

RESTful Resources can have relationships.
But every relationship doesn’t need to be nested.

The way people view and consume data is different from relationships between the data. e.g. In Reddit — Every Post must belong to a User, so it might seem like /users/1/posts could be a good idea. But end clients who consume the service aren’t going to care about the users, they only care about getting /posts.

TL;DR — Treat all resources as First-class Top-level resources, unless you are 100% sure that they will never ever become one (e.g. multi-tenant applications). After quite some time of working with REST, I can safely say this works best. At the very least, make sure that any URL has no more than one ID in the Path Parameters.

/orgs/1234/teams/56/users
/orgs/1234/teams/56/users/78

This deserves a separate specification called NESTful URLs.

/users.json

Suffixing all JSON endpoints as .json. There is a lurking namespace problem here. Most REST/MVC frameworks have namespaced Controllers with relative paths.

@Path("/items")      => everything under /items
ItemsController

@GET("/") => /items/
list() { ... }

@GET("/:id") => /items/1234
get() { ... }

The anomalous .json extension interferes with this in two ways:

@Path("/items.json") # duh
ItemsController
@GET("/:id") # oops! /items.json/1234

@Path("/items")
@GET("/.json") # oops! /items/.json

TL;DRUse HTTP Accepts header. Default extensions mess up with framework path namespacing features.

Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch

Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore

Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store