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.
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.