1

I am trying to explore and understand RESTful approach to things. I've read that the interface be should not be contractual. That is what I get from HATEOAS.

But surely there must exist some contracts between a client and a server in the communication. So a server returns a resource and possible actions defined for it as links. Example response to GET account/12345 (taken from the linked wiki):

HTTP/1.1 200 OK
Content-Type: application/xml
Content-Length: ...

<?xml version="1.0"?>
<account>
   <account_number>12345</account_number>
   <balance currency="usd">100.00</balance>
   <link rel="deposit" href="http://somebank.org/account/12345/deposit" />
   <link rel="withdraw" href="http://somebank.org/account/12345/withdraw" /> 
   <link rel="transfer" href="http://somebank.org/account/12345/transfer" />
   <link rel="close" href="http://somebank.org/account/12345/close" />
 </account>

However, it lacks the full information for the communication. I.e. I know where should I withdraw the money but I don't exactly know how.

My question is where and how should it be defined? I think this boils down to how does one figure out the sub questions:

  1. How client should know which HTTP method is expected (e.g. POST vs PUT)? Or should the server also provide a "method" field for the link.
  2. Is it OK, to expect a certain scheme for the resource being sent as a content of request (I guess it would be a withdrawal request) or should the server communicate it somehow? E.g. by sending a template.

There still are contracts made. I am not sure how much should be communicated by the server, and how much is/can be expected of the client.

  • I don't know how the restafarians feel about this but you might want to look at RAML: raml.org I haven't had a chance to really try it out but it looks promising. – JimmyJames Mar 31 '16 at 13:28
3

Basically, one key point in REST architectural style is the self-descriptive message aspect.

What you call "contract", i call it content type (or media type). If both client and server agree on the content type (i.e. content negotiation), they agree on the semantics on the message. For example with xHTML content type, a client know that a <p> </p> will contains text that is related to a paragraph, for </a> it will have an attribute href containing the URL, etc...

In your case, it the same things. One media type could define that a <link> tag must contains an attribute method that is either PUT, POST, DELETE, GET, ...

And actually this type of media type exists, they are called hypermedia formats. One example is Hydra: http://www.hydra-cg.com/ that is based on JSON-LD.

You could also define in a media type what parameters is expected when there is a link that supports a method POST or PUT. Hydra does that also.

A client should not rely on out of band knowledges when interacting with REST resources: messages sent by a server must contains all informations for the client to process it.

In 99% of API, you will see that it's not. Maybe because there is a tradeoff with performance (vs scalability ? that's an open question ;-) !): messages with additional informations involves heavier communications. But also because there is not a need for that. Traditionnal REST API have documentation, for example with a documentation page on a website explaining how to deal with the API. That's typically out of band knowledge.

EDIT: related to other answers: RAML, Swagger, Blueprint are also out of band knowledges. But if it's ok for you to use one of them (i mean: it meets your requirements), go for it!

  • (1) Self-describing is a relative term, you know. (2) "messages sent [...] must contain all informations [...] to process it" - True "In 99% of API, you will see that it's not" True as well. One might add that Roy Fielding never proposed REST as the ultimative solution to all problems, quite the opposite. Unfortunately, these days countless square pegs are put in round holes because square is declared to be the new round. – JensG Mar 31 '16 at 13:36
  • 1
    I agree. Just one additional information: REST has been inferred from the architecture of the web, in the context of a PhD thesis. A lot of people occult these two points (inferred from the web, and in the context of a thesis). And that's why, like you said, a lot of people consider REST as the ultimative solution i guess. – AilurusFulgens Apr 1 '16 at 8:54
2

Note: I am not a restafarian. I'm stubbornly pragmatic about things so if you are looking for the dogmatic 'true' REST answer, you might not get it from me.

The very simple answer to your question is that the OPTIONS verb is meant to be used to describe the methods that are available at a given resource. However this isn't universally accepted. Unfortunately, aside from OPTIONS, I don't think this is a standard REST approach to this so your clients will require some knowledge about how your interface works even if you host it i.e. they will need to know that address.

Personally, I think the obsession with building APIs that will work without any sort of human readable documentation and intervention is a bit of a fool's errand. Even when it has been done with some success (e.g. USB) it creates a ton of attack vectors for bad actors to take advantage of.

1

I can recommend you to use swagger.io to define a contract. The used Open API approach is held general so you keep as universal as possible with your backend.

The swagger specs are machine readable and the swagger tool-chain is very comfortable for both sides on client side and server side. You can also put the definition file under version control of your software so it always fits to your current software revision.

Furthermore I agree on the statement that the most crucial part about APIs is to make it easy for developers to implement them. And as for every other software the (also human-readable) documentation is deciding to that.

Regarding your 2nd question it is common practice to make use of OPTION requests - see https://stackoverflow.com/questions/11926908/how-to-respond-to-an-http-options-request

  • 1
    Could you please elaborate on the concepts used in your suggestions? The OP wants to understand how things work (OP: I am trying to explore and understand RESTful approach to things.) – Miguel van de Laar Mar 31 '16 at 13:51
0

I am trying to explore and understand RESTful approach to things. I've read that the interface be should not be contractual. That is what I get from HATEOAS.

