How to properly name REST methods for finding entity by Id and by name? - rest

By convention, REST methods should be nouns and should answer the question "What?" rather than "How?".
So, given that I only need to make find-by-id method, I can easily come up with the RESTful path /foo/{id}, where the part in brackets is substituted by some number.
Now, I also need to add find-by-name method, but I cannot use /foo/{name} as it's already taken.
I cannot also add 'name'-section to the path (i.e. the path would look like /foo/name/{name}), because it would mean "This method returns Foo's name".
What can be an appropriate way to compose this path?

There's nothing wrong with having both /foo/{name} and /foo/{id}. URI semantics are transparent to REST. Trying to embed behavior in URI doesn't make much sense in REST, where that behavior is supposed to come from the media type, the URI merely gives its location. /foo/name/{name} doesn't mean "this method returns Foo's name". It means whatever the source of the hyperlink giving you that URI template says it does.
The appropriate way to do what you want is having /foo returning an hyperlink title "Find Foo by name" or something like that. This hyperlink can be an URI template that when expanded with the name will retrieve a search result with the desired Foo, if it exists.
That uritemplate can be /foo/{name}, /foo?name={name}, /search?type=foo&name={name}, or even something totally unrelated like /my/api/is/a/mess?name={name}. It doesn't really matter, because all the client will do is retrieve that uritemplate, expand it, and retrieve the resource.
Obviously, you're encouraged to think carefully about your paths and make them meaningful and intuitive to client developers, but adopting one or other style doesn't make your API more or less RESTful and you can't say it's more or less appropriate. If you're thinking too much about that, it's probably because you're API is not hypertext driven, and not RESTful at all. Other implementation details, like your framework, will probably have more of a voice on the degree of appropriateness of one or the other than the REST constraints. For instance, some frameworks may have trouble with routing to both foo/{name} and /foo/{id}, but as I said above, that's not a problem at all for REST.

I guess the right way to it is smt like
/foo?name=bar
By querying in this way you will be able return several foo with same name. If for one name there are always no more than one foo perhaps name should be your id.

Related

Endpoint with two path parameters

