Is using a verb in URL fundamentally incompatible with REST?

Rest

Rest Problem Overview


So let's say we have something that does not seem best represented as a resource (status of process that we want to pause, stateless calculation we want to perform on the server, etc).

If in API design we use either process/123/pause or calculations/fibonacci -- is that fundamentally incompatible with REST? So far from what I read it does not seem to, as long as these URLs are discoverable using HATEOAS and media types are standardized.

Or should I prefer to put action in the message as answered here?

Note 1:
I do understand that it is possible to rephrase some of my examples in terms of nouns. However I feel that for specific cases nouns do not work as well as verbs do. So I am trying to understand if having those verbs would be immediately unRESTful. And if it is, then why the recommendation is so strict and what benefits I may miss by not following it in those cases.

Note 2:
Answer "REST does not have any constraints on that" would be a valid answer (which would mean that this approach is RESTful). Answers "it depends on who you ask" or "it is a best practice" is not really answering the question. The question assumes concept of REST exist as a well-defined common term two people can use to refer to the same set of constraints. If the assumption itself is incorrect and formal discussion of REST is meaningless, please do say so.

Rest Solutions


Solution 1 - Rest

This article has some nice tips: http://www.vinaysahni.com/best-practices-for-a-pragmatic-restful-api

Quoting from the article:

>What about actions that don't fit into the world of CRUD operations? > >This is where things can get fuzzy. There are a number of approaches: > >1. Restructure the action to appear like a field of a resource. This works if the action doesn't take parameters. For example an activate action could be mapped to a boolean activated field and updated via a PATCH to the resource. > >2. Treat it like a sub-resource with RESTful principles. For example, GitHub's API lets you star a gist with PUT /gists/:id/star and unstar with DELETE /gists/:id/star. > >3. Sometimes you really have no way to map the action to a sensible RESTful structure. For example, a multi-resource search doesn't really > make sense to be applied to a specific resource's endpoint. In this > case, /search would make the most sense even though it isn't a noun. > This is OK - just do what's right from the perspective of the API > consumer and make sure it's documented clearly to avoid confusion.

I personally like suggestion #2. If you need to pause something, what are you pausing? If it's a process with a name, then try this:

/process/{processName}/pause

Solution 2 - Rest

It's not strictly about nouns vs. verbs; it's about whether you are:

  • identifying resources
  • manipulating resources through representations

What's a resource? Fielding defines it thusly:

> The key abstraction of information in REST is a resource. Any information that can be named can be a resource: a document or image, a temporal service (e.g. "today's weather in Los Angeles"), a collection of other resources, a non-virtual object (e.g. a person), and so on. In other words, any concept that might be the target of an author's hypertext reference must fit within the definition of a resource. A resource is a conceptual mapping to a set of entities, not the entity that corresponds to the mapping at any particular point in time."

Now, to your question. You can't just look at a URL and say, "Is such-and-such a URL fundamentally incompatible with REST?" because URLs in a REST system aren't really the important bit. It's more important that the URLs process/123/pause and calculations/fibonacci identify resources by the above definition. If they do, there isn't a REST constraint violation. If they don't, you're violating the uniform interface constraint of REST. Your example leads me to believe it does not fit the resource definition and therefore would violate this constraint.

To illustrate what a resource might be in this system, you could change the status of a process by POSTing it to the paused-processes resource collection. Though that is perhaps an unusual way of working with processes, it's not fundamentally incompatible with the REST architecture style.

In the case of calculations, the calculations themselves might be the resource and that resource might look like this:

Request:
GET /calculations/5

Response:
{
  fibonacci: 5,
  prime-number: true,
  square-root: 2.23607
}

Though again, that's a somewhat unusual concept of a resource. I suppose a slightly more typical use might look like this:

Request:
GET /stored-calculations/12381728 (note that URL is a random identifier)

Response:
{
  number: 5,
  fibonacci: 5,
  prime-number: true,
  square-root: 2.23607
}

though presumably you'd want to store additional information about that resource other than a sheer calculation that anyone can do with a calculator...

Response:
{
  number: 5,
  fibonacci: 5,
  prime-number: true,
  square-root: 2.23607,
  last-accessed-date: 2013-10-28T00:00:00Z,
  number-of-retrievals-of-this-resource: 183
}

Solution 3 - Rest

It's considered bad practice to use verbs in your REST API.

There's some material on SO and elsewhere on why and how to avoid using verbs. That being said, there are plenty of "REST" APIs that use verbs.

For your process API, I would make the resource Process have a state field, which can be modified with a PUT.

Suppose GET /process/$id currently returns:

{
   state: "PAUSED"
}

Then you PUT this to /process/$id:

{
   state: "RUNNING"
}

which makes the process change state.

In the case of Fibonacci, just have a resource named fibonacci, and use POST with parameters (say n for the first n fibonacci numbers) in the body, or perhaps even GET with a query in the URL.

Solution 4 - Rest

The HTTP method is the verb: GET, PUT, POST, et cetera, while the URL should always refer to the noun (recipient of the action). Think of it like this: Would two verbs in a sentence make sense? "GET calculate" is nonsense, where "GET state" is good and "GET process" is better ("state" being metadata for a process).

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionAndrey ShchekinView Question on Stackoverflow
Solution 1 - RestccleveView Answer on Stackoverflow
Solution 2 - RestJonathan WView Answer on Stackoverflow
Solution 3 - RestBojView Answer on Stackoverflow
Solution 4 - RestsherbView Answer on Stackoverflow