Does HATEOAS contemplate hypermedia in the Error Response? - error-handling

In a Hypermedia-Driven RESTful solution, should I include relevant HATEOAS links in Error responses?
For instance, let's imagine we have a Microservices architecture.
We have FooSvc and BarSvc, where Bar resources are associated in a 1:1 relation with Foo resources, but managed independently (e.g. we have Projects that we can create just to present them, and then we can decide to Manage a project in our platform).
So, we can try to fetch the Bar resource associated with Foo with id 1 using GET /foo/1/bar (not caring how the request is routed downstream to the BarSvc).
Since there is no such Bar instance created yet, the service will retrieve a 404 response. Should that response include hypermedia links to point out how this can be created (e.g. a HAL _links field with a link to POST /foo/1/bar)?

Definitely, in fact, RFC7807 - 'Problem Details for HTTP APIs' can help with this, and the most popular frameworks should provide support for it (as for example the Spring HATEOAS library here)
Also, there is a proposed vnd.error mime type for this (further explained in this post), but it seems it has been superseded by RFC7807 mentioned above, at least Spring deprecated this in favor of the Problem Details approach (here)

Related

Are these URIs considered one endpoint or 3 endpoints?

I am sure this will be a simple question but I want to make sure I use the correct terminology for a meeting explaining my new API.
So if I have the following URIs for my API:
https://testapi.org/api/registration - POST defined
https://testapi.org/api/token - GET defined
https://testapi.org/api/pricedata - GET and POST defined
So these are 3 controllers in the same Web API. In conversation is this considered 1 endpoint or 3 endpoints?
In conversation is this considered 1 endpoint or 3 endpoints?
The REST answer is "0 endpoints".
There is no such thing as a REST endpoint -- Fielding, 2018
What you show here are three resource identifiers, and by implication three resources.
The fact that those three resources each have a separate "controller" is an accident of your implementation. REST really doesn't care.
In a context like OpenAPI 3, you will also see this described as four "operations" (path + method).
(You'll also see that the OpenAPI 3 documentation seems to consider "resource" and "endpoints" to be equivalent.)
Given Hohpe's description of the MessageEndpoint pattern, I'm inclined to think that resource isn't a particularly good match for "endpoint".
You might be able to argue that there is a message-endpoint in your web server process, which is handing off messages to your controllers? In which case, that would be one endpoint.
Are you saying I should have combined up some of the verbs into less controllers?
No, I'm not saying that. REST says that we need a client-stateless-server protocol with uniformly understood self descriptive messages. The HTTP specifications define self descriptive request messages and self descriptive response messages.
But the magic black box that decides what response to send to a request is yours. The number of controllers you decide to use is an implementation detail that is hidden from clients behind the HTTP facade.
There's nothing in REST, or HTTP, that requires/forbids that the server implementation use MVC.
Well, the responsibility of each one are different, it doesn't matter that they are acting in the same resource, so, for practice, all of that are different endpoint, you could put the 1 and 2 in the same one, but the 3 need to be a different product.

some doubts related to REST API [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 2 years ago.
Improve this question
Can we say Like Rest API we have SOAP, XML RPC, JSON RPC, GRAPH QL I mean Rest is just a type of API?
Is Rest is just a mechanism to share data between applications by using HTTP methods?
REST can share data between applications only with HTTP there is no alternative?
What is the relation between REST & CRUD exactly? we are saying HTTP: POST is CRUD: CREATE my question is HTTP: POST will just post the data to server and it's business logic's headache to CREATE A NEW RESOURCE in the server side but how we all are saying HTTP: POST is nothing but CRUD: CREATE here HTTP: POST is just helping to share the data only right then how it is related to CRUD: CREATE? If that is the case we can create a new resource with HTTP: GET by writing business logic right then why so many sites are saying REST is a mechanism to do CRUD operations... But it should be REST is a mechanism to help in Sharing the data between applications right?!!! (I have doubt similarly with HTTP: DELETE, GET, PUT aswell)
Last but not least... what exactly Representational state transfer mean? could you please answer this with a very low level general answer instead of definition.
Can we say Like Rest API we have SOAP, XML RPC, JSON RPC, GRAPH QL I mean Rest is just a type of API?
REST stands for representation state transfer and is just an architectural style, not a technology or protocol. According to Robert C. "Uncle Bob" Martin an architecture is about intent and the intention behind REST is the decoupling of servers and clients in a distributed system.
REST basically just defines a set of constraints that when followed correctly allow servers to change at any time without breaking clients as clients will just depend on the data given by the server and not on any external data or documentation. REST can be regarded as Web surfing for applications. The main premise should always be that a server teaches a client on how certain things can be achieved.
On the Web a server can i.e. teach a client on the supported properties of a resource through the help of HTML forms. Not only does a client learn that way what a server expects as input, it also learns what HTTP operation should be used to send the data to the server, the endpoint URI to send the request to as well as, usually implicitly given, also the media type to convert the input to, which is application/x-www-form-urlencoded usually by default, which transforms an input like the HTML example below for first and lastname to something like this:
fName=Roman&lName=Vottner
Is Rest is just a mechanism to share data between applications by using HTTP methods?
REST itself is protocol agnostic meaning that it is not tide to HTTP itself and could just work on other transport protocols as well. Though the common perception many developers have is that it is based on HTTP. After all, as Jim Webber put it, HTTP is just a transport layer whose domain is the transfer of files or data over the Web. All HTTP does is to send one document from one machine to the next and any business rules we conclude from sending/receiving a request are just a side effect of the actual document management. It is therefore always better to think of a request as a whole document and the HTTP operation define how the document should be stored on the current machine, especially when such a document is already available, instead of thinking of a service method invocations. The latter one is a typical RPC view.
REST can share data between applications only with HTTP there is no alternative?
HTTP is just a transport layer used in a REST architecture. The architecture cares more on the interaction model between client and servers than on the technical nuances of HTTP. As REST itself is transport protocol agnostic it could be used with other, maybe proprietary protocols as well.
What is the relation between REST & CRUD exactly? we are saying HTTP: POST is CRUD: CREATE my question is HTTP: POST will just post the data to server and it's business logic's headache to CREATE A NEW RESOURCE in the server side but how we all are saying HTTP: POST is nothing but CRUD: CREATE here HTTP: POST is just helping to share the data only right then how it is related to CRUD: CREATE? If that is the case we can create a new resource with HTTP: GET by writing business logic right then why so many sites are saying REST is a mechanism to do CRUD operations... But it should be REST is a mechanism to help in Sharing the data between applications right?!!! (I have doubt similarly with HTTP: DELETE, GET, PUT aswell)
Fielding's thesis on the REST architecture style does not contain the term CRUD at all. The term REST nowadays is heavily misused as people probably didn't bother to actually read the thesis, which admittingly is a bit abstract, and just follow what some people thought may be REST but was actually RPC. Nowadays, if a typical stakeholder talks about REST they usually think of a JSON-based HTTP CRUD-API whose supported endpoints are defined in some Web documentation (Swagger, OpenAPI, ...) and where the HTTP operations for POST (= Create), GET (= Read), PUT (= Update), Delete (= Delete) are supported by default. However, this is unfortunately far from the truth. Though people are just to accustomed with their (wrong) definition and don't see or don't care about the actual problem in their misusage. They don't care about a long-lasting service as in 2-5 years the next-gen technology is here that allows to reduce the number of lines of codes even more and if a new "version" of a service is needed, this usually goes hand in hand with a technology switch also, to justify the "cost of change" somehow.
Last but not least... what exactly Representational state transfer mean? could you please answer this with a very low level general answer instead of definition.
Probably the easiest way to grasp how the interaction in a REST architecture should be is by analyzing typical interaction on the Web, the big cousin of REST. You, as a user, usually start by opening your browser (= client) and typing in some URL in the search bar. Next a Web page is rendered on your screen. Behind the curtain a couple of things happened. Besides the whole connection management and any eventual TLS handshake your browser sent at least one GET request to the target server. On sending the GET request, the client included information on his capabilities, i.e. through the Accept HTTP header. This header is used on the server side to decide which representation format to generate and send to the user. On the Web this might be something like text/html or application/xhtml+xml or if some report is generated might be something like application/pdf or application/vnd.ms-excel or the like, depending which representation format fit the data best.
The representation format itself is now a concrete instance of a document following a certain media type specification. I.e. the HTML forms specification defines the supported elements within a <form>...</form> tag pair as well as describes the semantics of each of the elements. The concrete instance may now define a form as such:
<form action="/action_page.php" method="get">
<label for="fname">First name:</label>
<input type="text" id="fname" name="fname"><br><br>
<label for="lname">Last name:</label>
<input type="text" id="lname" name="lname"><br><br>
<input type="submit" value="Submit">
</form>
which should only use elements and attributes defined within the specification else a receiver of that document might not be able to process it correctly.
This process of telling the server which document types a client supports and allowing the server to chose a fitting representation is called content type negotiation and allows the exchange of arbitrary, type-less documents. Of course, both parties need to support and understand at least one common media type to be able to interact with each other. This is similar to a Frenchmen who does not understand a word of Chinese and a Chinese one that does not understand any word of French who need to communicate (for whatever reason), if both speak English they will be able to communicate.
There are loads of different media types already available that all server different purposes. Depending on your needs an all-purpose one, such as text/html, might be sufficient, others such as application/json or even application/hal+json might though lack support for certain needed elements. Existing media types might not support needed elements. In such a case extending such media types and registering those is probably easier than creating a whole media type from scratch.
REST assumes that a resource (i.e. a remote document) contains some internal data, its state. This state can be represented in many different ways. Think of some monthly sails figures. You might ship the data either in a HTML table, as CSV data, as Excel file, as PDF or yet a different representation format. Regardless of the chosen media type to marshal the data in, the actual data at least should express the same. Instead of questioning which media type you want to support, you should better ask how many different ones you want to support as this just increases the likelihood that other clients may interact with your server also.
edit:
I got all the points except 4th point... Could you please elaborate a bit.. So is it just a mechanism that helps in sharing the data between applications by using HTTP methods? we can say like that?
CRUD is a typical term in the context of persistence, especially with databases. REST or more formally the REST architecture itself treats persistence as internal detail. A typical user usually does not care whether some data is persisted into a DB, a local file system or is kept just in memory. All s/he cares is that the server can process it or for storage services also return the same data that was sent to the server.
In regards to the mapping of CRUD to the HTTP operations, if you take a look at HTML you might see that it only supports POST and GET operations. So anything related to C, U or D are performed with POST which is defined to process the enclosed representation according to the resource's own semantic. With POST you are basically allowed to do anything, even retrieving data if you like.
However, HTTP defines certain properties for the respective operations:
safe
idempotent
cacheable
The first property is a promise to clients that a well-behaved server should not alter the state of a resource upon requesting. The second one is a promise in regards to automatic retry attempts caused by i.e. temporary connection issues. And the latter one allows clients to store responses locally and reuse these instead of requesting the same resource again, if the cached content is "fresh-enough".
GET and HEAD are both safe, idempotent and cacheable, meaning that a client can request resources with such an operation without being hold accountable for any eventual changes. Think of a Web spider that is invoking arbitrary URIs all the time to learn new pages over time. If a GET request on a URI would trigger an order of a Pizza or the like, it is basically the server's fault and not the clients one if a crawler would order Pizzas every time such URIs are called.
PUT and DELETE are only idempotent, which basically allows a client to automatically resend a request in case of a network issue as the outcome of the operation leads to the same result regardless whether the request was processed once or multiple times in a row. Note that this property does not consider changes done by other clients to that resource between a resend. Such data would of course be overwritten.
The remaining operations (POST, PATCH, CONNECT, TRACE) are neither of these.
While technically it is sufficient to only use POST for each request, the above mentioned properties should trigger an inner intention to use them, when appropriate. However, as before mentioned, not the client should chose which operation to perform but the server should tell a client which HTTP operation it should use.
In regards to POST vs. PUT, both operations should behave similar on creating a resource. Both need to add a Location header within the response that teaches a client about the location of the new resource. PUT however, in contrast to POST, replaces the current representation of the requested resource with the one provided in the request body. So it already targets the respective resource while for a POST request the server defines where the resource is created. It is allowed to perform certain sanity checks and also to transform the representation to fit the representation format of the current one. It is also allowed to have side effects, i.e. think of Git where a commit creates a new entry on top of the current branch and moves the HEAD to the new commit.
PUT is probably considered as update operation as the replacement of the document more or less has the effect of an update. If no representation was yet available this just has the effect of the creation (including the location header). In the past, unfortunately, many developers used PUT incorrectly by performing a partial update instead of really replacing the whole document. While the spec states that a partial update could be achieved by overlapping resources (i.e. share parts of the same data in multiple resources), the usage of PATCH, which also is used incorrectly most of the time, may be better from a performance standpoint on larger resources.
Due to POSTs definition, one can do anything with it, though historically a document upload in HTML was triggered through this operation that is basically a resource creation on the server side. That POST is used for many other things as well though is not that important for that CRUD paradigm.
In regards to your concerns about the right terminology, most people, according to my experience, simply do not care. They just want to get the job done ASAP and move on. As roughly 90% of the users seem to understand a pretty similar concept when talking about REST (even though this view is flawed) which usually resolves around JSON, HTTP, CRUD, Swagger/OpenAPI, ... they usually only look for quick-win-solutions and more or less agreement on their thought process.
As HTTP (0.9-1.1) is a plain text protocol sending a GET request is not much different from a POST or PUT request, so technically you can create resources with GET request or support payloads on GET requests (semantics of the payload is undefined according to the spec). That's why I mentioned well-behaved client/servers above. In such a case, however, due to the safe property of GET, if you as a server maintainer violate the HTTP protocol you are the one to blame in case something "unexpected" is happening (crawler is ordering 500 Pizzas).

Spring Auto REST Docs + Spring Data REST? HATEOAS?

I really like the idea of using Javadoc comments for auto-generating REST Docs!
Huge parts of our REST API are automatically generated by Spring Data REST (by adding #RepositoryRestResource to Repositories). It would be great if REST Docs could also be generated for these - that would be a very high degree of automatition.
But unfortunately most "auto-"snippets are "empty" (e.g. auto-response-fields.adoc only contains a list of links[]-Attributes). I guess the reason could be that the REST Controllers are probably created dynamically by Spring Data REST. Currently I do not see how to re-use the Javadoc comments for them.
Is there any way to auto-generate REST Docs for such REST APIs that are provided by Spring Data REST?
It would even be helpful to manually tell Spring Auto REST Docs which classes are used in requests and responses instead of letting it discover it statically - is that possible?
And we also add HATEOAS "_links" to most response Resources (by providing ResourceProcessors as Beans). These links contain "title"s which are used by Spring REST Docs - if we list all of them with HypermediaDocumentation.linkWithRel(...). This is a bit redundant, and it would be nice if all the _links with "title"s could be processed automatically. (But this can be done by listing all of them in some extra code, so it is not as bad as with Spring Data REST.)
If necessary, I could also create an example project for what I am talking about.
Answer to the question whether one can manually tell Spring Auto REST Docs which classes to use for the documentation:
Spring Auto REST Docs allows to specify the request and response classes to use for the documentation. This can be done with requestBodyAsType and responseBodyAsType. In a test it looks like this:
.andDo(document("folderName",
requestFields().requestBodyAsType(Command.class),
responseFields().responseBodyAsType(CommandResult.class)));
This is from a test in the example project.

developing your own RESTful API

in developing your own RESTful API. does it necessarilly needed to use the four different http methods? GET POST PUT & DELETE?
i was checking the Twitter REST API and saw that they are just using the common methods (GET & POST)
Short answer: No
Long Answer:
REST is not specific to any one protocol, instead it is a style of programming. This is helpful to keep in mind because a RESTful endpoint should be thought of as having specific goals. Your job is to expose the web service in the most RESTful way possible.
When you're making a RESTful API you are not required to use any specific HTTP methods. Instead, REST can be embodied in this guiding principal: That you must expose individually identifiable resources; these resources must be manipulable in their exposed form. Oh and use self descriptive messages.
I'm sure this is a leaky explanation. Try to see, though, that REST becomes much more clear when you have the key idea in mind. RESTful practices expose resources in a way that allows us work with state in a sane manner. The technical details of how to implement a RESTful API can be learned by reading this:
http://en.wikipedia.org/wiki/Representational_state_transfer
After that, read something specific to your language. Fast track: find some RESTful API written in your language and clone it/play with it.
You should use whatever HTTP methods are appropriate for the operations you expose.
For example, you should accept HTTP DELETE requests only for operations that delete things.
If your API does not allow callers to delete things (eg, a traffic or weather API), you should not accept the DELETE verb.
Only if you are going to support those logical operations:
GET - fetch a resource
PUT - update (or create) a resource
DELETE - delete a resource
POST - several uses: create a new resource in a collection, perform some operation that will alter a resource in some one (as opposed to PUTting an entirely new version of a resource)
Most APIs will want to to provide those operations, and will use all those methods. And don't forget HEAD - fetch information about a resource (but not the resource itself).

WCF Rest - what are the best practices?

Just started my first WCF rest project and would like some help on what are the best practices for using REST.
I have seen a number of tutorials and there seems to be a number of ways to do things...for example if doing a POST, I have seen some tutorials which are setting HttpStatusCodes (OK/Errors etc), and other tutorials where they are just returning strings which contain result of the operation.
At the end of the day, there are 4 operations and surely there must be a guide that says if you are doing a GET, do it this way, etc and with a POST, do this...
Any help would be appreciated.
JD
UPDDATE
Use ASP.NET Web API.
OK I left the comment REST best practices: dont use WCF REST. Just avoid it like a plague and I feel like I have to explain it.
One of the fundamental flaws of the WCF is that it is concerned only with the Payload. For example Foo and Bar are the payloads here.
[OperationContract]
public Foo Do(Bar bar)
{
...
}
This is one of the tenants of WCF so that no matter what the transport is, we get the payload over to you.
But what it ignore is the context/envelope of the call which in many cases transport specific - so a lot of the context get's lost. In fact, HTTP's power lies in its context not payload and back in the earlier versions of WCF, there was no way to get the client's IP Address in netTcpBinding and WCF team were adamant that they cannot provide it. I cannot find the page now but remember reading the comments and the MS guys just said this is not supported.
Using WCF REST, you lose the flexibility of HTTP in expressing yourself clearly (and they had to budge it later) in terms of:
HTTP Status code
HTTP media types
ETag, ...
The new Web API, Glenn Block is working addresses this issue by encapsulating the payload in the context:
public HttpResponse<Foo> Do(HttpRequest<Bar> bar) // PSEUDOCODE
{
...
}
But to my test this is not perfect and I personally prefer to use frameworks such as Nancy or even plain ASP NET MVC to expose web API.
There are some basic rules when using the different HTTP verbs that come from the HTTP specification
GET: This is a pure read operation. Invocation must not cause state change in the service. The response to a GET may be delivered from cache (local, proxy, etc) depending on caching headers
DELETE: Used to delete a resource
There is sometimes some confusion around PUT and POST - which should be used when? To answer that you have to consider idempotency - whether the operation can be repeated without affecting service state - so for example setting a customer's name to a value can be repeated multiple times without further state change; however, if I am incrementing a customer's bank balance this cannot be safely be repeated without further state change on the service. The first is said to be idempotent the second is not
PUT: Non-delete state changes that are idempotent
POST: Non-delete state changes that are not idempotent
REST embraces HTTP - therefore failures should be communicated using HTTP status codes. 200 for success, 201 for creation and the service should return a URI for the new resource using the HTTP location header, 4xx are failures due to the nature of the client request (so can be fixed by the client changing what they are doing), 5xx are server errors that can only be resolved server side
There's something missing here that needs to be said.
WCF Rest may not be able to provide all functionality of REST protocol, but it is able to facilitate REST protocol for existing WCF services. So if you decide to provide some sort of REST support on top of the current SOAP/Named pipe protocol, it's the way to go if the ROI is low.
Hand rolling full blown REST protocol maybe ideal, but not always economical. In 90% of my projects, REST api is an afterthought. Wcf comes in quite handy in that regard.