This material has been used demonstrate practices with some misunderstanding of RESTful APIs. Let's see some samples and share. Json-patch is also shown with some samples, as it is quite useful for RESTful services.
3. Definition
REST for “REpresentation State Transfer is not a protocol, nor a format,
but an architecture style, a convention or an approach to construct
web services, on top of HTTP.
It is used to develop Resources Oriented Application. Applications that
are complied with this architecture is said RESTful”.
4. Contraints
• Client-server
• The separation of concerns enables independent evolution of the Client and the Server.
• Stateless
• The communication between Client and Server must be stateless between requests. Each
request from a client should contain all the necessary information for the service to complete
the request. all session state data should then be returned to the client at the end of each
request.
• Cache
• All responses from the Server should be explicitly labeled as cacheable or non-cacheable.
• Interface / Uniform Contract
• The Service and all Clients must share a single uniform technical interface.
• Layered System
• Allow for Intermediaries / Middleware.
5. Terminology
• Resource
• The Resource is the key abstraction of information in REST. Any information
that can be named / identified via a unique, global id (the URI) - is a Resource.
• Representation
• Any given Resource can have multiple Representations; these capture the
current state of the Resource in a specific format.
• At the lowest level, the Representation is “a sequence of bytes, plus
representation metadata to describe these bytes”.
• Hypermedia Types
• There are several Hypermedia types we can use for our Representations, and
we can build our own if we need to. Note that JSON is not a Hypermedia.
6. Principles
• Resources are identified by URI
• Every resource is identified by a unique identifier.
• Uniform interface, use HTTP verbs for CRUD operations on resources
• Use common set of verbs : GET, PUT, POST, DELETE, PATCH.
• Response represents resource (json, xml)
• Response is the representation of the resource.
• Links to other resources
• Within response, there are links to other resources (links, next, last, otherResource).
• Stateless services
• So the server does not maintain the states of the clients. This means that you cannot use server session storage and you have to authenticate
every request. Don’t confuse session storage and persistence into database.
• Each request from a client should contain all the necessary information for the service to complete the request. All session state data should
then be returned to the client at the end of each request.
• Cacheable, if you can
• So you don’t have to serve the same requests again and again
• Layered system
• To increase scalability, the REST system is composed of hierarchical layers. Each layer contains components which use the services of
components which are in the next layer below. So you can add new layers and components effortless. Intermediary components or middleware
must be transparent and independent.
7. CRUD basics
• Create : POST
• Retrieve : GET
• Update : PUT ou PATCH
• Delete : DELETE
8. FAQ
• Trigger an action on server side with a GET?
• E.g. : Triggering a batch or a notification
• Create a resource with a GET?
• Read a resource with a POST?
• E.g Search with complex criteria
• Update with DELETE, or Delete with PUT?
Following standards makes intent explicit. Refer to the RFC-626
9. Sample
GET /user/new
GET /new_user.x
POST /user/new
POST /user/delete
GET /delete_user.x?id=123
GET /user?id=1
GET /user/id/1
GET /get/user/by/profile/id
GET /get/user/address/by/city?city=paris
GET /find/user/by/name?name=Bob
PUT /user/update?id=100
GET /user/findBy?name=Bob&age=29
POST /user
GET /user/2
DELETE /user/2
PUT /user/2
GET
/user/address?city=paris
10. RESTfull Sample
@RestController
@RequestMapping("/address")
public class AdressController {
@Autowired
private AddressService addressService;
@PostMapping(value = "")
public AddressDto create(@RequestBody AddressDto address) {
return addressService.save(address);
}
@PutMapping(value = "/{id}")
public void update(@PathVariable Long id, @RequestBody AddressDto address) {
addressService.updateById(id, address);
}
@DeleteMapping(value = "/{id}")
public void delete(@PathVariable Long id) {
addressService.deleteById(id);
}
@GetMapping(value = "")
public Collection<AddressDto> findAll() {
return addressService.findAll();
}
}