RESTful Service Theory
The term "REST" was coined by Dr Roy Fielding in Chapter 5 of his PhD dissertation, in which he describes the underlying design philosophy of the World Wide Web, of which he was one of the principal architects (see, for instance, his contributions to the standards for HTTP and URIs/URLs, among others). In effect, to describe something as "RESTful" (having the characteristics of REST) is to say that it is architected in the same style as the Web.
REST is an acronym for "Representational State Transfer", which refers to the transfer of a representation of some aspect of the state of one machine to another. That aspect of state is referred to as a resource. In the case of a simple web site, a resource might be, for instance, a page of HTML: a web page (however don't forget that more complex web pages themselves often - usually! - contain many other kinds of embedded resources).
In practice (if not in theory) that transfer is almost always conducted over HTTP (or, more commonly for live services, HTTPS), where a representation of a resource, identified by its URL, is operated on through the use of HTTP Verbs.
When this design style is applied to a web service, that service, or API, is often referred to as being "RESTful", so a "REST API" or a "RESTful API" or a "RESTful service" are all simply different ways of describing essentially the same thing.
(To skip further discussion of the theory and go directly to the practicalities of dealing with consuming or creating RESTful services in DataFlex, go to the See also section at the end of this article, or directly to the RESTful Services in DataFlex article.)
The Characteristics of REST
In his dissertation, Fielding identified six characteristics which typified REST:
- Client-Server - a client (such as, for instance, a web browser) makes requests of a server (such as a web server) and receives a response
- Statelessness - each request and response is independent of others and stands alone: no state is maintained on the server between requests
- Cacheable - for efficiency, the response to a request must be explicitly marked as cacheable or not
- Uniform Interface - essentially the use of URIs (in practice, URLs) to identify coarse-grained resources
- Layered System - the use of intermediate hardware components, such as proxies and gateways, to, in conjunction with the caching above, improve scalability and reduce latency
In addition to these, RESTful web services also generally exhibit the use of:
- HTTP Verbs to specify the operation being carried out on a resource
- the HTTP Authorization header to provide access control
- the HTTP Content-Type header to identify the representation type being employed
- HTTP response statuses to indicate the result of a request
- query string parameters to modify the scope or detail of a request
- hypertext references (HREFs) to provide navigable links between different resources
The last of these is somewhat controversial. REST purists (sometimes referred to as "RESTafarians"), including Fielding himself, maintain that to be properly RESTful, an API must exhibit the property of HATEOAS ("Hypermedia As The Engine Of Application State"). By this they mean that an API should be "entered" by a client via a single known URL, with all other resources, and the operations which can be performed on them, being "discoverable" through HREF links and other information returned by the server. In his dissertation Fielding says: "REST is defined by four interface constraints: identification of resources; manipulation of resources through representations; self-descriptive messages; and, hypermedia as the engine of application state"; the last of these has become something an article of faith among some in the community, with interfaces (APIs) which do not conform to such a constraint being dismissed as "JSON-RPC". In practice, you are free to make your own design choices: there is nothing wrong with JSON-RPC if that fits your requirements.
The representation of a resource need not (and in web services, probably will not) be anything like the way it is stored at source (i.e. on the server). Typically that representation will be in some platform-neutral form such as HTML, XML, JSON, base64 or plain text (all of which are actually forms of plain text). In the case of RESTful web services, JSON is by far the commonest representation, although some services do support XML as an alternative.
Which would refer to the instance resource: customer number 1035 within the Example.org API version 2, or:
Which would refer to the collection resource: the line-items within order number 3269 in the RESTful API of MyWebsite.
Or you might dedicate an entire server (actual or virtual) to your APIs:
- https://en.wikipedia.org/wiki/Hypertext_Transfer_Protocol - Wikipedia is an example of a RESTful system (as is this Wiki).
Typically resources are organized into collections (i.e. orders) and within those, instances (i.e. the specific order number 3269), which in turn may have dependant collections (i.e. items) of further instances (i.e. item 14).
Collection names should, in general, be plural (because they refer to a plurality of instances within them), while instances should be identified by a unique key within their containing collection.
In APIs representing a hierarchically organised systems, which most databases, to a greater or lesser extent, are, the pattern:
- <protocol>://<host>/<api-path>/<version>/<collectionID>/<instanceID>/<collectionID>/<instanceID>/<collectionID>/... etc.
is a common one, although a depth of more that four or five collections would start to seem excessive!
RESTful interfaces make use of HTTP verbs to determine what operation should be performed on a given resource. The standard set of verbs are: GET, POST, PUT, DELETE, PATCH, HEAD, OPTIONS, CONNECT and TRACE. In practice, only the first five of these are in common use in RESTful services.
GET is used to retrieve a resource, be that a collection or an instance. It should (must!) have no side effects: its use should change nothing on the server (for this purpose we can discount irrelevant "plumbing" side effects, such as incrementing page counters or updating server logs).
POST is permitted to do anything, so there are no constraints on what this verb can be used for.
PUT is supposed to be "idempotent". Idempotent is a term, originally from mathematics (denoting an element of a set which is unchanged in value when multiplied or otherwise operated on by itself), but in the context of computing, it means that repeated applications of the same operation on the same resource should result in the same server state as resulted from the first application.
This makes PUT problematic for various operations. PUT can only be used to create or modify an entire resource. When creating a resource, everything about that resource must be known in advance: there must be no server-allocated key, or other associated aspect, involved in that creation, otherwise each new application would result in a different server state. Similarly, modifying a resource can only be done by replacing that resource entirely, which makes PUT unsuitable for partially updating a resource in a multi-user environment.
DELETE, like PUT, is also supposed to be idempotent, however this is less of a problem. If a resource is deleted, subsequent attempts to delete that resource will fail (probably giving an HTTP response status of "404 Not Found") because the resource is no longer there to be acted upon, however the state of the server will not be changed by those subsequent attempts: the resource will still not be there.
PATCH is a relatively recent (March 2010) addition to the list of common verbs, filling a requirement for "a feature to do partial resource modification", and that is exactly what it is good for: changing some parts of a resource without completely overwriting all of it.