What should a link extension relation type URI point to in a RESTful API? - rest

I've been designing an API recently that needs to be RESTful, and have managed to define a system that uses exclusively HTTP headers and query string parameters to define meta data so that the body of responses is free to just be actual resource data only.
However I'm now thinking about links for HATEOAS, and due to wanting to keep everything in HTTP headers or query string parameters I've decided on using the HTTP Link header field.
This has brought up a question about the rel attribute that I'm having trouble finding a direct answer for.
My idea is that for collections of resources one of the Links that will be sent in a response will be something like: Link: <https://api.domain.com/things/{id}>; rel="..."
This would allow a client to use simple string expansion, as defined in RFC6570, to create a correct resource URI for each resource in a collection without me having to embed meta data into each resource and without the client needing to know anything other than the URI template and the resource ID.
However, I'm not sure what the rel should be here, or what it should point to.
In RFC5988, it says that an extension relation type must be a URI and:
Although the URI can point to a
resource that contains a definition of the semantics of the relation
type, clients SHOULD NOT automatically access that resource to avoid
overburdening its server.
My question is, what should the definition look like in a RESTful API?
By the looks of it I could just make the rel something like https://api.domain.com/media/thing, or something like that.
But then what should the actual definition content be?
It looks like it could technically be anything, for example a plain text document with a short explanation.
Is there any RESTful standard for these kinds of rel attributes and what they should point to?
Any help is appreciated.

Looking at Richardson's Maturity Model level 3, rel seems to be representing the name of the published link/relationship. In your case that might translate to curie:thing-by-id (provided you're using curies as suggested in the proposed HAL draft), for example. The idea is that the client could search a link by its name (rel), without peering into the actual url.

Is there any RESTful standard for these kinds of rel attributes and what they should point to?
I don't know of an authoritative answer, but it is probably worth noticing that link relations that are registered with IANA reference the standards document that describes the link.
For example, in the registry, the "item" and "collection" relations both reference RFC 6573. Which, you will notice, is pretty darn close to a "a plain text document with a short explanation."
If the media type of your documentation supports anchors, then you could use a link directly to the secondary resource as your link relation
Link: <https://api.domain.com/things/2>; rel="https://api.domain.com/link-relations#foo"

Related

What is the RESTful way to design URL that returns parent of a child resource?

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.

Get a resource in rest API based on an alternative identificator

What would be a rest API convention to get a resource based on a different identificator?
For example
GET
/resource/{id}
GET
/resource/{guid}
Since this could be considered as a dupliate resource and setting routes for this could be a problem, what is an alternative then would follow rest API guidelines?
Maybe
/resources/?guid={guid}
or
/resources/guid/{guid}
or something else?
Short answer
You could use both /resource/{id} and /resource/{guid}. Many frameworks support regular expressions for matching path parameter values.
Long answer
REST is an architectural style and not a cookbook for designing URIs (see notes below). It doesn't enforce any URI design and it's totally up to you to pick the URIs that better identify your resources.
What you should keep in mind is: it's perfectly fine to have multiple mappings for the same entity. And each mapping is a resource, according to Fielding's dissertation:
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.
With that being said, if you are supporting DELETE, it's important to mention how it's supposed to work:
4.3.5. DELETE
The DELETE method requests that the origin server remove the association between the target resource and its current functionality. In effect, this method is similar to the rm command in UNIX: it expresses a deletion operation on the URI mapping of the origin server rather than an expectation that the previously associated information be deleted. [...]
Note 1: The URI syntax is defined in the RFC 3986. As general rule, the path is organized in hierarchical form (with segments separated by /) and can contain non-hierarchical data in the query component (starting with ?).
Note 2: The REST architectural style is described in the chapter 5 of Roy T. Fielding's dissertation and it defines a set of constraints that must be followed by the applications that follow such architecture. However it says nothing about what the URIs must be like.
Note 3: The examples of a popular article written by Martin Fowler explaining a model defined by Leonard Richardson suggest a URI structure that looks friendly and easy to read.
I wouldn't normally duplicate an endpoint. The question would be:
why does one client have an id while another has a guid?
what design choice allowed that to happen?
I would leave it as a single resource endpoint:
GET
/resource/{id}
so clients who access resources via their id will use the above endpoint. I'd allow clients who access resources via their guid to exchange what they have (guid) for what they need (id):
GET
/id/{guid}
The above returns a resource id for the given resource guid. The client can then call the main resource endpoint with the id they have just received:
GET
/resource/{id}
but ultimately I'd look into why some clients use a guid rather than an id and change that so all clients access the API in the same way.