But surely there must exist some contracts between a client and a server in the communication.

There is. Both the client and server understand the HTTP protocol, which defines how to transfer representations of resources from client to server and vice versa. And both client and server understand the representation format (aka Content Type) that the resource is in.

A very important concept to remember when discussing REST is the State Transfer part of Representation State Transfer. The client and server are passing around state changes in the representation of the resource. The client is not telling the server how to change a resource. It is changing the resource, and then telling the server "Hey, here is the new state for this resource"

How client should know which HTTP method is expected (e.g. POST vs PUT)? Or should the server also provide a "method" field for the link.

Most of the time this is not necessary. GET, DELETE and PUT all already make sense without needing to know the content type of the resource's representation. Whether you are GETting a topographical map of Utah or a download of the latest Doom game, "GET some resources at this URL" makes perfect sense. Same with DELETE (delete the the resource at this URL) and PUT (put this representation of the resource at this URL).

POST on the other hand was left vague on purpose. POST simply means post some data to this resource. What you expect that resource to do with this data is left for the client and server to figure out via at the level of the content type, rather than the communication protocol level. HTTP just cares that some data was POSTed to the resource.

A good example would be the HTML content type which defines the <form> tag which takes a method parameter which tells the web browser to POST data to a resource. Because both the web browser (the client) and the web server (the server) understand the HTML form convention it is clear what happens in this context. Every web browser in the world understands that when you see a form tag with a method set to POST you are posting data to that resource.

So this should be something the client and server understand about each other because they are both using a content type that uses POSTing data to a resource to achieve something.

Just a word on content types. JSON and XML aren't content types. They are data exchange formats that can be used for content types. A lot of people don't realise this, and ponder how can the client know what to do with the data the server sent them if the "Content Type" is just JSON. The answer is it can't, you need more than this. You need a content type that the client actually understands how to work with. That can use JSON for data transfer, but it needs to be more, in the same way that if you sent a HTMl document to a web browser and just said "hey, its ASCII text, figure it out" the web browser would have no clue what to do with it. Tell it that it is a HTML document and it knows exactly what to do with it.

Is it OK, to expect a certain scheme for the resource being sent as a content of request (I guess it would be a withdrawal request) or should the server communicate it somehow?

Its not just OK, it is pretty much mandatory. Both the client and the server need to know that the resource is an Bank Account represented in the SuperBankAccountDataFormat_v1.3 in order to understand how to work with the resource. You do this by telling the client the content type of the resource when it fetches it (in the same way a web server tells a web browser "Hey this is a HTML 5 document" when it ```GET``s a website)

The important point though is that none of the specifics of this format is in the communication protocol (e.g. HTTP 1.1) or in the URL scheme. A web server can send a modern browser a HTML 5 document using the HTTP 1.1 protocol despite HTML 5 not existing when HTTP 1.1 was made. And nothing has to change with the HTTP 1.1. protocol for a server to send a client a HTML 5 document.

Think of REST as the postman. The postman doesn't care what is in the box he is delivering. He (or she) accepts certain generic commands "Please deliver this parcel to this address" without ever knowing or caring if the person he is delivering the parcel to will understand what is in the box. The postman doesn't care if the box says "Auto parts" or if it says "Flowers" or if it says "Census form"

You get the census form, fill it out, and post it back to the Census department because both you and them understand what a census form is and what you are supposed to do with it and how to send it back to the Census department. But the postman doesn't care, and neither do you or the postman need to know what address to send the form back to, its on the form on the back page at the bottom as defined by the Census Form v1.0 specification that you understand.

Next year the address to return the census form can completely change. You don't care, you just send it back to what ever address the form tells you to. And the postman certainly doesn't care, they just send what you tell them to send to what ever address you tell them to.

That is what they mean by "the interface should not be contractional"

Going beyond that the year after next year the census form can completely change, with a completely new way to post back the form, that the Census department has to spend ages educating everyone about (the clients) the changes. The postman still doesn't care, the package now just says "Census form 2.0". This is why you need a new web browser to use all the cool features of HTML 5, but you still use bog standard HTTP 1.1 to communicate with websites.

So what does this mean in practical terms. If means the client should know how to handle the SuperBankAccountDataFormat_v1.3 and know from understanding that content type if something needs to be POSTed to a resource in the same way that a web browser understands HTML forms and knows when to POST something to a resource.

Hope that helps clarify some of the concepts.

0

Maybe I can add something to the conversation by stating my interpretation about how 'stateless' in REST can be well matched with readable.

When you ask, regarding one of the properties in one of your resource:

However, it lacks the full information for the communication. I.e. I know where should I withdraw the money but I don't exactly know how.

You can use HATEOS as you do but leveraging the power given by nested data structures (in XML or JSON). In JSON for example:

{
...
"withdraw": {
    "uri": "../withdraw",
    "method": "POST"
    },
...
}

This way the content is self-describing to a reader and he/she can create a client for your HATEOS uri to be followed with the proper method.

As stated elsewhere, it can also be used a metadata framework to be fed to the client, like HYDRA, which describes semantics for different resources in the API.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.