SlideShare a Scribd company logo
Restful web services
Dans la pratique
KONG TO
Code matters most
Summary
• Theory
• Principles
• CRUD
• FAQ
• Sample
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”.
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.
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.
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.
CRUD basics
• Create : POST
• Retrieve : GET
• Update : PUT ou PATCH
• Delete : DELETE
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
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
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();
}
}
import { Injectable } from '@angular/core';
import { Observable, of } from 'rxjs';
import { HttpClient, HttpHeaders } from '@angular/common/http';
import { Address, Status } from '../address/address.model';
const httpOptions = {
headers: new HttpHeaders({ 'Content-Type': 'application/json' })
};
@Injectable()
export class AddressService {
private url = 'api/address';
constructor(private http: HttpClient) { }
create(address: Address): Observable<Address> {
return this.http.post<Address>(this.url, user, httpOptions);
}
update(address: Address): Observable<Address> {
return this.http.put<Address>(this.url + '/' + address.id, address, httpOptions);
}
delete(address: Address): Observable<void> {
return this.http.delete<void>(this.url + '/' + address.id, httpOptions);
}
addresses(): Observable<Array<Address>> {
return this.http.get<Array<Address>>(this.url, httpOptions);
}
}
RESTfull Client Sample
RESTfull Sample
@RestController
@RequestMapping("/user")
public class UserController {
@Autowired
private UserService userService;
@PostMapping(value = "")
public UserDto create(@RequestBody UserDto user) {
return userService.save(user);
}
@PutMapping(value = "/{username}")
public void updateById(@PathVariable String username, @RequestBody UserDto user) {
userService.updateByUsername(username, user);
}
@DeleteMapping(value = "/{username}")
public void deleteByUsername(@PathVariable String username) {
userService.deleteByUsername(username);
}
@GetMapping(value = "", params = {"username"})
public UserDto findByUsername(@RequestParam String username) {
return userService.findByUsername(username);
}
@GetMapping(value = "")
public Collection<UserDto> findAll() {
return userService.findAll();
}
}
import { Injectable } from '@angular/core';
import { Observable, of } from 'rxjs';
import { HttpClient, HttpHeaders } from '@angular/common/http';
import { User, Status } from '../user/user.model';
const httpOptions = {
headers: new HttpHeaders({ 'Content-Type': 'application/json' })
};
@Injectable()
export class UserService {
private url = 'api/user';
constructor(private http: HttpClient) { }
create(user: User): Observable<User> {
return this.http.post<User>(this.url, user, httpOptions);
}
update(user: User): Observable<User> {
return this.http.put<User>(this.url + '/' + user.username, user, httpOptions);
}
delete(user: User): Observable<void> {
return this.http.delete<void>(this.url + '/' + user.username, httpOptions);
}
users(): Observable<Array<User>> {
return this.http.get<Array<User>>(this.url, httpOptions);
}
}
RESTfull Client Sample
Json-patch
JSON Patch is a format for describing changes to a JSON document.
It can be used to avoid sending a whole document when only a part has
changed.
{
"username": "uncle",
"firstname": "kong",
"lastname": "to",
" roles ": ["user"]
}
[
{ "op": "replace", "path": "/username", "value": "donkey" },
{ "op": "add", "path": "/roles", "value": ["admin"] },
{ "op": "replace", "path": "/roles/0/name", "value": "guest" }
{ "op": "add", "path": "/age", "value": 25 }
{ "op": "remove", "path": "/firstname" }
]
{
"username": "donkey",
"lastname": "to",
"age": 25,
"roles": ["guest", "admin"]
}
Json-patch 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);
}
@PatchMapping(value = "/{id}")
public void patch(@PathVariable Long id, @RequestBody List<JsonPatchOperation> operations) {
this.addressService.patch(id, operations);
}
@PatchMapping(value = "/{id}", params = {"patchById"})
public void patchById(@PathVariable Long id, @RequestBody JsonPatch jsonPatch) {
this.addressService.patchById(id, jsonPatch);
}
@DeleteMapping(value = "/{id}")
public void delete(@PathVariable Long id) {
addressService.deleteById(id);
}
@GetMapping(value = "")
public Collection<AddressDto> findAll() {
return addressService.findAll();
}
}
Json-patch sample
public class AddressService {
private AddressRepository addressRepository;
public AddressService(AddressRepository addressRepository) {
this.addressRepository = addressRepository;
}
public void updateById(Long id, AddressDto userDto) {
Optional<AddressEntity> entity = addressRepository.findById(id);
entity.ifPresent(u -> {
BeanUtils.copyProperties(AddressMapper.from(userDto), u);
addressRepository.save(u);
});
}
public void patchById(Long id, JsonPatch jsonPatch) {
this.findById(id)
.ifPresent(existing -> {
try {
ObjectMapper objectMapper = new ObjectMapper();
JsonNode patched = jsonPatch.apply(objectMapper.convertValue(existing, JsonNode.class));
AddressEntity patchedUser = objectMapper.treeToValue(patched, AddressEntity.class);
addressRepository.save(patchedUser);
} catch (JsonPatchException | JsonProcessingException e) {
throw new IllegalStateException();
}
});
}
}
Json-patch authorized operation
public class AddressService {
private AddressRepository addressRepository;
public AddressService(AddressRepository addressRepository) {
this.addressRepository = addressRepository;
}
public void patch(Long id, List<JsonPatchOperation> operations) {
addressRepository.findById(id)
.ifPresent(existing -> {
ObjectMapper objectMapper = new ObjectMapper();
operations.stream().forEach(op -> {
try {
JsonNode node = objectMapper.readValue(op.toString(), JsonNode.class);
// allow only add operation
if ("add".equals(node.get("op"))) {
JsonNode patched = op.apply(objectMapper.convertValue(existing, JsonNode.class));
AddressEntity patchedUser = objectMapper.treeToValue(patched, AddressEntity.class);
addressRepository.save(patchedUser);
}
} catch (IOException | JsonPatchException e) {
throw new IllegalStateException();
}
});
});
}
}