REST strategy for overloading GET verb

Consider a need to create a GET endpoint for fetching Member details using either of 4 options (It's common in legacy application with RPC calls)
Get member by ID
Get member by SSN
Get member by a combination of Phone and LastName (both must be passed)
What's a recommended strategy to live the REST spirit and yet provide this flexibility?
Some options I could think of are:
Parameters Based
/user/{ID}
/user?ssn=?
/user?phone=?&lname=?
Separate Endpoints
/user/{ID}
/user/SSN/{SSNID}
/user/{lname}/{phone}
RPC for custom
/user/{ID}
/user/findBySSN/
/user/findbycontact/
REST doesn't care what spelling you use for your identifiers.
For example, think about how you would do this on the web. You would provide forms, one for each set of search criteria. The consumer would choose which form to use, and submit the form, without ever knowing what the URI is.
In the case of HTML forms, there are specific processing rules for describing how the form information will be copied into the URI. The form takes on the aspect of a URI Template.
A URI Template provides both a structural description of a URI space and, when variable values are provided, machine-readable instructions on how to construct a URI corresponding to those values.
But there aren't any rules saying that restrict the server from providing a URI template that directs the client to copy the variable values into path segments rather than into the query string.
In other words, in REST, the server retains control of its own URI space.
You might sometimes prefer to use path segments because of their hierarchical nature, which may be convenient if you want the client to use relative resolution of relative references in your representations.
REST ≠ pretty URLs. The two are orthogonal.
Your question is about the latter, I feel.
Whilst the other answers have been good, if you want your API to work with HTML forms, go with query parameters on the collection /user resource for all fields, even for ID (assuming a human is typing these in based on information they are getting from sheets of paper on their desk, etc.)
If your server is able to produce links to each record, always produce canonical links such as /users/{id}, don't duplicate data under different URLs.

RESTfully Fetching by Attribute

Which of the following URLs is more RESTful compliant when it comes to fetch only items that have a certain value for attribute?
GET: /items/attribute/{value}
GET: /items/findByAttribute?attribute={value}
GET: /items?attribute={value}
Having in mind that GET: /items returns all items.
Example
GET: /shirts/color/FF9900
GET: /shirts/findByColor?color=FF9900
GET: /shirts?color=FF9900
I think that the last option is the correct one ;-)
Here are some comments for the others:
Generally the path element right after the one that corresponds to the list resource is the identifier of the element. So if you use something at this level, it could be considered as an identifier...
You can have resource to manage a particular field but the URL would be something like /items/{itemid}/fieldname.
You shouldn't use "action names" within the URL (in your example findByAttribute). The HTTP method should correspond to the "action" itself. See this answer if you want to support several actions for an HTTP method: How to Update a REST Resource Collection.
There is a question about how to design search filter: How to desing RESTful advanced search/filter. I think that your use case if a bit simple and using query parameters matches for you.
Otherwise I wrote a post about the way to design a Web API. This could be useful for you. See this link: https://templth.wordpress.com/2014/12/15/designing-a-web-api/.
Hope it helps you,
Thierry
Most certainly this one
GET: /items?attribute={value}
Why?
GET: /items/attribute/{value} is wrong because with REST, url segments represent resources, attribute is not a resource
GET: /items/findByAttribute?attribute={value} is wrong for the same reason really. findByAttribute is not a resource
Using url queries to filter by attributes is perfectly fine, so go with that.
URI semantics are irrelevant to REST. It doesn't make sense to ask which URI is more RESTful. What makes an URI RESTful or not is how the client obtains it. If he's reading URI patterns in documentation and filling placeholders with values, it's not RESTful. If this is news for you, I recommend reading this.
With that in mind, all three examples can be RESTful if the server provided that URI template to the client as a link to query the collection resource filtering by that value, but 3 is definitely the best option since it follows a more conventional query syntax. I wouldn't use 2 since it implies a method call and it looks too RPC for my taste, and I wouldn't use 1 since it implies for a human that it will return only the attribute as a resource.

