Sitemap

Explained Simply #19

4 min read16 hours ago

--

Resources and good URL naming

Press enter or click to view image in full size

In REST, the URL names a resource, and the method says what to do with it. When the names are right, an API becomes easy to guess. When they’re wrong, every developer has to stop and read the documentation for each endpoint.

Our running example is the travel app. It needs to list trips, book a trip, look at one user’s trips, and check the bookings for a trip. Each of those actions can be expressed clearly, or in a way that confuses everyone who uses it.

Everyday comparison: Think of a shop’s shelves. A label that says “Shoes” or “Jackets” helps you find what you need. A label that says “Find shoes now” mixes up the sign with the action. Shelves name the things, and the cashier handles the transactions. In a good API, the URL is the shelf label and the method is the transaction.

Nouns, not verbs

The most common naming mistake is putting a verb into the URL. Compare these two designs for the same features:

Verb-based: /getTrips, /createBooking?trip=42, /cancelTrip?id=42

Noun-based: GET /trips, POST /trips/42/bookings, DELETE /trips/42

In the first design, every action gets its own URL, and the method is always GET or POST. Developers must learn a new name for every feature. In the second design, the URLs name things, and the methods do the work. Learn the pattern once, and you can predict dozens of endpoints.

A closer look at collections and items

REST distinguishes between a collection and a single item. /trips is the collection of all trips. /trips/42 is one item in that collection. Keeping this pattern consistent is one of the most useful habits you can build.

Here’s how the pattern usually looks for one resource:

  • GET /trips lists trips.
  • POST /trips creates a trip.
  • GET /trips/42 reads trip 42.
  • PUT /trips/42 or PATCH /trips/42 updates it.
  • DELETE /trips/42 removes it.

A developer who learns this pattern for trips can apply it to bookings, users and hotels without reading new documentation for each one.

Naming rules that prevent problems

Use plural nouns for collections. /trips is the collection, and /trips/42 is one member. Using the plural every time keeps the pattern predictable. Mixing /trip and /trips forces people to guess.

Keep it lowercase. The URL path is case-sensitive according to the standard. /Trips and /trips may lead to different places, and people often mistype capital letters. Pick lowercase and use it everywhere.

Get ThinkTaught’s stories in your inbox

Join Medium for free to get updates from this writer.

Use hyphens to join words. /travel-guides reads more easily than /travelGuides or /travel_guides. Hyphens are the common convention in URLs, and they’re easy to read aloud.

Avoid file extensions. /trips/42.json mixes the address with a format. Use the Accept header to ask for JSON instead, so the same URL can serve different formats.

Nest only when there’s a real relationship. /users/7/trips says that these trips belong to user 7. That relationship is real, so nesting makes it clear. But don’t nest deeper than you need. Long chains become hard to read and hard to change.

Press enter or click to view image in full size

Reading nested paths like a sentence

Nested paths look daunting at first, but you can read them from left to right, like a sentence. Take /users/7/trips/42/bookings:

Press enter or click to view image in full size

It starts with the collection of users, picks user 7, then that user’s trips, then trip 42, then the bookings for that trip. Read as a sentence: “the bookings of trip 42, which belongs to user 7.”

Notice that each step narrows the target. The path always points to one kind of thing at each level, so the reader always knows what to expect next.

When a nested path becomes too long

If you find yourself writing five or six levels, the design probably needs flattening. Bookings can often live under their own collection, such as /bookings, with the trip ID stored as a field. The rule of thumb is to nest when a child can’t meaningfully exist without its parent, and to keep it flat when it can stand on its own.

Names for actions that aren’t things

Sometimes an action doesn’t map neatly to a noun. Cancelling a booking, for example. Options include treating the cancellation as a change to a status field, such as PATCH /bookings/9 with "status": "cancelled", or creating a cancellation resource, such as POST /bookings/9/cancellation. Both are reasonable. Pick one, document it, and use the same approach for similar cases.

Quick recap

  • Put the thing in the URL as a noun, and the action in the method.
  • Use plural nouns for collections, such as /trips.
  • Keep paths lowercase, use hyphens between words, and avoid file extensions.
  • Nest resources only when a real relationship exists.
  • Read a nested path from left to right, like a sentence.
  • For awkward actions, choose one pattern and apply it consistently.

One question to take with you

Good names make an API easy to use. But there’s a bigger design question underneath them. When your app sends a request, does the server remember anything about it from last time? The answer shapes how an API can grow, and it’s called statelessness.

That’s what the next episode answers: Statelessness and why it helps scale.

Follow ThinkTaught so you don’t miss it. If something here is unclear, tell me in the comments. We’re learning this together.

--

--