More Related Content

What's hot (20)

ODP
RestFull Webservices with JAX-RS
Neil Ghosh
 
PDF
PHP And Web Services: Perfect Partners
Lorna Mitchell
 
PDF
So various polymorphism in Scala
b0ris_1
 
PPT
Introduction to JAX-RS
Andreas Bjärlestam
 
PPT
Json-based Service Oriented Architecture for the web
kriszyp
 
PPT
Wsdl
ppts123456
 
PDF
JSON-RPC - JSON Remote Procedure Call
Peter R. Egli
 
PDF
Consuming RESTful services in PHP
Zoran Jeremic
 
PPTX
Web Services - WSDL
Martin Necasky
 
PPTX
Soap and restful webservice
Dong Ngoc
 
PDF
Introduction to SOAP/WSDL Web Services and RESTful Web Services
ecosio GmbH
 
PDF
OAuth: Trust Issues
Lorna Mitchell
 
ODP
SCDJWS 6. REST JAX-P
Francesco Ierna
 
PDF
XML-RPC (XML Remote Procedure Call)
Peter R. Egli
 
PPTX
Database connect
Yoga Raja
 
PPTX
Java Servlet
Yoga Raja
 
PDF
Restful web services by Sreeni Inturi
Sreeni I
 
PDF
Url programming
vantinhkhuc
 
PDF
Web Services (SOAP, WSDL, UDDI)
Peter R. Egli
 
RestFull Webservices with JAX-RS
Neil Ghosh
 
PHP And Web Services: Perfect Partners
Lorna Mitchell
 
So various polymorphism in Scala
b0ris_1
 
Introduction to JAX-RS
Andreas Bjärlestam
 
Json-based Service Oriented Architecture for the web
kriszyp
 
JSON-RPC - JSON Remote Procedure Call
Peter R. Egli
 
Consuming RESTful services in PHP
Zoran Jeremic
 
Web Services - WSDL
Martin Necasky
 
Soap and restful webservice
Dong Ngoc
 
Introduction to SOAP/WSDL Web Services and RESTful Web Services
ecosio GmbH
 
OAuth: Trust Issues
Lorna Mitchell
 
SCDJWS 6. REST JAX-P
Francesco Ierna
 