RESTful POSTS, do you POST objects to the singular or plural Uri?

Which one of these URIs would be more 'fit' for receiving POSTs (adding product(s))? Are there any best practices available or is it just personal preference?
/product/ (singular)
or
/products/ (plural)
Currently we use /products/?query=blah for searching and /product/{productId}/ for GETs PUTs & DELETEs of a single product.
Since POST is an "append" operation, it might be more Englishy to POST to /products, as you'd be appending a new product to the existing list of products.
As long as you've standardized on something within your API, I think that's good enough.
Since REST APIs should be hypertext-driven, the URI is relatively inconsequential anyway. Clients should be pulling URIs from returned documents and using those in subsequent requests; typically applications and people aren't going to need to guess or visually interpret URIs, since the application will be explicitly instructing clients what resources and URIs are available.
Typically you use POST to create a resource when you don't know the identifier of the resource in advance, and PUT when you do. So you'd POST to /products, or PUT to /products/{new-id}.
With both of these you'll return 201 Created, and with the POST additionally return a Location header containing the URL of the newly created resource (assuming it was successfully created).
In RESTful design, there are a few patterns around creating new resources. The pattern that you choose largely depends on who is responsible for choosing the URL for the newly created resource.
If the client is responsible for choosing the URL, then the client should PUT to the URL for the resource. In contrast, if the server is responsible for the URL for the resource then the client should POST to a "factory" resource. Typically the factory resource is the parent resource of the resource being created and is usually a collection which is pluralized.
So, in your case I would recommend using /products
You POST or GET a single thing: a single PRODUCT.
Sometimes you GET with no specific product (or with query criteria). But you still say it in the singular.
You rarely work plural forms of names. If you have a collection (a Catalog of products), it's one Catalog.
I would only post to the singular /product. It's just too easy to mix up the two URL-s and get confused or make mistakes.
As many said, you can probably choose any style you like as long as you are consistent, however I'd like to point out some arguments on both sides; I'm personally biased towards singular
In favor of plural resource names:
simplicity of the URL scheme as you know the resource name is always at plural
many consider this convention similar to how databases tables are addressed and consider this an advantage
seems to be more widely adopted
In favor of singular resource names (this doesn't exclude plurals when working on multiple resources)
the URL scheme is more complex but you gain more expressivity
you always know when you are dealing with one or more resources based on the resource name, as opposed to check whether the resource has an additional Id path component
plural is sometimes harder for non-native speakers (when is not simply an "s")
the URL is longer
the "s" seems to be a redundant from a programmers' standpoint
is just awkward to consider the path parameter as a sub-resource of the collection as opposed to consider it for what it is: simply an ID of the resource it identifies
you can apply the filtering parameters only where they are needed (endpoint with plural resource name)
you could use the same url for all of them and use the MessageContext to determine what type of action the caller of the web service wanted to perform.
No language was specified but in Java you can do something like this.
WebServiceContext ws_ctx;
MessageContext ctx = ws_ctx.getMessageContext();
String action = (String)ctx.get(MessageContext.HTTP_REQUEST_METHOD);
if(action.equals("GET")
// do something
else if(action.equals("POST")
// do something
That way you can check the type of request that was sent to the web service and perform the appropriate action based upon the request method.