Coderrob brand logo Coderrob

Hi, I'm Rob—programmer, Pluralsight author, software architect, emerging technologist, and lifelong learner.


A Quick Guide to Designing RESTful Endpoints for Your Api


Sun, 01 Sep 2024

Let’s dive into the world of RESTful API design, especially for those of you transitioning from Java or other back-end heavy environments.

One of the common mistakes I see everyday is naming API endpoints based on the actions they perform, using prefixes like /submitSomething/, /startSomething/, /getSomething/, or /updateSomething/.

While this might feel natural for function naming, it’s not the RESTful way to do things.

REST Basics: Start with the Resource

When designing a RESTful API, everything starts with the resource. If you can name it (think nouns), then it’s probably a resource.

On the flip side, anything that describes what you want to do with that resource is typically an action, like:

NOTE: CRUD is the acronym to refer to the four functions necessary to manage data.

In the world of HTTP, we have specific verbs that map directly to these actions:

The ultimate goal of RESTful design is to create an API that is intuitive, scalable, and easy to work with.

From submitQuestion to RESTful

Let’s take a practical example. Suppose you have an endpoint named submitQuestion. If you’re using a POST method here, the “submit” part is redundant because POST already implies creation or submission. So, let’s clean it up:

POST /question

This is better, but there’s still room for improvement…

In RESTful design, it’s often best to use the plural form of resources. This way, your API structure naturally supports CRUD operations (Create, Read, Update, Delete) on a collection of resources.

So, instead of:

POST /question

We should have:

POST /questions

Now we’re talking! But what about when you want to deal with a specific question? That’s where identifiers come into play.

NOTE: Moose is an acceptable exception to this rule.

Avoiding REST-In-Peace API Designs

This brings us to the problem with what we call “REST-in-peace” APIs. These are APIs that seem to follow REST principles but miss the mark by not fully embracing the concept of “resources”.

  1. Ignoring the Resource: In RESTful design, the URL should represent the resource itself, not the action. For example, an endpoint like /getQuestion focuses on the action of getting a question rather than the resource (the question).

    This goes against REST principles because the HTTP Verb should dictate the action, not the endpoint name.

  2. Redundant Actions in URLs: When you use verbs like get, create, or set in your endpoint names, you’re duplicating what the HTTP Verbs are already designed to do.

    For instance, GET /getAllQuestions is redundant because the GET method already implies that you’re retrieving something. A more RESTful approach would be GET /questions.

  3. Singular vs. Plural Resource Names: Another common mistake in REST-in-peace APIs is the inconsistent use of singular vs plural resource names.

    In RESTful design, the URL segment representing a collection of resources should be plural (e.g., /questions for multiple questions). When referring to a specific resource, you append the resource’s identifier in the path (e.g., /questions/{questionId}).

    • Correct:
      • GET /questions (to retrieve a list of questions)
      • GET /questions/{questionId} (to retrieve a specific question)
    • Incorrect:
      • GET /question (singular form used to represent a collection)
      • GET /getQuestion (verb-focused rather than resource-focused)
  4. Misuse of Named Queries in Paths: RESTful design also encourages the use of named queries in the path to represent common filters or actions.

    For example, if you want to retrieve all unanswered questions, a RESTful approach might be:

    GET /questions/unanswered
    

    This is cleaner and more intuitive than embedding the action within the endpoint name, like /getUnansweredQuestions, or /questions?type="unanswered".

    It keeps the focus on the resource (questions) and uses the path to naturally extend the query.

CRUD Operations in REST

Let’s walk through how you’d handle each of the CRUD operations with our questions resource.

The Importance of Versioning Your API

As your API evolves, it’s CRUCIAL to version your endpoints to maintain backward compatibility. At very least intentionally signals to developers breaking changes coming soon instead of breaking immediately after deploying changes.

NOTE: Not versioning is like spinning until you’re dizzy, tossing lawn darts into the air—it’s only a matter of time before one comes down on you, just like an unversioned API eventually breaks something.

NOTE NOTE: I’m the best at analogies.

There are several ways to version an API:

Regardless of the method you choose, it’s essential to follow semantic versioning principles. Semantic versioning involves incrementing the version number in a meaningful way (e.g., major changes for breaking updates, minor changes for backward-compatible enhancements, and patch changes for backward-compatible bug fixes).

Wrapping Up

To avoid falling into the trap of “REST-in-peace” API design, always remember to:

By adhering to these principles, you’ll create RESTful APIs that are not only clean and easy to use but also maintainable and scalable as your application grows.