XML-RPC (XML Remote Procedure Call)
Peter R. Egli
 
Database connect
Yoga Raja
 
Java Servlet
Yoga Raja
 
Restful web services by Sreeni Inturi
Sreeni I
 
Url programming
vantinhkhuc
 
Web Services (SOAP, WSDL, UDDI)
Peter R. Egli
 

Similar to Restful webservices (20)

PPTX
A Deep Dive into RESTful API Design Part 2
VivekKrishna34
 
PPTX
REST Methodologies
jrodbx
 
PPTX
RestfulDesignRules
Michael De Courci
 
PPTX
RESTful Web Services
Martin Necasky
 
PPTX
Best Practices for Architecting a Pragmatic Web API.
Mario Cardinal
 
PPTX
Rest APIs Training
Shekhar Kumar
 
PDF
Building RESTful API
Anna Pietras
 
PPSX
Restful web services rule financial
Rule_Financial
 
PDF
Rest API Interview Questions PDF By ScholarHat
Scholarhat
 
PPTX
REST Api Tips and Tricks
Maksym Bruner
 
PDF
REST API Recommendations
Jeelani Shaik
 
PDF
Rest web services
Paulo Gandra de Sousa
 
PDF
What is REST?
Saeid Zebardast
 
PDF
Modern REST API design principles and rules.pdf
Aparna Sharma
 
PPTX
Rest with Java EE 6 , Security , Backbone.js
Carol McDonald
 
PPTX
Rest
Carol McDonald
 
PDF
What are restful web services?
Aparna Sharma
 
PPTX
RESTful API - Best Practices
Tricode (part of Dept)
 
PPT
RESTful SOA - 中科院暑期讲座
Li Yi
 
PPTX
JAX-RS. Developing RESTful APIs with Java
Jerry Kurian
 
A Deep Dive into RESTful API Design Part 2
VivekKrishna34
 
REST Methodologies
jrodbx
 
RestfulDesignRules
Michael De Courci
 
RESTful Web Services
Martin Necasky
 
Best Practices for Architecting a Pragmatic Web API.
Mario Cardinal
 
Rest APIs Training
Shekhar Kumar
 
Building RESTful API
Anna Pietras
 
Restful web services rule financial
Rule_Financial
 
Rest API Interview Questions PDF By ScholarHat
Scholarhat
 
REST Api Tips and Tricks
Maksym Bruner
 
REST API Recommendations
Jeelani Shaik
 
Rest web services
Paulo Gandra de Sousa
 
What is REST?
Saeid Zebardast
 
Modern REST API design principles and rules.pdf
Aparna Sharma
 
Rest with Java EE 6 , Security , Backbone.js
Carol McDonald
 
What are restful web services?
Aparna Sharma
 
RESTful API - Best Practices
Tricode (part of Dept)
 
RESTful SOA - 中科院暑期讲座
Li Yi
 
JAX-RS. Developing RESTful APIs with Java
Jerry Kurian
 
Ad

Recently uploaded (20)

PPTX
UI5con_2025_Accessibility_Ever_Evolving_
gerganakremenska1
 
PPTX
Smart Doctor Appointment Booking option in odoo.pptx
AxisTechnolabs
 
PDF
Simplify React app login with asgardeo-sdk
vaibhav289687
 
PPTX
How Can Reporting Tools Improve Marketing Performance.pptx
Varsha Nayak
 
PPTX
Transforming Lending with IntelliGrow – Advanced Loan Software Solutions
Intelli grow
 
PDF
chapter 5.pdf cyber security and Internet of things
PalakSharma980227
 
PDF
Salesforce Experience Cloud Consultant.pdf
VALiNTRY360
 
PDF
Meet in the Middle: Solving the Low-Latency Challenge for Agentic AI
Alluxio, Inc.
 
PDF
Introduction to Apache Iceberg™ & Tableflow
Alluxio, Inc.
 
PDF
Optimizing Tiered Storage for Low-Latency Real-Time Analytics at AI Scale
Alluxio, Inc.
 
PDF
IDM Crack with Internet Download Manager 6.42 Build 31 2025?
utfefguu
 
