TutorialsPoint defines the following methods in context of RESTful design:
URI HTTP Body Result
-----------------------------------------------------------------
listUsers GET empty Show list of all the users
addUser POST JSON string Add details of new user
deleteUser DELETE JSON string Delete an existing user
:id GET empty Show details of a user
I think this is misleading, because it's not RESTful.
A RESTful design would be as following:
URI HTTP Body Result
----------------------------------------------------------------
users GET empty Show list of all the users
users POST JSON string Add details of new user
users DELETE empty Delete an existing user
users/:id GET empty Show details of a user
Is my understanding of RESTful correct?
Regardless of definition of RESTful, in my opinion, TutorialsPoint presented wrong design, because deleteUser inside URL duplicates information that is already passed as DELETE HTTP action, which violates universal principle of Once And Only Once.
The first set of endpoints is a bad design for a REST API. It's all about RPC (and DELETE requests should not have a payload).
The second set of endpoints are resource-orientated and that's what you want in a REST API. The URI identifies the resource and the HTTP method expresses the operation over the resource.
However the REST architecture goes much beyond the URIs design.
The REST architectural style is protocol independent, but it's designed over the HTTP protocol most of the time.
The fundamental concept in a RESTful application is the resource. And resources can have different representations. For more details, this answer can be helpful.
To be considered RESTful, an application must follow a set of constraints defined in the chapter 5 of Roy Thomas Fielding's dissertation:
Client-server
Stateless
Cache
Uniform interface
Resources identification
Resources representation
Self-descriptive messages
Hypermedia
Layered system
Code-on-demand
Yes your understanding is correct. That tutorial is misleading.
Related
If I am calling a Web APi service and that service makes various other calls to other services, do I use POST or GET?
To elaborate further, let's say I call Web Api Service One saying 'Do the thing'. Web Api One's job when requested thus, is to GET data from Service Two and POST data to Service Three. Perhaps Service One will then update Service Two. Service One will then respond to caller with any success/failure.
My question again is should I the caller, use POST or GET to Service One?
It's all about the semantics of the request. From the RFC 7231:
The request method token is the primary source of request semantics;
it indicates the purpose for which the client has made this request
and what is expected by the client as a successful result.
Here's a brief description of some HTTP methods defined in the RFC RFC 7231 (click the links to check the full method definition):
GET: Transfer a current representation of the target resource.
HEAD: Same as GET, but only transfer the status line and header section.
POST: Perform resource-specific processing on the request payload.
PUT: Replace all current representations of the target resource with the request payload.
DELETE: Remove all current representations of the target resource
In addition to the methods listed above, the RFC 5789 standardized the PATCH HTTP method for performing partial updates to a resource.
POST is commonly seen as a "catch all" method, once the target resource process the request payload according to the resource's own specific semantics.
HTTP methods can be classified as safe and/or idempotent and it must be taken into account when designing an API with on the top of HTTP.
Typically I would only use a variety of HTTP verbs (GET, POST, PUT, DELETE etc) when using a REST API. Then the endpoints are resources in their own right. For example:
/car
So the verbs make sense (are you getting a car? creating one? updating one? removing one?)
But when I am not using a REST API the HTTP verbs tend to have less meaning and I generally only use HTTP POST. Otherwise you hit logical problems like you're experiencing here.
eg
/rentacar
This API models an RPC that may cause many resources to change in many ways. It is not a REST API and so the HTTP Verbs don't really relate.
But in honesty, for RPC (remote procedure calls), people choose between GET and POST by either:
GET for operations that don’t modify anything and POST for other cases.
GET for operations that don’t need too much parameters and POST for other cases.
GET and POST on a random basis or always use POST.
Purists prefer 1. But sometimes you don't know when modifications are going to occur. So, take your pick!
In RESTful websites, each resource should be identified by an URI. But how should I handle what are called "weak entities" in relational databases, aka, ressources that only make sense when related to another resource? Should these have specific URIs pointing to them too?
To give an example: Say I have a website for showing events going on in a city. Each event can have comments posted by users.
An event is a resource, with corresponding URI (/events/:id).
But should each comment have an URI, too? Like /events/:eventid/comments/:commentid ? Comments only make sense when they're associated with the corresponding event, so having a page just to represent one message seems weird/unnecessary. I only want the comments to appear on the page of the event.
I guess the /events/:eventid/comments/:commentid URI could be used for a DELETE request, but what should it return to a GET request?
An event is a resource, with corresponding URI (/events/:id).
But should each comment have an URI, too? Like /events/:eventid/comments/:commentid ?
If comment is a resource, it must have an identifier, but it doesn't mean that you have to support all operations for such resource. The server can return a response with the 405 status code if a method is not supported by the target resource:
6.5.5. 405 Method Not Allowed
The 405 (Method Not Allowed) status code indicates that the method received in the request-line is known by the origin server but not supported by the target resource. [...]
I guess the /events/:eventid/comments/:commentid URI could be used for a DELETE request, but what should it return to a GET request?
Return a representation of the comment with the given identifier.
In RESTful websites, each resource should be identified by an URI. But how should I handle what are called "weak entities" in relational databases, aka, ressources that only make sense when related to another resource? Should these have specific URIs pointing to them too?
It depends. An important thing to recognize is that resources and entities are not one to one. You are allowed to have many resources (web pages) that include information from the same entity.
Jim Webber described the distinction this way
The web is not your domain, it's a document management system. All the HTTP verbs apply to the document management domain. URIs do NOT map onto domain objects - that violates encapsulation.
Domain Driven Design for Restful Systems
I guess the /events/:eventid/comments/:commentid URI could be used for a DELETE request, but what should it return to a GET request?
As noted by Cassio, 405 Method Not Allowed is the correct status code to use if the client erroneously sends a request with an unsupported method. OPTIONS is the appropriate mechanism for informing a client of which methods are currently supported by a resource.
You could also have it respond by redirecting the client to the /events/:eventId resource; it might even make sense to take advantage of URI Fragment support, and redirect the client to /events/:eventid#:commentid - allowing the client to use its own fragment discovery to identify the specific comment within the representation of the event.
Or, if there are useful integrations that you want to support, you could simply have this resource return a representation that exposes the integrations.
It really depends on how the client wants to work with the domain. Would an app want to get a list of all the comments for an event? Are users allowed to update their commments? Or are they anonymous comments?
If you plan to only ever use the same page to display the backend information of events and comments, then you prolly don't need a separate comments api. If you want to open the dataset to app vendors (perhaps you might want to develop an app in future) a comments api would be handy. i.e. get all comments for an event.
Is there a name for one piece of an API?
For example, say I have an API the offers four services:
getCustomerInfo
setCustomerInfo
getProductInfo
setProductInfo
Then say, I want to tell a colleague:
The API is going to need a fifth webhook?
I know this is an incorrect use of the word webhook.
What is the correct terminology?
Thanks!
UPDATE: This might be a duplicate. krishna kanth's answer here: What is an Endpoint? is:
The term Endpoint was initially used for WCF services. Later even
though this word is being used synonymous to API resources, REST
recommends to call these URI (URI[s] which understand HTTP verbs and
follow REST architecture) as "Resource".
In a nutshell, a Resource or Endpoint is kind of an entry point to a
remotely hosted application which lets the users to communicate to it
via HTTP protocol.
I think the word you're looking for is resource. I also think that getting and setting would be combined under a single resource and the HTTP calls to that resource would define whether you are GETing or PUTing (setting in REST using HTTP).
I think in general an API is a set of methods of communication between various software components.
So, I would say:
The API is going to need a fifth method?
Wikipedia also defines API and methods here:
https://en.wikipedia.org/wiki/Application_programming_interface
Roy Thomas Fielding defines it as Resource Identifier in your dissertation for the degree of Doctor of Philosophy (see Architectural Styles and the Design of Network-based Software Architectures).
According Roy Fielding:
REST uses a resource identifier to identify the particular resource
involved in an interaction between components.
I believe you can use the resource identifier /product do handle the product resource and the resource identifier /customer to handle the customer resource. Also, use the appropriated HTTP method to do the desired action. For example:
PUT to /product/{id} to edit a product resource identified by {id} (instead of setProductInfo)
GET to /product/{id} to return a representation of a product resource identified by {id} (instead of getProductInfo)
I am new to RESTful APIs and everywhere I read that REST APIs "must be hypertext-driven". I have googled a lot but haven't found a concrete explanation of the concept. So:
In practical terms, what does it mean that REST APIs should be 'hypertext-driven'?.
When I say hypertext, I mean the simultaneous presentation of information and controls such that the information becomes the affordance through which the user (or automaton) obtains choices and selects action. Roy T. Fielding - http://roy.gbiv.com/untangled/2008/rest-apis-must-be-hypertext-driven
It is about one of the fundamental constraints of REST architectural style - Hypermedia As The Engine Of Application State (HATEOAS). It means that in any given moment, client, based on hypermedia in representation of current resource, must have all the information he needs to decide where to transit next(change its Application State). That hypermedia controls in hypertext connect resources to each other, and describe their capabilities in machine-readable ways. A REST client just needs to know one thing in order to communicate with REST server - understanding of hypermedia. Opposite, in a service-oriented architecture(SOA), clients and servers interact through a fixed interface shared through documentation or an interface description language (IDL).
HATEOAS decouples client and server so that they can be developed separately.
For example,
If you make an initial call to a rest service to add a customer using some URL /customers/ then you will get a response back (consider the customer is successfully added),
HTTP/1.1 201 Created
Location: http://www.myREST/customers/<uuid>/
Now the client who made the call to add customer knows how to find the corresponding customer from the link returned as a response header.
You may ask how does client know that he can make POST to /customer/. By different means - hypermedia controls, DSL specific formats and profiles.
REST mean that api follow correct use for HTTP Verbs, Status code, etc. HTTP protocol, has verbs like: GET, POST, PUT, OPTIONS and DELETE. In a rest api, each verb is map to specific action on resource. For example:
POST is allways create a new instance of resource; GET is get the resource (or a list), DELETE is allways remove resource associated; PUT is modify/update a exist resource .....
Plus, you should use the status code for indicate response : 201 to create, 200 to modify, etc.
You can take more information on http://restinpractice.com/book/ (Jim Weber book)
I'm reasonably sure I understand the server-side of HATEOAS design - returning state URL's in the response - but I'm slightly confused about how to design a client to accept these.
For instance, we access a resource at //somehost.com/resource/1 - this provides us with the resource data and links. We'll assume POST to //somehost.com/resource is returned, indicating a 'new' action. Now I understand posting some data to that url creates a new resource, and provides a response, but where does the form to post that data reside? I've seen implementations where //somehost.com/resource/1/new provides a form which POSTS to /resource, but that URL itself contains a verb, and seems to violate REST.
I think my confusion lies in that I'm implementing a RESTful API and a client to consume it, within the same application.
Is there some sort of best-practice for this sort of thing?
I've seen implementations where //somehost.com/resource/1/new provides a form which POSTS to /resource, but that URL itself contains a verb, and seems to violate REST.
This is incorrect. A URI containing a verb does not, in itself, violate any REST constraint. It is only when that URI represents an action that this becomes a violation. If you can perform a GET request on the URL and receive some meaningful resource (such as a "create new resource" form), then that is perfectly RESTful, and good practice.
My own API is exactly as you describe: /{collection}/new returns a form. /new is just shorthand for a hypothetical /new-resource-creation-form and still represents a noun, and only supports GET requests (HEAD, OPTIONS and TRACE not withstanding).
What HATEOAS prohibits is the user agent being required to know, that in order to create a new resource, it must add /new to the name of the collection.
Basically, if you implement your API as (X)HTML, and can surf it in a browser and perform all actions (AJAX may be required for non-POST form submissions until HTML and browsers catch up with HTTP), then it complies with the hypermedia constraint of REST.
EDIT promoted from comments:
As long as the response negates any need for a priori knowledge, it conforms to the hypermedia constraint. If the client claims to understand HTML, and you send back a response containing a link to an external stylesheet or javascript (no matter where that is hosted) which the client needs to be able to render the page correctly, then it is reasonable to say that the constraint is met. The client should know how to handle all media types it claims to support. A normal human web browser is the perfect example of a client with no out-of-band knowledge about any one HTTP service (web site).
Just to say it explicitly, a web site is a kind of HTTP service. Web browsers do not treat different web sites differently. In order to search for products on Amazon, you load the Amazon service endpoint at http://amazon.com/ and follow links or fill out forms provided in that response. In order to search for products on eBay, you load the eBay service endpoint at http://ebay.com/ and do the same.
Browsers don't know in advance that for searching eBay you must do this, but for searching Amazon you have to do that. Browsers are ignorant. Clients for other HTTP services should be ignorant too.
Yes, you could provide a URI that returns a form for resource creation. Conceivably the form could be used for dynamic discovery of the elements needed to construct a new resource (but you'd want to decide how practical that would really be in a machine-to-machine environment).
Unless there is a requirement that somehow the API has an exact browser-surfable equivalent, the documentation of the media type will describe what elements are needed.
Remember that documentation of media types and the allowed HTTP verbs for a resource is not contrary to RESTful principles. Look at the SunCloud API for an example.
Indeed, according to your example, POST'ing to
//somehost.com/resource
to create a new resource is more standard than first returning a form
//somehost.com/resource/1/new
and THEN POST'ing to
//somehost.com/resource
anyway.