HTTP methods
The REST-based architecture uses standard HTTP methods: PUT, GET, POST, and DELETE. The following list gives an explanation of these operations:
- GET gives a read access to the resource. Calling GET should not create any side-effects. It means that the GET operation is idempotent. The resource is never changed via a GET request; for example, the request has no side effects. It means it's idempotent
- PUT creates a new resource. Similar to GET, it should also be idempotent
- DELETE removes the resource or resources. The DELETE operation should not give different results when called repeatedly
- POST will update an existing resource or create a new one
A RESTful web service is simply a web service that is based on the REST resource concept and usage of HTTP methods. It should define the base URI for the exposed methods, the MIME-types supported, such as XML, text, or JSON, and the set of operations (POST, GET, PUT, and DELETE) which the service handles. HTTP is simple and very natural for REST, according to RESTful principles. These principles are a set of constraints that ensure that clients (service consumers, other services or browsers, for example) can communicate with servers in a flexible way. Let's look at them now.
In REST principles client-server communication, all applications built in the RESTful style must also be client-server in principle. There should be a server (service provider) and a client (service consumer). Having this enables loose coupling and independent evolution of server and client. This fits very well to the concept of a microservice. As you will remember from Chapter 3, Working with Microservices, they must be independent:
- Stateless: Each client request to the server requires that its state be fully represented. The server must be able to completely understand the client request without using any server context or server session state. In other words, all states must be managed on the client side. Each REST service should be stateless. Subsequent requests should not depend on some data from a previous request being temporarily stored. Messages should be self-descriptive.
- Cacheable: Response data could be marked as cacheable or non-cacheable. Any data marked as cacheable may be reused as the response to the same subsequent request. Each response should indicate if it is cacheable.
- Uniform interface: All components must interact through a single uniform interface. Because all component interactions occur via this interface, interaction with different services is very simple.
- Layered system: A consumer of the service should not assume direct connection to the service provider. In other words, at any time the client cannot tell if it is connected to the end server or to an intermediate. The intermediate layer helps to enforce the security policies and improve the system scalability by enabling load-balancing. Since requests can be cached, the client might be getting the cached response from a middle layer.
- Manipulation of resources through representations: A resource can have multiple representations. It should be possible to modify the resource through a message with any of these representations.
- Hypermedia As The Engine Of Application State (HATEOAS): A consumer of a RESTful application should know about only one fixed service URL. All subsequent resources should be discoverable from the links included in the resource representations.
The previous concepts represent defining characteristics of REST and differentiate the REST architecture from other architectures such as web services. It is useful to note that a REST service is a web service, but a web service is not necessarily a REST service. The REST microservice should represent the state of an entity. Let our entity be a book, for example (altogether with its properties such as ID, title, and an author), represented as XML, JSON, or plain text. The most basic way of thinking about REST is as a way of formatting the URLs of your service. For example, having our book resource, we could imagine having the following operations defined in the service:
- /books would allow access of all the books
- /books/:id would be an operation for viewing an individual book, retrieved based on its unique ID
- sending a POST request to /books would be how you would actually create a new book and store it in a database
- sending a PUT request to /books/:id would be how you would update the attributes of a given book, again identified by its unique ID
- sending a DELETE request to /books/:id would be how you would delete a specific book, again identified by its unique ID
It's worth trying to understand that REST is not HTTP. It often uses HTTP because in its most general form, REST is about mapping the concept of a verb against an arbitrary collection of nouns and fits well with HTTP methods. HTTP contains a useful set of generic verbs (GET, POST, PUT, PATCH, and so on). In REST, we do not transfer an actual object but a representation of it in a specific form, such as XML, text, or JSON. REST as an architectural style means it is just a concept. How it's implemented, is up to you. Java is suited well for developing REST services. Let's see how can we do it.