I have a simple model
Each Use can have multiple cars
Now when I decide to name the related REST URL naming for Cars service
Initially I suggest to be as the following
GET /cars/{carId}
But when I read about best practices in REST Resource Identifier (URI) Naming
I found that its better to put parent information in the URI as the following
GET /users/{userId}/cars/{carId}
Any one explain to us
Why the second one is the recommended naming
However, I need ONLY a carId to fetch the car
And no need to userId
REST does not care what spelling you use for your identifiers.
/a4e199c3-ea64-4249-96aa-abb71d860a55
Is a perfectly satisfactory REST identifier.
Guidelines such as the one that you linked should be understood a style guide; human readable identifiers that adhere to local spelling conventions are goodness for exactly the same reasons as human readable variable names that adhere to local spelling conventions.
Some URI guidelines advocate convention over configuration -- put broadly, you can simplify your implementations if you choose identifier spellings that allow your framework to deduce where things should live.
when I read about best practices in REST Resource Identifier (URI) Naming
I found that its better to put parent information in the URI
Maybe; part of the problem may be confusing resources with entities. It's an entirely normal thing for one single row in your database to contribute to the representation of many different resources, each of which has its own identifier
/users/:userId/cars/:carId
/cars/:carId
In HTTP, you might even send to the client information that the representation of one of these resources is equivalent to another (see RFC 7231).
The good news: hypermedia clients can deal this sort of thing automatically, because they have built into them awareness of the semantics of links; web aware hypermedia clients (for instance: browsers) will also be able to do the right thing with the meta data.
The bad news: you probably aren't using hypermedia types as your representations, so you won't see those benefits.
IMO, it depends more on the context. Consider the following example:
GET /users/user001/cars/car001
Response:
owner-name, car-license-no, purchase-date, first-owner
Here the response is - car details, specific to a user
GET /cars/car001
Response:
car-model-no, manufacturer, displacement, car-type
Here the response is - car details, specific to the car
Related
Lets assume we have some main-resource and a related sub-resource with 1-n relation;
User of the API can:
list main-resources so GET /main-resources endpoint.
list sub-resources so GET /sub-resources endpoint.
list sub-resources of a main-resource so one or both of;
GET /main-resources/{main-id}/sub-resources
GET /sub-resouces?main={main-id}
create a sub-resource under a main-resource
POST /main-resource/{main-id}/sub-resouces: Which has the benefit of hierarchy, but in order to support this one needs to provide another set of endpoints(list, create, update, delete).
POST /sub-resouces?main={main-id}: Which has the benefit of having embedded id inside URL. A middleware can handle and inject provided values into request itself.
create a sub-resource with all parameters in body POST /sub-resources
Is providing a URI with main={main-id} query parameter embedded a good way to solve this or should I go with the route of hierarchical URI?
In a true REST environment the spelling of URIs is not of importance as long as the characters used in the URI adhere to the URI specification. While RFC 3986 states that
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 path is terminated by the first question mark ("?") and number sign ("#") character, or by the end of the URI. (Source)
it does not state that a URI has to have a hierarchical structure assigned to it. A URI as a whole is a pointer to a resource and as such a combination of various URIs may give the impression of some hierarchy involved. The actual information of whether URIs have some hierarchical structure to it should though stem from link relations that are attached to URIs. These can be registered names like up, fist, last, next, prev and the like or Web linking extensions such as https://acme.org/rel/parent which acts more like a predicate in a Semantic Web relation basically stating that the URI at hand is a parent to the current resource. Don't confuse rel-URIs for real URIs though. Such rel-URIs do not necessarily need to point to an actual resource or even to a documentation. Such link relation extensions though my be defined by media-types or certain profiles.
In a perfect world the URI though is only used to send the request to the actual server. A client won't parse or try to extract some knowledge off an URI as it will use accompanying link relation names to determine whether the URI is of relevance to the task at hand or not. REST is full of such "indirection" mechanism in order to help decoupling clients from servers.
I.e. what is the difference between a URI like https://acme.org/api/users/1 and https://acme.org/api/3f067d90-8b55-4b60-befc-1ce124b4e080? Developers in the first case might be tempted to create a user object representing the data returned by the URI invoked. Over time the response format might break as stuff is renamed, removed and replaced by other stuff. This is what Fielding called typed resources which REST shouldn't have.
The second URI doesn't give you a clue on what content it returns, and you might start questioning on what benefit it brings then. While you might not be aware of what actual content the service returns for such URIs, you know at least that your client is able to process the data somehow as otherwise the service would have responded with a 406 Not Acceptable response. So, content-type negotiation ensures that your client will with high certainty receive data it is able to process. Maintaining interoperability in a domain that is likely to change over time is one of RESTs strong benefits and selling points. Depending on the capabilities of your client and the service, you might receive a tailored response-format, which is only applicable to that particular service, or receive a more general-purpose one, like HTML i.e.. Your client basically needs a mapping to translate the received representation format into something your application then can use. As mentioned, REST is probably all about introducing indirections for the purpose of decoupling clients from servers. The benefit for going this indirection however is that once you have it working it will work with responses issued not only from that server but for any other service that also supports returning that media type format. And just think a minute what options your client has when it supports a couple of general-purpose formats. It then can basically communicate and interoperate with various other services in that ecosystem without a need for you touching it. This is how browsers operate on the Web for decades now.
This is exactly why I think that this phrase of Fielding is probably one of the most important ones but also the one that is ignored and or misinterpreted by most in the domain of REST:
A REST API should spend almost all of its descriptive effort in defining the media type(s) used for representing resources and driving application state, or in defining extended relation names and/or hypertext-enabled mark-up for existing standard media types. (Source)
So, in a true REST environment the form of the URI is unimportant as clients rely on other mechanisms to determine whether to use that URI or not. Even for so called "REST APIs" that do not really care about the true meaning of REST and treat it more like old-school RPC the question at hands is probably very opinionated and there probably isn't that one fits all solution. If your framework supports injecting stuff based on the presence of certain query parameters, use that. If you prefer the more hierarchical structure of URIs, go for those. There isn't a right or wrong in such cases.
According to the URI standard when you have a hierarchical relationship between resources, then better to add it to the path instead of the query. https://datatracker.ietf.org/doc/html/rfc3986#page-22 Sometimes it is better to describe the relation itself, not just the sub-resource, but that happens only if the sub-resource can belong to multiple main resources, which is n:m relationship.
A situation where I want a URL for list of values for a filter a URL for best match out of them to be returned.
Example data is as follows
/studentInformation?student=Albert&class=3&rollno=13&marks=24 will return 2 entries as no value is a value of interest to me
/studentInformation/bestMatch?student=Albert&class=3&rollno=13&marks=24 will return 1 value which is the best match i.e entry no 3 (limiting to 1 would not find the best match)
what is the right way to form the URL for best match?
REST doesn't have a standard for designing URI. It just says that every resource should have one.
On the web, we have a standard that describes the production rules for URI (RFC 3986) and a standard that describes URI Templates (RFC 6570), but neither of those get into the level of detail that you seem to be asking for.
And that's on purpose: URI on the web are a lot like variable names in a programming language; it's more generally useful to afford you the freedom to make local decisions about spelling conventions.
The machines don't care about semantic relationships between the spelling of the URI and the information of the resource, so you can choose any spelling that makes things better for people (where people here could be customers looking at the URI in their browser history, or pasting it into emails, or operators looking at URI in web logs, or writers trying to document your resource model, or even just the programmers trying to implement the API).
I am modeling blogging REST API which has resources Blog, Post and Comment with following URLs:
/api/blogs
/api/blogs/{blogId}
/api/blogs/{blogId}/posts
and I create separate endpoint for all Posts in and their Comment`s:
/api/posts
/api/posts/{postId}
/api/posts/{postId}/comments
Given that I have postId, what is the RESTful way to get Blog for a specific Post? I have three ideas:
1. /api/posts/{postId}/blog
2. /api/blogs/parent-of-post/{postId}
3. /api/blogs?postId={postId}
To me the 1. URL looks more "prettier" but the 2. option looks more "logical" since that endpoint (eg. /api/blogs/*) is generally for blogs resources.
The third option uses query string as parameter but the issue I have with it is that this endpoint would return different type of body depending on the parameter. Eg. without parameter /api/blogs returns a collection of Blog resources, while with parameter postId it would return just single instance of Blog. I am not sure if this is good thing to do (especially because I am using ASP.NET Core and C# which has strongly typed return objects, so implementation might be awkward).
what is the RESTful way to get Blog for a specific Post?
Real answer: anything you want.
REST doesn't care what spelling conventions you use for your resource identifiers. As long as your identifiers conform to the production rules described by RFC 3986, you are good to go.
/api/blogs?postId={postId}
This is a perfectly normal choice, and turns out to be a really convenient one when you want to use general purpose web browsers, because HTML forms already have standards that make it easy to create URI with this shape.
Your other two choices are fine; they lose a point for not being HTML form friendly, but it's still easy enough to describe these identifiers using a URI template.
The third option uses query string as parameter but the issue I have with it is that this endpoint would return different type of body depending on the parameter
General purpose API consumers do NOT assume that two resources are alike just because the spellings of their identifiers overlap each other.
Which is to say, from the outside, there is no implied relationship between
/api/blogs
/api/blogs/1
/api/blogs?postId=2
so the fact that they return different bodies really isn't going to be a surprise to a general purpose consumer.
Now, your routing framework may not support returning different types from the handlers for these resources (or, more likely, may not have any "nice" way to do the routing automatically), but that's an implementation detail deliberately hidden behind the REST API facade.
Similarly, the human beings that read your access log might prefer one spelling to another, to reduce their own cognitive load.
I have many resources like product, bookings and etc. Need routes to get all resources by user.
For example:
{GET} /bookings/user
I think this is incorrect, because this route would return user resource. Or I am wrong?
What is the right way?
I think this is incorrect, because this route would return user resource. Or I am wrong?
It returns a representation of the resource identified by /bookings/user. What resource is that? It's up to the origin server.
rest doesn't care what spelling conventions you use for your identifiers. As far as REST is concerned, /6414b60b-1ecb-4e28-8887-4bfe120810e7 is a perfectly satisfactory resource identifier.
If you want human readable identifiers, that's OK too. RFC 3986 encourages that practice:
A URI often has to be remembered by people, and it is easier for people to remember a URI when it consists of meaningful or familiar components.
You should also keep in mind that RFC 3986 distinguishes hierarchical and non-hierarchical signal in the URI
The URI syntax is organized hierarchically, with components listed in order of decreasing significance from left to right. -- section 1.2.3
The path component contains data, usually organized in hierarchical form, that, along with data in the non-hierarchical query component -- section 3.3
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) -- section 3.4
In short, if you are describing information that is described in a hierarchy, then using path segments makes a lot of sense
I don`t return users and user ids, need return all booking for authorized user.
That sounds like you are describing a spelling like /my/bookings.
A heuristic that may help in URI design is to consider the benefits of relative references; much as with a file system, you can use dot-segments to navigate toward the root of the namespace.
`/my/bookings` + `../profile` --> `/my/profile`
There are reasons where you might not want to support hackable URI; so you'll want to think about that constraint, and its implications, carefully.
Typically, one would use a query parameter for this:
GET /bookings?userId={userId}
That would return all the bookings for the given user id.
If entity (e.g person) has data that has to be presented in different representations:
I have a big profile that has different representations but for a small example:
representations1:
GET /profiles/{id}/activity/projection1
returns:
{"actions":["add", "delete", "add"], "dates":[1499865456, 1499861544, 1499863655]}
representations2:
GET /profiles/{id}/activity/projection2
returns:
{add_at:[1499865456, 1499863655], delete_at:[1499861544]}
So the question: how to design such cases?
I have some ideas but don't know which one is better
GET /profiles/{id}/activity/projection1
GET /profiles/{id}/activity/projections/1
GET /profiles/{id}/activities/projection1
GET /profiles/{id}/activities/projections/1
GET /profiles/{id}/activity-actions and GET /profiles/{id}/activity-timestamps
I found only one same question Different RESTful representations of the same resource but it is about filtering data in response not about change model
A couple things to keep in mind
As far as REST is concerned, two things with different identifiers (URI) are different resources. The fact that they have the same source of truth is an implementation detail.
In designing a REST api, your resources are integration points. The representations of your resources will depend on the state of your model at any given time.
For instance, if I look up Clayton Kershaw at Baseball Reference, I am probably directed to this resource
http://www.baseball-reference.com/players/k/kershcl01.shtml
But if I ask to see his "2014 splits", then I'll be directed to this resource instead.
http://www.baseball-reference.com/players/split.fcgi?id=kershcl01&year=2014&t=p
There's no particular reason that every resource identifier related to kershcl01 has to be under the same root in the hierarchy.
You may want to review Cool URIs don't change; stable URI over time is a good goal for a design, in which case you'll want to make sure that temporary implementation details don't leak into the URI space.
Jim Webber's observation was that REST resources are part of your integration domain; "Resources adapt your domain model for the web."
So your design guidance should probably come from asking what properties are important to your consumers, and what constraints will ensure that those properties are present (outside in), rather than starting from your (current) implementation.