PDF
10 Salesforce Consulting Companies in Sydney.pdf
DianApps Technologies
 
PPTX
PCC IT Forum 2025 - Legislative Technology Snapshot
Gareth Oakes
 
PPTX
BB FlashBack Pro 5.61.0.4843 With Crack Free Download
cracked shares
 
PPTX
Build a Custom Agent for Agentic Testing.pptx
klpathrudu
 
PPTX
Cutting Optimization Pro 5.18.2 Crack With Free Download
cracked shares
 
PDF
Latest Capcut Pro 5.9.0 Crack Version For PC {Fully 2025
utfefguu
 
PDF
intro_to_cpp_namespace_robotics_corner.pdf
MohamedSaied877003
 
PDF
Ready Layer One: Intro to the Model Context Protocol
mmckenna1
 
PDF
Instantiations Company Update (ESUG 2025)
ESUG
 
UI5con_2025_Accessibility_Ever_Evolving_
gerganakremenska1
 
Smart Doctor Appointment Booking option in odoo.pptx
AxisTechnolabs
 
Simplify React app login with asgardeo-sdk
vaibhav289687
 
How Can Reporting Tools Improve Marketing Performance.pptx
Varsha Nayak
 
Transforming Lending with IntelliGrow – Advanced Loan Software Solutions
Intelli grow
 
chapter 5.pdf cyber security and Internet of things
PalakSharma980227
 
Salesforce Experience Cloud Consultant.pdf
VALiNTRY360
 
Meet in the Middle: Solving the Low-Latency Challenge for Agentic AI
Alluxio, Inc.
 
Introduction to Apache Iceberg™ & Tableflow
Alluxio, Inc.
 
Optimizing Tiered Storage for Low-Latency Real-Time Analytics at AI Scale
Alluxio, Inc.
 
IDM Crack with Internet Download Manager 6.42 Build 31 2025?
utfefguu
 
10 Salesforce Consulting Companies in Sydney.pdf
DianApps Technologies
 
PCC IT Forum 2025 - Legislative Technology Snapshot
Gareth Oakes
 
BB FlashBack Pro 5.61.0.4843 With Crack Free Download
cracked shares
 
Build a Custom Agent for Agentic Testing.pptx
klpathrudu
 
Cutting Optimization Pro 5.18.2 Crack With Free Download
cracked shares
 
Latest Capcut Pro 5.9.0 Crack Version For PC {Fully 2025
utfefguu
 
intro_to_cpp_namespace_robotics_corner.pdf
MohamedSaied877003
 
Ready Layer One: Intro to the Model Context Protocol
mmckenna1
 
Instantiations Company Update (ESUG 2025)
ESUG
 
Ad

Restful webservices

  • 1. Restful web services Dans la pratique KONG TO Code matters most
  • 2. Summary • Theory • Principles • CRUD • FAQ • Sample
  • 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(); } }
  • 11. import { Injectable } from '@angular/core'; import { Observable, of } from 'rxjs'; import { HttpClient, HttpHeaders } from '@angular/common/http'; import { Address, Status } from '../address/address.model'; const httpOptions = { headers: new HttpHeaders({ 'Content-Type': 'application/json' }) }; @Injectable() export class AddressService { private url = 'api/address'; constructor(private http: HttpClient) { } create(address: Address): Observable<Address> { return this.http.post<Address>(this.url, user, httpOptions); } update(address: Address): Observable<Address> { return this.http.put<Address>(this.url + '/' + address.id, address, httpOptions); } delete(address: Address): Observable<void> { return this.http.delete<void>(this.url + '/' + address.id, httpOptions); } addresses(): Observable<Array<Address>> { return this.http.get<Array<Address>>(this.url, httpOptions); } } RESTfull Client Sample
  • 12. RESTfull Sample @RestController @RequestMapping("/user") public class UserController { @Autowired private UserService userService; @PostMapping(value = "") public UserDto create(@RequestBody UserDto user) { return userService.save(user); } @PutMapping(value = "/{username}") public void updateById(@PathVariable String username, @RequestBody UserDto user) { userService.updateByUsername(username, user); } @DeleteMapping(value = "/{username}") public void deleteByUsername(@PathVariable String username) { userService.deleteByUsername(username); } @GetMapping(value = "", params = {"username"}) public UserDto findByUsername(@RequestParam String username) { return userService.findByUsername(username); } @GetMapping(value = "") public Collection<UserDto> findAll() { return userService.findAll(); } }
  • 13. import { Injectable } from '@angular/core'; import { Observable, of } from 'rxjs'; import { HttpClient, HttpHeaders } from '@angular/common/http'; import { User, Status } from '../user/user.model'; const httpOptions = { headers: new HttpHeaders({ 'Content-Type': 'application/json' }) }; @Injectable() export class UserService { private url = 'api/user'; constructor(private http: HttpClient) { } create(user: User): Observable<User> { return this.http.post<User>(this.url, user, httpOptions); } update(user: User): Observable<User> { return this.http.put<User>(this.url + '/' + user.username, user, httpOptions); } delete(user: User): Observable<void> { return this.http.delete<void>(this.url + '/' + user.username, httpOptions); } users(): Observable<Array<User>> { return this.http.get<Array<User>>(this.url, httpOptions); } } RESTfull Client Sample
  • 14. Json-patch JSON Patch is a format for describing changes to a JSON document. It can be used to avoid sending a whole document when only a part has changed. { "username": "uncle", "firstname": "kong", "lastname": "to", " roles ": ["user"] } [ { "op": "replace", "path": "/username", "value": "donkey" }, { "op": "add", "path": "/roles", "value": ["admin"] }, { "op": "replace", "path": "/roles/0/name", "value": "guest" } { "op": "add", "path": "/age", "value": 25 } { "op": "remove", "path": "/firstname" } ] { "username": "donkey", "lastname": "to", "age": 25, "roles": ["guest", "admin"] }
  • 15. Json-patch 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); } @PatchMapping(value = "/{id}") public void patch(@PathVariable Long id, @RequestBody List<JsonPatchOperation> operations) { this.addressService.patch(id, operations); } @PatchMapping(value = "/{id}", params = {"patchById"}) public void patchById(@PathVariable Long id, @RequestBody JsonPatch jsonPatch) { this.addressService.patchById(id, jsonPatch); } @DeleteMapping(value = "/{id}") public void delete(@PathVariable Long id) { addressService.deleteById(id); } @GetMapping(value = "") public Collection<AddressDto> findAll() { return addressService.findAll(); } }
  • 16. Json-patch sample public class AddressService { private AddressRepository addressRepository; public AddressService(AddressRepository addressRepository) { this.addressRepository = addressRepository; } public void updateById(Long id, AddressDto userDto) { Optional<AddressEntity> entity = addressRepository.findById(id); entity.ifPresent(u -> { BeanUtils.copyProperties(AddressMapper.from(userDto), u); addressRepository.save(u); }); } public void patchById(Long id, JsonPatch jsonPatch) { this.findById(id) .ifPresent(existing -> { try { ObjectMapper objectMapper = new ObjectMapper(); JsonNode patched = jsonPatch.apply(objectMapper.convertValue(existing, JsonNode.class)); AddressEntity patchedUser = objectMapper.treeToValue(patched, AddressEntity.class); addressRepository.save(patchedUser); } catch (JsonPatchException | JsonProcessingException e) { throw new IllegalStateException(); } }); } }
  • 17. Json-patch authorized operation public class AddressService { private AddressRepository addressRepository; public AddressService(AddressRepository addressRepository) { this.addressRepository = addressRepository; } public void patch(Long id, List<JsonPatchOperation> operations) { addressRepository.findById(id) .ifPresent(existing -> { ObjectMapper objectMapper = new ObjectMapper(); operations.stream().forEach(op -> { try { JsonNode node = objectMapper.readValue(op.toString(), JsonNode.class); // allow only add operation if ("add".equals(node.get("op"))) { JsonNode patched = op.apply(objectMapper.convertValue(existing, JsonNode.class)); AddressEntity patchedUser = objectMapper.treeToValue(patched, AddressEntity.class); addressRepository.save(patchedUser); } } catch (IOException | JsonPatchException e) { throw new IllegalStateException(); } }); }); } }