What is the best way for my rest api uri name to include module name that the ressource belongs to? - rest

I'm wondering what is the best way for my rest api uri name to include the module name that the ressource belongs to? lets clarify this, my rest api should expose the details of Object-A and should also expose the details of Object-B, in this case i can't use the ressource name ipAdresse:port/details because there is two details types.
add to this that i should not use the nesting style like this ipAdresse:port/objectA/:id/details.
So in this case, is it better to do it the following way (include the parent ressource or module name in the url):
ipAdresse:port/objecta/details
or this way (using hyphen):
ipAdresse:port/objectb-details
thanks

There's a small advantage to using path segments, if you have a family of these documents that want to link to each other
/objecta/details
/objecta/comments
/objecta/pricing
These resources can all reference each other using dot segments (ex: ../comments), which means that you don't have to specify the "objecta" part in the links. In other words, you could move the whole family of identifiers to a different location in your hierarchy, and relative resolution would just work.
/objectb-details
/objectb-comments
/objectb-pricing
Each of these paths is a single segment, so dot segments remove the entire path, which you would have to replace (ex: ../objectb-comment), and if you decide to replace the objectb prefix with something else, you also need to update all of the links.
In effect, using / gives you a little bit of future proofing.
That said, if the hyphen-minus is part of the name of the thing, then leave it in the identifier.
/objective-c/comments
If you bring one of these to me in a code review, I'm going to think you've lost the plot:
/objective/c/comments
/objective-c-comments
But of course they will work just as well (the machines don't care) as long as the identifiers match the syntax described by RFC 3986.

Related

What is the best practice to design the rest api url if one resource identifier is a path

It is straightforward to put resource id into url if it is a int or long type. e.g.
GET files/123
But my problem is that my resource identifier is a path. e.g. /folder_1/folder_2/a.sh because the underlying implementation is a filesystem. So I can not put it as part of rest api url because it is conflict with url path.
Here's approaches what I can think of:
Put the path id as the request param. e.g.
GET files?path=/folder_1/folder_2/a.sh
Encode/decode the path to make it qualifier as part of url.
Introduce another int/long id for this resource in backend. And map it to the path. The int/long type resource id is stored in database. And I need to maintain the mapping for each CURD operation.
I am not sure whether approach 1 is restful, approach 2 needs extra encoding/decoding, and approach 3 needs extra work to maintain the mapping.
I wonder what is the best practice to design the rest api url for this kind of case.
Simple:
#GET
#Path("/files/{path:.+}")
#Produces({MediaType.TEXT_PLAIN})
public String files(
#PathParam("path") String path
) {
return path;
}
When you query files/test1/tes2 via url output is:
test1/tes2
Just put the path after a prefix, for example:
GET /files/folder_1/folder_2/a.sh
There isn't a conflict, since when the request path starts with your known prefix (/files/, in the above example), you know that the rest should be parsed as the path to the file, including any slashes.
Well, my experience designing "restful" APIs shows that you have to take into consideration future extensions of your API.
So, the guidelines work best when followed closely when it makes sense.
In your specific example, the path of the file is more of an attribute of the file, that can also serve as its unique ID.
From your API client's perspective, /files/123 would make perfect sense, but /files/dir1/file2.txt is debatable.
A query parameter here would probably help more, much like what you would do if you wanted to retrieve a filtered list of files, rather than the whole collection.
On the other hand, using a query parameter would also help for future extensions, since supporting /files/{path} would also mean conflicts when attempting to add sub-resources to your files endpoint.
For example, let's assume that you might need in the future another endpoint /files/attributes. But, having such an endpoint, would exclude any possibility for your clients to match a file named attributes.

How to create right API URLs for getting data

I'm creating a simple API which works with geographical data.
Some URLs look very simple like:
GET /towns/{id}
or
GET /towns
Now I want to get a town by alias, should I use this kind of URL?
GET /towns/alias/{alias}
What if I also want to get a list of towns located near certain town?
GET /towns/closest/{id}/radius/{radius}
I understand that my URLs can be any I want. What is a canonical way to do it?
I understand that my URLs can be any I want. What is a canonical way to do it?
There isn't really a "canonical way" to design URLs, any more than there is a canonical way to name variables -- there are only local spelling conventions.
RFC 3986 distinguishes between hierarchical and non-hierarchical data:
The path component contains data, usually organized in hierarchical form, that, along with data in the non-hierarchical query component (Section 3.4), serves to identify a resource within the scope of the URI's scheme and naming authority (if any)
The effect of using hierarchical data is that you can take advantage of dot-segments to compute one URI from another.
For example
/town/alias/{alias}
/alias/{alias}
Both of these spellings are "fine", but /town/alias gives us the option of using dot segments to specify an identifier under /town
/town/alias/abc + ../123
=> /town/alias/../123
=> /town/123
That can be handy when it allows you to re-use a representation for multiple resources in your hierarchy.
Yes it can possible through the URL routing.You can send any number of parameter through url.
Can you please confirm the technology you used?

REST url for nested resources

Which is a proper way of creating REST path ?
Say i have REST resource like,
base_url/api/projects/{projId}/sprints/{sprintId}/.....etc
I have more than 5 path params like this in a resource url. Is it proper to have so many path params or we have to cut it to different resources like,
base_url/api/projects/{projId}
base_url/api/sprints/{sprintId}
...etc
The condition here is , a sprint cannot exist without a project and so on. If we need to cut the resources to different paths, are there any standards on which conditions we can cut them?
REST doesn't care about the URI design. That's a misconception.
The readability of a URI is desirable but not mandatory in the REST architectural style.
As defined in the RFC 3986, the URI syntax is organized hierarchically, with components listed in order of decreasing significance from left to right separated by /. If a sprint cannot exist without a project, you can use the following to express such hierarchy:
/api/projects/{project-id}/sprints/{sprint-id}
However, if the URI gets too long and you have many parameters to pass around, there's not issues in splitting it:
/api/projects/{project-id}
/api/sprints/{sprint-id}

The correct way to access sub resources in REST service

Let's imagine we have a resource As that contains Bs which in it's turn contains Cs.
To get all the Cs I'd usually create controller method with URL like As/Bs/Cs. And to get a particular B I would do As/Bs/{bId}. But is this correct ?
How someone else would understand that this "Cs" part in the first URL is the name of the sub resource, not the {bId} ? Specially if B has a string id.
Shouldn't it be something like a wildcard symbol, that would make the first query look like As/*/Bs/*/Cs, So you would immediately see what is id and what is the sub resource ?
Short answer
When a URL matches multiple patterns, a sort is used to find the most specific match. How is it determined? A pattern with a lower count of URI variables and wild cards is considered more specific.
So /servers/deployments/executions is more specific than /servers/deployments/{deploymentId}.
A bit longer answer
The Spring MVC documentation tells you the whole story:
Path Pattern Comparison
When a URL matches multiple patterns, a sort is used to find the most specific match.
A pattern with a lower count of URI variables and wild cards is considered more specific. For example /hotels/{hotel}/* has 1 URI variable and 1 wild card and is considered more specific than /hotels/{hotel}/** which as 1 URI variable and 2 wild cards.
If two patterns have the same count, the one that is longer is considered more specific. For example /foo/bar* is longer and considered more specific than /foo/*.
When two patterns have the same count and length, the pattern with fewer wild cards is considered more specific. For example /hotels/{hotel} is more specific than /hotels/*.
There are also some additional special rules:
The default mapping pattern /** is less specific than any other pattern. For example /api/{a}/{b}/{c} is more specific.
A prefix pattern such as /public/** is less specific than any other pattern that doesn’t contain double wildcards. For example /public/path3/{a}/{b}/{c} is more specific.

Proper way to construct this REST URI?

I want to have a REST resource for Foo and I want to be able to perform a POST to create a new Foo.
Foos can only be of two subtypes - Fizz and Buzz (the models are FooFizz and FooBuzz on the backend and both extend Foo). All Foos are either a Fizz or a Buzz. Most of the other models follow this pattern too (generic with subtypes for Fizz and Buzz). For the short and medium term, there will not be a new type added to Foos. In the long term it's more likely that this application will be obsolete before a new type is added, but the possibility exists.
At any rate, here are some URI schemes I came up with for working with Foos.
POST /foo?type=fizz
POST /foo/fizz
POST /fizz/foo
POST /foo-fizz
POST /foo/{foo-id}/fizz
My thoughts on this:
(1) might be unnecessary client-server coupling since it's dependent on the query string being properly formed. But it makes the most sense to me.
(2) and (3) are undesirable because you want to be able to have the URI go /foo/{foo-id} for performing operations on an individual Foo.
(4) requires Fizzes and Buzzes to become completely separate branches of the URI tree
(5) seems like a decent scheme although it might mess up the URI tree.
I'd be strongly tempted to just have a POST to /foo with the type of foo to be created (fizz or buzz) being determined by the contents of the document being POSTed. It would respond with a suitable redirect to the URI for the newly created foo (/foo/{fooId}, presumably) through which you'd manipulate things in the normal way.
Admittedly, I am not a REST expert, however here are my two cents.
Why would you even have a post to foo/{foo-id}? In that case, it would be more of a PUT for an update. The only time you would need to post would be if the id was being auto-created and unknown until actually created. So, in that case, I would lean towards 1 as you are creating a foo and the rest is just information needed to create foo. After that point, would you even need to care about the subtype (fizz or buzz)? I would assume the foo/{foo-id} would be enough information to work on it individually and determine the type from it.
So:
POST /foo?type=fizz
**You could possibly even remove the query string and send it in as your creation data, but that is up to you
GET /foo/{foo-id} ...retrieve the created foo
PUT /foo/{foo-id} ...update the created foo
DELETE /foo/{foo-id} ...delete the created foo
That is what I would do at least.
<soapbox>If you are really doing a RESTful architecture, then you shouldn't need to ask this question</soapbox>.
RESTful architectures include links in the representation that direct the flow of the application. If you are creating a new resource that is a child of a parent resource, then the representation of the parent resource should have an embedded link that tells you what URL and (potentially) which verb to use. Something like:
<link rel="add-child" method="POST" href="http://foo/1234">Add a new child</link>
If you are creating a wholly new root resource then, you probably want to POST to an absolute URL and have either the response document or Location header tell your application where to retrieve a new representation from. The target resource is essentially the "entry point" into your application's state machine.