I'm learning REST and I have a question.
Is there a scenario where the endpoint person/pathParm1/PathParam2 is legitimate?
For example:
person/ben/stiller
people /2/4
As far as I understand REST, query parameters should be used for searches:
person?firstName=ben&secondName=stiller
or
person/2/order4
REST doesn't care what spelling conventions you use for your resource identifiers.
So if you want to have a URI template with multiple variables to expand, and more than one of those variables are expanded as path segments, that's fine.
For example, you'll notice that your browser has no trouble with this resource identifier:
https://stackoverflow.com/questions/74969638/endpoint-with-two-path-parameters
which might reasonably be produced by expanding variables into a template like
https://stackoverflow.com/questions/{id}/{hint}
As far as I understand REST, query parameters should be used for searches:
That's not a REST constraint, although for the special case of the web it turned out that way. This is primarily a historical accident: we didn't have standards for URI templates when the web was young, which meant that searches came about from the standardized implementation of HTML form submissions (application/x-www-form-urlencoded key value parameters replacing the query part of the form action)
REST does say that we use resource identifiers to... identify resources; and that we all use the same general purpose resources (ie: conforming to the production rules defined in RFC 3986), but without constraints on the spelling or semantics of those identifiers.
Example: URL shorteners work.
(Note: your misunderstanding is a common one, and not at all your fault; the literature sucks. FWIW, I was once where you are; Stefan Tilkov's 2014 talk was the one that really got my own thinking straightened out.)
That said, you might find a "query parameters should be used for searches" constraint coming from somewhere else; a local style guide, for example.
this means I could also make a restful endpoint like this: api/person/{firstName}/{lastName} instead api/person?firstName=ben&lastName=stiller ?
Yes; you can use either of those spellings for your resource identifiers, and all of the general purpose components out there will still "just work" -- because they are treating the resource identifier as semantically opaque.

REST API path using route parameters without identifiers

Using expressjs term route parameters to show my problem, I also see people call that path parameters. The "proper" URL will be
Route path: /users/:userId/books/:bookId
But currently I am taking over a project that design the api like this,
/:userId/:bookId
/:groupId/:userId/some_resurce
...
The obvious problem is when I look at the url from browser I will feel confused with what those parameters mean, like the following. But the project has run for more than one year, I need to know whether it is worth the effort to rewrite it.
So is there other problem with the URL like these ?
So is there other problem with the URL like these ?
They might be making extra work for your operators when reading the access logs?
REST doesn't care about URI spelling conventions - until you get to the origin server, a URI is effectively an opaque string; only the origin server has the authority to decompose the URI into its semantic parts.
Which is to say, general purpose components don't care that there are identifiers encoded into the path, or that the semantics of those identifiers changes depending on other path elements.
In particular, they don't care at all that unrelated identifiers have common elements:
/1/2
/1/2/some_resource
As far as a general purpose component is concerned, the resources identified here have no special relationship to one another. (For example, if you DELETE /1/2, that's not expected to impact /1/2/some_resource in any way).
when I look at the url from browser I will feel confused with what those parameters mean
Yup - this is your primary argument: that the current URI design doesn't consider human affordances.
Unless you can make a case that those human focused considerations (users, operators, tech writers) offset the costs of change, you are probably stuck with it.

Need feedbck on the quality of REST URL

For getting the latest valid address (of the logged in user), how RESTful is the following URL?
GET /addresses/valid/latest
Probably
GET /addresses?valid=true&limit=1
is the best, but it should then return a list. And, I'd like to return an object rather then a list.
Any other suggestions?
Your url structure doesn't have much to do with how RESTful something is.
So lets assume which one is the 'best'. Also a bit hard to say, pretty subjective.
I would generally avoid a pattern like /addresses/valid/latest. This kinda suggest that there is a 'latest resource' in the 'valid collection', in the 'addresses collection'.
So I like your other suggestion a bit better, because it suggests that you're using an 'addresses' collection, filtering by valid items and only showing 1.
If you don't want all kinds of parameters, I would be more inclined to find a url pattern that's not literally 'addresses, but only the valid, but only the latest', but think about what the purpose is of the endpoint. Maybe something that's easier to remember like /fresh-address =)
how RESTful is the following URL?
Any identifier that satisfies the production rules described by RFC 3986 is RESTful.
General purpose components are not supposed to derive semantics from identifiers, they are opaque. Which means that the server is free to encode information into those identifiers at its own discretion.
Consider Google search: does your browser care what URI is used as the target of the search form? Does your browser care about the href provided by Google with each search result? In both cases, the browser just does what it is told, which is to say it creates an HTTP request based on the representation of application state that was provided by the server.
URI are in the same broad category as variable names in a programming language - the machines don't care so long as the spellings are consistent with some simple constraints. People care, so there are some benefits to having a locally consistent and logical scheme.
But there are contexts in which easily guessed URI are not what you want. See Mark Seemann 2013.
Since the semantic content of the URI is reserved for use by the server only, it follows that the server can choose to encode that information into path segments or the query part. Or both.
Spellings that can be described by a URI Template can be very powerful. The most familiar URI template is probably an HTML form using the GET method, which encodes key value pairs onto the query part of the URI; so you should think about whether that's a use case you want to support.

How to pass null value in RESTful way (GET filtering)? As an empty value or as 'null'?

I want to retrieve all installations that weren't removed yet.
Should I do this like that:
/installations?removedOn=
or
/installations?removedOn=null
or maybe in some other way?
/installations?removed=false
Despite the fact, that something tells me that removed=false looks better, removedOn` may be more practical because later I could query installations that are removed in particular timeframe using the same param.
REST doesn't care what spelling you use for your URI.
/installationsThatArentRemovedYet
/installations?neverRemoved
/f784d74e-b8bf-4832-9297-03816e5b4936
Any of these are fine, as far as REST is concerned.
It follows that these are also fine
/installations?removedOn=
/installations?removedOn=null
/installations?removed=false
One important thing to keep in mind is that the URI should still work even if your underlying implementation changes. So you want stable semantics, with your controller having the responsibility of mapping those semantics to your current implementation.

Is using a verb in URL fundamentally incompatible with REST?

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.
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:
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.
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.
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
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
}
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.
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).