Need feedbck on the quality of REST URL - rest

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.

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.

Design RESTFul GET with URL as resource

What would be the best approach to implement a GET REST API in order to check if a given URL existed in the database.
Each GET request will have the following parts : hostname, port, origin, path, and query.
My idea is to setup the resource as follows.
/urlservice/1/{hostname}/{port}/{origin}/{path}/{query}
But this seems very verbose since it will results in resource urls like:
/urlservice/1/google.com/80/"https://google.com/"/"/search"/"?q=aba"
What is a better way of designing this?
The main caveat with REST when designing your URI structure is that you follow the URI spec. That being said, looking at the URI spec in regards to the structure it has a couple important notes to help with your question:
1.2.3. Hierarchical Identifiers
The URI syntax is organized hierarchically, with components listed in
order of decreasing significance from left to right. For some URI
schemes, the visible hierarchy is limited to the scheme itself:
everything after the scheme component delimiter (":") is considered
opaque to URI processing. Other URI schemes make the hierarchy
explicit and visible to generic parsing algorithms.
The generic syntax uses the slash ("/"), question mark ("?"), and
number sign ("#") characters to delimit components that are
significant to the generic parser's hierarchical interpretation of an
identifier...
Now in regards to the query string:
3.4. Query
The query component contains non-hierarchical data that, along with
data in the path component (Section 3.3), serves to identify a
resource within the scope of the URI's scheme and naming authority
(if any). The query component is indicated by the first question
mark ("?") character and terminated by a number sign ("#") character
or by the end of the URI...
With the above, looking at your URI you need to determine whether your structure is hierarchical or not to follow the URI spec to satisfy REST. Of course, there is a bit of subjectivity here but looking at what you have, most (if not all) of the parameters you called out look like candidates for use in a query string is as it is non-hierarchical. To that end, I'd recommend moving them to the query string.
/urlservice/1?hostname={hostname}&port={port}&origin={origin}&path={path}&query={query}
Again, as there is some subjectivity and you know your domain better than others, use the above guidance and make your best judgement call.
You could decompose it to be service based rather than specifying everything in the request:
/urlservice/1/{service}/{request}
The services would be 'service based' so a google search service would know how to build a google search url:
/urlservice/1/google/aba
would be resolved to:
https://google.com/search/?q=aba
by the google service. It also means all clients wouldn't have to change if google changed their service parameters. Only the google service would change its internal implementation of the url builder.

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

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.

Are there any naming convention guidelines for REST APIs? [closed]

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 4 years ago.
Improve this question
When creating REST APIs, are there any guidelines or defacto standards for naming conventions within the API (eg: URL endpoint path components, querystring parameters)? Are camel caps the norm, or underscores? others?
For example:
api.service.com/helloWorld/userId/x
or
api.service.com/hello_world/user_id/x
Note: This is not a question of RESTful API design, rather the naming convention guidelines to use for the eventual path components and/or query string parameters used.
Any guidelines would be appreciated.
I think you should avoid camel caps. The norm is to use lower case letters. I would also avoid underscores and use dashes instead
So your URL should look like this (ignoring the design issues as you requested :-))
api.service.com/hello-world/user-id/x
The REST API for Dropbox, Twitter, Google Web Services and Facebook all uses underscores.
Look closely at URI's for ordinary web resources. Those are your template. Think of directory trees; use simple Linux-like file and directory names.
HelloWorld isn't a really good class of resources. It doesn't appear to be a "thing". It might be, but it isn't very noun-like. A greeting is a thing.
user-id might be a noun that you're fetching. It's doubtful, however, that the result of your request is only a user_id. It's much more likely that the result of the request is a User. Therefore, user is the noun you're fetching
www.example.com/greeting/user/x/
Makes sense to me. Focus on making your REST request a kind of noun phrase -- a path through a hierarchy (or taxonomy, or directory). Use the simplest nouns possible, avoiding noun phrases if possible.
Generally, compound noun phrases usually mean another step in your hierarchy. So you don't have /hello-world/user/ and /hello-universe/user/. You have /hello/world/user/ and hello/universe/user/. Or possibly /world/hello/user/ and /universe/hello/user/.
The point is to provide a navigation path among resources.
'UserId' is wholly the wrong approach. The Verb (HTTP Methods) and Noun approach is what Roy Fielding meant for The REST architecture. The Nouns are either:
A Collection of things
A thing
One good naming convention is:
[POST or Create](To the *collection*)
sub.domain.tld/class_name.{media_type}
[GET or Read](of *one* thing)
sub.domain.tld/class_name/id_value.{media_type}
[PUT or Update](of *one* thing)
sub.domain.tld/class_name/id_value.{media_type}
[DELETE](of *one* thing)
sub.domain.tld/class_name/id_value.{media_type}
[GET or Search](of a *collection*, FRIENDLY URL)
sub.domain.tld/class_name.{media_type}/{var}/{value}/{more-var-value-pairs}
[GET or Search](of a *collection*, Normal URL)
sub.domain.tld/class_name.{media_type}?var=value&more-var-value-pairs
Where {media_type} is one of: json, xml, rss, pdf, png, even html.
It is possible to distinguish the collection by adding an 's' at the end, like:
'users.json' *collection of things*
'user/id_value.json' *single thing*
But this means you have to keep track of where you have put the 's' and where you haven't. Plus half the planet (Asians for starters)
speaks languages without explicit plurals so the URL is less friendly to them.
No. REST has nothing to do with URI naming conventions. If you include these conventions as part of your API, out-of-band, instead of only via hypertext, then your API is not RESTful.
For more information, see http://roy.gbiv.com/untangled/2008/rest-apis-must-be-hypertext-driven
Domain names are not case sensitive but the rest of the URI certainly can be. It's a big mistake to assume URIs are not case sensitive.
I have a list of guidelines at http://soaprobe.blogspot.co.uk/2012/10/soa-rest-service-naming-guideline.html which we have used in prod. Guidelines are always debatable... I think consistency is sometimes more important than getting things perfect (if there is such a thing).
If you authenticate your clients with Oauth2 I think you will need underscore for at least two of your parameter names:
client_id
client_secret
I have used camelCase in my (not yet published) REST API. While writing the API documentation I have been thinking of changing everything to snake_case so I don't have to explain why the Oauth params are snake_case while other params are not.
See: https://www.rfc-editor.org/rfc/rfc6749
I don't think the camel case is the issue in that example, but I imagine a more RESTful naming convention for the above example would be:
api.service.com/helloWorld/userId/x
rather then making userId a query parameter (which is perfectly legal) my example denotes that resource in, IMO, a more RESTful way.
I would say that it's preferable to use as few special characters as possible in REST URLs. One of the benefits of REST is that it makes the "interface" for a service easy to read. Camel case or Pascal case is probably good for the resource names (Users or users). I don't think there are really any hard standards around REST.
Also, I think Gandalf is right, it's usually cleaner in REST to not use query string parameters, but instead create paths that define which resources you want to deal with.
http://api.example.com/HelloWorld/Users/12345/Order/3/etc