We are creating a two REST APIs
To do a template processing
To convert the HTML to PDF.
The template in 1, and the HTML in 2 can be provided along with the request body as well as present in a persistent location.
What is the best way to design the REST contract? Are these good ways to design it? Or are there better suggestions for this?
For Scenario 1
PUT - /template/process; include the Template markup in the body
PUT - /templates/{id}/process; there is a template with that {id} in a persistent location
For Scenario 2
PUT /html2pdf/convert with the HTML markup mentioned in the body
PUT html2pdf/{id}/convert with the resource HTML with the {id} available in a persistent location.
Is it a good idea to have the action too (process, convert in this case) in the URL? Or is it possible to give a meaning to it using the HTTP verb itself?
The use of PUT is suspicious. Remember, part of the point of REST is that we have a uniform interface - everybody understands HTTP messages the same way.
In particular, PUT is the method token that we use if we are uploading a web page to a server. The semantics of the request are analogous to "save" or "upsert" - you are telling the server that you want to make the server's copy of the target resource look like your copy of the target resource.
POST serves many useful purposes in HTTP, including the general purpose of “this action isn’t worth standardizing.” -- Fielding, 2009
What we want in a lot of cases similar to yours is an effectively read only request with a payload. As of early 2021, the registry of HTTP methods doesn't have a good match for that case - the closest options are SEARCH and REPORT, but both of those carry WebDAV baggage.
But in late 2020, the HTTP WG adopted the draft-snell-search-method spec:
the scope of work is to define a method that has the behavior of a GET with a body -- Tommy Pauly
So when that work is done, we'll have another standard method to consider for this type of problem.
Is it a good idea to have the action too in the URL?
It's a neutral idea.
URL/URI are identifiers; they are (from the point of view of the protocol) semantically opaque. So long as your spelling conventions are consistent with the production rules defined in RFC 3986, you can do as you like.
Any HTTP compliant component should understand that the semantics of the message are defined my the method token, not by the target-uri.
Resources are generalization of documents. The URI is, effectively, the "name" of the document. You can use any name for your documents that makes sense to your human beings (operators looking at access logs, tech writers trying to document your app, other developers trying to read those documents, etc).
Related
I read that HATEOAS links are the one that separates a REST API from a normal http API. In that case, does REST need a separate name? I wonder what all this hype about REST API is about. It seems to be just a http method with one extra rule in the response.
Q) What other differences exist?
I read that HATEOAS links are the one that separates a REST API from a normal http API.
That's probably a little bit of an understatement. When Leonard Richardson (2008) described the "technology stack" of the web, he listed:
URI
HTTP
HTML
A way of exploring the latter is to consider how HTML, as a media type, differs from a text document with URI in it. To my mind, the key element is links and forms -- standardized ways of encoding into the representation the semantics of a URI (this is a link to another page, this is an embedded image, this is an embedded script, this is a form...).
Mike Admundsen, 2010:
Hypermedia Types are MIME media types that contain native hyper-linking semantics that induce application flow. For example, HTML is a hypermedia type; XML is not.
Atom Syndication/Atom Publishing is a good demonstration for defining a REST API.
Can you throw some light on what REST actually means and how it differs from normal http?
Have you noticed that websites don't normally use plain text for the representations of the information that they share? It's something of a dead end -- raw text doesn't have any hypermedia semantics built into it, so a generic client can't do anything more interesting than search for sequences that might be URI.
On the other hand, with HTML we have link semantics: we can include references to images, to style sheets, to scripts, as well as linking to other documents. We can describe forms, that allow the creation of parameterized HTTP requests.
Additionally, that means that if some relation shouldn't be used by the client, the server can easily change the representation to remove the link.
Furthermore, the use of the hypermedia representation allows the server to use a richer description of which request message should be sent by the client.
Consider, for example, Google. They can use the form to control whether search requests use GET or POST. They can remove the "I Feel Lucky" option, or arrange that it redirects to the main experience. They can embed additional information in to the fields of the form, to track what is going on. They can choose which URI targets are used in the search results, directing the client to send to Google another request which gets redirected to the actual target, with additional meta data embedded in the query parameters, all without requiring any special coordination with the client used.
For further discussion, see Leonard Richardson's slide deck from QCon 2008, or Phil Sturgeon's REST and Hypermedia in 2019.
Does n't think the client need to read the documentation if the HATEOAS link is a POST API? HATEOAS links will only guide you to an API but will not throw any light on how its request body needs to be filled....GET won't have request body. So, not much or a problem. but POST API?
Sort of - here's Fielding writing in 2008:
REST doesn’t eliminate the need for a clue. What REST does is concentrate that need for prior knowledge into readily standardizable forms.
On the web, the common use case is agents assisting human beings; the humans can resolve certain ambiguities on their own. The result is a separation of responsibilities; the humans decode the domain specific semantics of the messages, the clients determine the right way to describe an interaction as an HTTP request.
If we want to easily replace the human with a machine, then we'll need to invest extra design capital in a message schema that expresses the domain specific semantics as clearly as we express the plumbing.
To me, REST is an ideology you want to aim for if you have a system that should last for years to come which has the freedom to evolve freely without breaking stuff on parts you can't control. This is very similar to the Web where a server can't control browsers directly though browsers are able to cooperate with any changes done to Web site representations returned by the server.
I read that HATEOAS links are the one that separates a REST API from a normal http API. In that case, does REST need a separate name?
REST does basically what its name implies, it transfers the state of a resource representation. If so, we should come up with a new name for such "REST" APIs that are truly RPC in the back, to avoid confusion.
If you read through the Richardson Maturity Model (RMM) you might fall under the impression that links or hypermedia controls as Fowler named it, which are mandatory at Level 3, are the feature that separates REST from normal HTTP interaction. However, Level 3 is just not enough to reach the ultimate goal of decoupling.
Most so called "REST APIs" do put a lot of design effort into pretty URIs in a way to express meaning of the target resource to client developer. They come up with fancy documentation generated by their tooling support, such as Swagger or similar stuff, which the client developer has to follow stringent or they wont be able to interact with their API. Such APIs are RPC though. You won't be able to point the same client that interacts with API A to point to API B now and still work out of the box as they might use completely different endpoints and return different types of data for almost the same named resource endpoint. A client that is attempting to use a bit more of dynamic behavior might learn the type from parsing the endpoint and expect a URI such as .../api/users to return users, when all of a sudden now the API changed its URI structure to something like .../api/entities. What would happen now? Most of these clients would break, a clear hint that the whole interaction model doesn't follow the one outline by a REST architecture.
REST puts emphasis on link relation names that should give clients a stable way of learning the URIs intent by allowing a URI to actually change over time. A URI basically is attached to a link relation name and basically represents an affordance, something that is clear what it does. I.e. the affordance of a button could be that you can press it and something would happen as a result. Or the affordance of a light switch would be that a light goes on or off depending on the toggled state of the light switch.
Link relation names now express such an affordance and are a text-based way to represent something like a trash bin or pencil symbol next to table entry on a Web page were you might figure out that on clicking one will delete an entry from the table while the other symbol allows to edit that entry. Such link relation names should be either standardized, use widely accepted ontologies or use custom link-relation extensions as outlined by RFC 8288 (Web Linking)
It is important to note however, that a URI is just a URI which should not convey a semantic meaning to a client. This does not mean that a URI can't have a semantic meaning to the server or API, but a client should not attempt to deduce one from the URI itself. This is what the link-relation name is for, which provides the infrequently changing part of that relation. An endpoint might be referenced by multiple, different URIs, some of which might use different query parameters used for filtering. According to Fielding each of these URIs represent different resources:
The definition of resource in REST is based on a simple premise: identifiers should change as infrequently as possible. Because the Web uses embedded identifiers rather than link servers, authors need an identifier that closely matches the semantics they intend by a hypermedia reference, allowing the reference to remain static even though the result of accessing that reference may change over time. REST accomplishes this by defining a resource to be the semantics of what the author intends to identify, rather than the value corresponding to those semantics at the time the reference is created. It is then left to the author to ensure that the identifier chosen for a reference does indeed identify the intended semantics. (Source 6.2.1)
As URIs are used for caching results, they basically represent the keys used for caching the response payload. As such, it gets obvious that on adding additional query parameters to URIs used in GET requests, you end up bypassing caches as the key is not stored in the cache yet and therefore get the result of a different resource, even though it might be identical (also in response representation) as the URI without that additional parameter.
I wonder what all this hype about REST API is about. It seems to be just a http method with one extra rule in the response.
In short, this is what those self- or marketing-termed pseudo "REST APIs" do convey and many people seem to understand.
The hype for "REST" arose from the inconveniences put onto developers on interacting with other interop-solutions such as Corba, RMI or SOAP where often partly-commercial third-party libraries and frameworks had to be used in order to interact with such systems. Most languages supported HTTP both as client and server out of the box removing the requirement for external libraries or frameworks per se. In addition to that, RPC based solution usually require certain stub- or skeleton-classes to be generated first, which was usually done by the build pipeline automatically. Upon updates of the IDL, such as WSDL linking or including XSD schemata, the whole stub-generation needed to be redone and the whole code needed to looked through in order to spot whether a breaking change was added or not. Usually no obvious changelog was available which made changing or updating such stuff a pain in the ...
In those pseudo "REST" APIs plain JSON is now pretty much the de facto standard, avoiding the step of generating stub classes and the hazzle of analyzing the own code to see whether some of the forced changes had a negative impact on the system. Most of those APIs use some sort of URI based versioning allowing a developer to see based on the URI whether something breaking was introduced or not, mimicking some kind of semantic versioning.
The problem with those solution though is, that not the response representation format itself is versioned but the whole API itself leading to common issues when only a change on a part of the API should be introduced as now the whole API's version needs to be bumped. In addition to that, to URIs such as .../api/v1/users/1234 and .../api/v2/users/1234 may represent the same user and thus the same resource though are in fact different by nature as the URI is different.
Q) What other differences exist?
While REST is just an architecture model that can't force you to implement it stringent, you simply will not benefit from its properties if you ignore some of its constraints. As mentioned above, HATEOAS support is therefore not yet enough to really decouple all clients from an API and thus allow to benefit from the REST architecture.
RMM unfortunately does not talk about media types at all. A media type basically specifies how a received payload should be processed and defines the semantics and constraints of each of the elements used within that payload. I.e. if you look at text/html registered in IANA's media type registry, you can see that it points to the published specification, which always references the most recent version of HTML. HTML is designed in a way to stay backwards compatible so no special versioning stuff is required.
HTML provides, IMO, two important things:
semi-structured content
form support
The former one allows to structure data, giving certain segments or elements the possibility to express different semantics defined in the media type. I.e. a browser will handle an image differently than a div element or an article element. A crawler might favor links and content contained in an article element and ignore script and image elements completely. Based on the existence or absence of certain elements even certain processing differences may occur.
Including support for forms is a very important thing in REST actually as this is the feature which allows a server to teach a client on what a server needs as input. Most so called "REST APIs" just force a developer to go through their documentation, which might be outdated, incorrect or incomplete, and send data to a predefined endpoint according to the documentation. In case of outdated or incomplete documentation, how should a client ever be able to send data to the server? Moreover, a server might never be able to change as basically the documentation is now the truth and the API has to align with the documentation.
Unfortunately, form-support is still a bit in its infancy. Besides HTML, which provides <form>...</form>, you have a couple of JSON based form attempts such as hal-forms, halo-json (halform), Ion or hydra. None of these have yet wide library or framework support yet as some of these form representations still have not finalized their specification on how to support forms more effectively.
Other media-types, unfortunately, might not use semi-structured content or provide support for forms that teach a client on the needs of a server, though they are still valuable to REST in general. First, through Web linking link support can be added to media types that do not naturally support those. Second, the data itself does not really need to be text-based at all in order for an application to use it further. I.e. pictures an videos usually are encoded and byte based anyways still a client can present them to users.
The main point about media-types though is, as Fielding already pointed out in one of his cited blog posts, is, that representations shouldn't be confused with types. Fielding stated that:
A REST API should never have “typed” resources that are significant to the client. Specification authors may use resource types for describing server implementation behind the interface, but those types must be irrelevant and invisible to the client. The only types that are significant to a client are the current representation’s media type and standardized relation names.
Jørn Wildt explained in an excellent blog post what a "typed" resource is and why a REST architecture shouldn't use such types. Basically, to sum the blog post up, a client expecting a ../api/users endpoint to return a pre-assumed data payload might break if the server adds additional, unexpected fields, renames existing fields or leave out expected fields. This coupling can be avoided by using simple content-type negotiation where a client informs a server on which capabilities the client supports and the client will chose the representation that best fits the target resource. If the server can't support the client with a representation the client supports the server should respond with a failure (or a default representation) the client might log to inform the user.
This in essence is exactly what the name REST stands for, the transfer of a resource's state representation where the representation may differ depending on the representation format defined by the selected media type. While HATEOAS may be one of the most obvious changes between REST and a non-REST based HTTP solution, this for sure is not the only factor that makes up a payload in REST. I hope I could shed some light on the decoupling intention and that a server should teach clients what the server expects through forms and that the affordance of URIs is captured by link-relation names. All these tiny aspects in sum make up REST, and you will only benefit from REST, unfortunately, if you respect all of its constraints and not only those that are either easy to obtain or what you have the mood for implementing.
Suppose I am developing a RESTful API with a container of items:
/items
and individual items would be identified by URIs like:
/items/{id}
What is the best way to describe the fact that new items can be created by PUT request under the HATEOAS constraint, i.e. where the client would specify {id}?
PUT /items/1234
What is the best way to describe the fact that new items can be created by PUT request under the HATEOAS constraint, i.e. where the client would specify {id}?
How would you do that on a web site?
You'd probably have some resource that provides a form; and the form would include the id, and possibly other interesting things. The client would fill in the form (using semantic hints to interpret which information belonged in each field). When the form is submitted, the HTML processing rules would encode the form values into an application/x-www-url-formencoded representation, which would become the query part of the target-url. The server would review the payload, compute the appropriate target URI, and send a redirect response to the client.
The client can then GET/PUT/POST etc to the resource recommended by the server.
If you squint a little bit, you may see that the form is playing a role very similar to a URI Template.
So the basic sketch is pretty straight forward: the client and server have to agree on a media type that describes the template (and its semantic meaning), and the corresponding processing rules.
Here's the bad news: that bit is hard. In the world-wide-web, HTML is doing a ton of the heavy lifting for us. If your API is also using html representations of its resources, then you can piggy back on the forms that are already there. But HTML has kind of fallen out of vogue.
In the API space, JSON has a lot of mind share, and there are a few media types that use it as a starting point. Sookocheff's 2014 survey is five years old now, but will give you some idea of what is out there.
I've heard about the conception RESTFul for a long time but I always can't understand it clearly.
I've read the links below:
What are RESTful web services?
What exactly is RESTful programming?
As my understanding, RESTFul means that the URL shouldn't contain any verb, meaning that an URL represents an unique resource. And also, the method GET shouldn't modify any resource and we should use POST to do so.
But I still have a question.
For example, if we want to search a user by his name, we can design the URL like this:
www.example.com/user?name=test
Or like this:
www.example.com/user/name/test
Can you tell me which one is RESTFul?
When you are using rest - you are accessing resources through URI's and you can set actions on these resources through the HTTP request types.
There are different parameters that you can pass through REST request , there can be resource identifiers (That are usually passed through the URI - in your case the www.example.com/user/name/test is more restfull) or things like filters when you want to search, for example www.example.com/user/?age=....
In this post you can find more about best practices in passing parameters in rest:
REST API Best practices: Where to put parameters?
REST, to start with, is not a protocol but just an architectural style that when followed correctly decouples clients from server APIs and thus make them tolerant to changes done on the serverside. It should therefore be regarded as a design approach for distributed systems.
The difference between a protocol and an architectural style is simply that the former one defines a rule set a server or client has to follow. It should be defined as precise as possible to reduce ambiguity and thus reduce the likelihood of incompatible implementations by different vendors. The latter one just contains suggestions how to design the overall application and/or message flow and outlining the benefits one gains by adhering to the design.
By that definition, REST is a generalization of the interaction style used for browsing Web content. A Web browser is able to make use of multiple protocols such as HTTP, FTP, SMTP, IMAP, ... and different flavors of it while remaining independant of any server specific implementation though being capable of interacting with it as the communication is done according to the rules of the protocol used. REST does follow this approach by building up on the same protocols (most often just HTTP) which an application implementing the RESTful architeturce approach should adhere to as well to stay compatible with other users of that protocol.
Similar to a Web browser, which does not care whether the URI string contains any semantical structure, REST doesn't care how the URI is designed or if the resource is named after a verb either. Both will use the URI just to invoke a resource on the server providing the resource. A RESTful client should thus not expect a certain URI to return a certain type (= typed resources). Though how will a client know what an invoked URI will return? The keywords here are content-negotiation and media-types.
The format exchanged by both, Web browser and REST, is negotiated between client and server. While for typical Web browsers the representation is probably one of the HTML variants (i.e. XHTML, HTML 5, ...) it is not limited to it. Your browser is probably capable of processing other media types as well, i.e. pictures, videos, PDF, ... As REST is just a generalization of this idea it also should not limit itself to just XML or JSON.
Media types are thus some kind of guildlines of how to process and interpret data received in a representation format outlined by the media type. It should define the syntax and semantics of a received payload i.e. like text/html, which defines that a received representation will have a case-insensitive <html token (<xhtml in case of XHTML) near the beginning of the content and that fragment identifiers (# character in URIs) are according to URI semantics and that certain tags like A, IMG or others may define a name attribute which act as a target for anchors. It may also define a more thorough description of the syntax and how to interpret it like in case of text/vcard (vCard) (or one of its variants like application/vcard+json (jCard) or application/vcard+xml (xCard)).
As media types are one of the most important parts of the RESTful design, most effort has to be put into its creation. A client that can't deduct the next possible actions from the media type needs some out-of-band information which often is hardcoded into the client and thus couples it tightly to the API itself. If the API will change in future, the chances that the client will stop working once the changes are applied on the server are fairly high (depending on the changes).
I hope I could shed some light on the idea behind REST and that the design of URI is not of relevance to a true RESTful client/API as the client might deduct what to do with that URI based on some relation name returned for the URI and the media-type which might state that a relation name such as order can be invoked to trigger a new order with the API rather than having the client to analyze something like http://some.server.com/api/order/product/1234 or http:/some.server.com/ajfajd/fj/afja.
Further information and reasons why RESTful APIs should follow the design closely can be found in Roy Fielding famous blog post which explains some of the constraints an API should adhere to if it follows the RESTful approach.
REST resource is a noun, no notion of behavior should be in the uri, we use verbs to indicate action we are doing. Basically there are only two types of resources: Instance and Collections. So good practise is to use plurals in the uri: users instead of user:
www.example.com/users GET - fetch collection of all users
www.example.com/users/1 GET - fetch instance of a concrete user
www.example.com/users POST - create of a new user
etc.
REST is not a strict standard (but a list of 6 constraints) says nothing about how search feature should be implemented. But definetely your first option /users?name=test seems preferable for me: tt is straightforward and this is a huge benefit.
As alternative you may want to investigate OData protocol - it is a standard to make queryable apis. OData-like solution would be:
/users?$filter=name eq 'test'
Also Facebook APIs is a good source for inspiration.
Hope this helps
In terms of good REST API design, is it a good idea to return id of the newly created resource? Say I have an API:
api/resource POST
I've seen some guru who has such API to return empty json and insert the URI into with Location header in response. I think returning
{ 'id': '1000' }
so that the caller can do something right away with it is better. Save one more round-trip to the server. What's the problem with this approach if any?
As requested I reposted my comment as an answer and added some more details to be worth an answer at all.
The common approach for creating new resources via HTTP POST method is to return a 201 Created status code. The response furthermore should therefore contain the current state of the resource as entity body and a location header pointing to the URI the resource can be found. Not doing so, may break some clients and prevent their correct interaction with the service. Clients here may be browsers, tailor made "languageOfYourChoice" applications or even other services.
In an ideal RESTful world, the client is only aware of one single URI to start with (like the entrance URI of the service, f.e. http://service.company.com/). The response of an invocation of that URI should return a document which can be understood by the client and contains further links the client can use if interested. This concept is similar to the big brother HTML and similar web resources used everyday by humans where links can be used to move from the start page to sub-pages or even external resources or other hyper-media resources. REST is just an abstraction and a generalization of the Web thing.
Although not part of the actual question and this is rather opinion based, there is an ongoing discussion among RESTful devolopers regarding the usefulness of common vs. specialized document types (mime types, ...). I think that there should be a standardized common REST-aware format for JSON, XML, ... Just plain application/json is not enough as this does not define how links and schemas have to be included. Even HAL is not descriptive enough (IMO) regarding executable actions on URIs and what document formats to expect on invoking those URIs and what arguments needed to be passed to the service.
Document formats (a.k.a media types) are one of the core concepts of Roy Fieldings acronym HATEOAS. Clients should not need any prior knowledge other than the entrance point and the media types understood by the clients (thus the previous paragraph). The possible actions are all described through following the HTTP protocol specification and knowing what the respective media types express.
Therefore, returning a URI instead of an ID has a couple of advantages:
URIs are per se unique, different vendors though may have identical IDs
Client needs no knowledge on how the server is creating those URIs, the server on the other hand can provide them almost for free. Returning a product ID of 1234 has almost infintly ways to be combined in an URI by the client - the client therefore needs special knowledge on how to create the URI so that the server is actually able to process the request correctly.
The server can move resources without the need of clients to change as clients (in an ideal RESTful world) would retrieve the URI of the resource within a further request' response. The client therefore needs only the semantical knowledge what the returned field acutally "means"
I was doing some reading on REST this morning and I came across the HATEOAS principle ("hypermedia as the engine of application state").
Quoting the REST Wikipedia page:
Clients make state transitions only through actions that are dynamically identified within hypermedia by the server (e.g. by hyperlinks within hypertext). Except for simple fixed entry points to the application, a client does not assume that any particular actions will be available for any particular resources beyond those described in representations previously received from the server.
And Roy Fielding's blog:
...if the engine of application state (and hence the API) is not being driven by hypertext, then it cannot be RESTful and cannot be a REST API. Period.
I read this as: The client may only request state changes based on the actions made available from the body of the response from the server (the hypertext).
In an HTML world, this makes perfect sense. The client should only be able to request state changes (new actions/pages) based on the links made available to them through the hypertext (HTML).
When the resource is represented in other ways - such as JSON, XML, YAML etc. This is not so apparent.
Let's take an example "REST" JSON API:
I create a new resource (a new comment for example) by sending a POST request to
/comments.json? # with params...
The server responds with:
# Headers
HTTP/1.1 201 Created
Location: http://example.com/comments/3
Content-Type: application/json; charset=utf-8
... Etc.
# Body
{"id":3,"name":"Bodacious","body":"An awesome comment","post_id":"1"}
I know that I can now access this comment at the URI returned in the header: http://example.com/comments/3.json
When I visit http://example.com/comments/3.json I see:
{"id":3,"name":"Bodacious","body":"An awesome comment","post_id":"1"}
Suppose the API's documentation tells me that I can delete this comment by sending a DELETE request to the same URI. This is fairly common amongst "REST" APIs.
However:
The response from the server at GET http://example.com/comments/3.json doesn't tell me anything about being able to delete the comment by sending a DELETE request. All it shows me is the resource.
That I can also DELETE a comment with the same URL is something the client knows through out-of-band information (the documentation) and is not discovered and driven by the response from the server.
Here, the client is assuming that the DELETE action (and possible others) are available for this resource and this information has not been previously received from the server.
Have I misunderstood HATEOAS or am I right in saying than an API matching the above description would not, in the strict sense, be a REST API?
I'm aware 100% adherence to REST is not always possible or the most pragmatic way to go. I've posted this question purely to satisfy my own curiosity about the theory behind REST, not for advice on real world best-practice.
Jon Moore gave an excellent talk in Nov 2010 about the nuts and bolts of writing a truly RESTful (i.e. HATEOAS supporting) API and client. In the first part, he suggests the JSON is not a proper media type for REST because it lacks a commonly understood way of representing links and supported HTTP methods. He argues that good ol' XHTML is actually perfect for this since tools for parsing it (i.e. XPath) are readily available, it supports forms (think GET link templating and PUT, POST, and DELETE methods) and has a well-understood way of identifying hyperlinks, plus some other advantages mainly achieved through the ability to use the API with any standard web browser (eases the jobs for devs, QA, and support staff.)
The argument I'd always made prior to watching his talk is that JSON is so much lower of bandwidth consumer than any *ML language e.g. XML, HTML, XHTML. But by using terse XHTML where possible such as relative links instead of absolute ones (hinted at but not so evident in the example he uses throughout his talk), and by using gzip compression, this argument loses a lot of weight.
I realize efforts such as JSON-Schema and other RFC's are underway to try standardizing things in JSON, but in the meantime, Moore's talk convinced me to give XHTML a try.
JSON as a hypermedia type doesn't define an identifier for application flow. HTML has link and form tag that that guide a user through a process.
If your application is only concerned with PUT, POST, DELETE, GET on a resource, your documentation could easily explain that.
However, if it were more complicated like adding a rebuttal to a comment and that rebuttal was a different resource then the comment you would need hypermedia type that would guide the consumer create the rebuttal.
You could use HTML/XHTML, Create your own 'bodacious+json' or use something else. Here are all the different media types
http://www.iana.org/assignments/media-types/index.html
I'm using HAL and it has a pretty active group. Here are links to it.
http://www.iana.org/assignments/media-types/application/vnd.hal+json
http://stateless.co/hal_specification.html
The book "Building Hypermedia APIs with HTML5 and Node" goes deep into hypermedia and media types. It shows how to create a media type for a specific or general purpose in XML or JSON.
A RESTful solution would be to utilise the Allow-header to inform the client of the available methods/actions:
> GET /posts/1/comments/1 HTTP/1.1
> Content-Type: application/json
>
< HTTP/1.1 200 OK
< Allow: HEAD, GET, DELETE
< Content-Type: application/json
<
< {
< "name": "Bodacious",
< "body": "An awesome comment",
< "id": "1",
< "uri": "/posts/1/comments/1"
< }
Fielding's dissertation sets out two types of metadata: representation metadata; and resource metadata.
The Allow-header in HTTP/1.1 functions as resource metadata because it describes some property of a resource; i.e. the methods it allows.
By fully utilising the features provided by HTTP you eliminate the need for any out-of-bound information, and become more RESTful.
HATEOAS in a simple HTTP context describes how a client can navigate from one representation to another by following URIs using GET, whilst the Allow-header informs the client of the additional methods supported by the resource that generated the representation.
It's a neat design; the client asked for a representation, and additionally received a whole bunch of extra metadata about the resource that enables the efficient requesting of further representations.
I think the quote you have from the Wikipedia REST page is somewhat misleading in its choice of words and hasn't helped here (N.B. It has been improved since this question was asked).
All HTTP clients have to assume that a GET-method is likely to be available for the majority of resources. They do this because support for GET and HEAD are the minimum requirements for an HTTP/1.1 server. Without this assumption the web would not function. If a client can assume GET is available, then why not make other assumptions about common methods such as DELETE, or POST?
REST and HTTP aim to leverage the power of making assumptions about a basic set of methods in order to reduce the overall volume of requests on a network; if a request succeeds there's no need for further communication; but if a request fails with status '405 Method Not Allowed', then the client is immediately in receipt of the requests that could succeed via the Allow-header:
> ANNIHILATE /posts/1/comments/1 HTTP/1.1
> Content-Type: application/json
>
< HTTP/1.1 405 Method Not Allowed
< Allow: HEAD, GET, DELETE
< Content-Type: application/json
<
If the basic set of HTTP/1.1 methods aren't enough then you are free to define your own. However, it would be RESTful to solve problems using the available features of HTTP before defining new methods or putting metadata into the message-body.
A fully discoverable JSON API that doesn't require any out-of-band knowledge as you put it so succinctly:
"That I can also DELETE a comment with the same URL is something the client knows through out-of-band information (the documentation) and is not discovered and driven by the response from the server."
...is completely possible. It just requires a simple standard and a client that understands the standard. Check out hm-json and the hm-json Browser project:
https://bitbucket.org/ratfactor/hm-json-browser/
As you can see in the demo, absolutely no out-of-band documentation is needed - only one entry point URI from which all other resources and their HTTP methods can be discovered by browsing.
By the way, HAL as mentioned in suing's answer is very, very close to your hypothetical requirements for HATEOAS. It's a great standard and it has a lot of cool ideas like embedded resources, but it has no way of informing the client about all available HTTP methods such as DELETE for a given resource.
Another solid (and new as of May 2013) attempt at resolving HATEOAS for JSON can be found here:
JSON API: http://jsonapi.org/
The premise of your question contains an often misunderstood aspect of REST – that the API response body entity be responsible for not only communicating the representational state of the requested resource but for also communicating the over-all state of the application the resource belongs to. These two things - resource state and application state are not the same thing.
The response entity body by definition provides you the state of the resource at a point in time. But a single resource is only one of many that comprises an application. Application state is the combined states of all in scope related resources – at any point in time – from the perspective of the application consumer - human or machine. To deliver this 'application state' a level 3 REST API make possible HATEOAS.
Since Hypertext is what most people mean when referring to the 'Hyper'media in HATEOAS, the special power of hypertext is it's ability to link to other media. Further, since most experience hypertext via HTTP/HTML this tends to lead many to think hyperlinks are only possible via an anchor tag or link tag within the body of a response entity - but this is not so.
If the transport protocol is HTTP then application state can and should be communicated via headers. Specifically, one or more 'Link' HEADERS with a 'rel' attribute to provide semantics. The Link HEADER along with the ALLOW header are the HTTP mechanisms for communicating what the next possible state transitions are and how to go about accessing them.
If you decide to not use these built-in mechanisms than your options are to try and communicate the application state by 'piggy-backing' on your resource state communication channel i.e. the response body, which leads to trying to devise some form of additional specification into the design of the resource itself.
When this is done - 'piggy-backing'- many run into content-type issues because the response body has to be specified by a MIME/Content-type like XML or JSON which means figuring out how to implement the HATEOAS mechanisms via some custom content-type specific format like custom XML tags or key:value pairs of nested object. You can do this, many do - e.g. see json-api suggestion above, but again HTTP already provides mechanisms for this.
I think it goes to us as humans always thinking we have to see or be able to click on these links as in the normal web use-case but we are talking about APIs that I can only assume are being built not for human consumption but for machine consumption - right? The fact that headers - which are there by the way as part of the response - are not visible in most human interfaces to HTTP i.e. browsers is not an issue with REST but rather an implementation limitation of the HTTP Agents on the market.
Hope this helps. BTW if you want a good human browser for APIs google 'Paw API Browser'