Patch REST API to Partial Update MongoDB in spring boot - java

I want to send a REST PATCH request to my API to only update some fields not the whole requestbody. Can someone help me to solve this issue
#PatchMapping("/update/{id}")
public ResponseEntity<String> update(#Valid #RequestBody Ordonnance ordonnance, #PathVariable("id") String id){
Optional<Ordonnance> ordonnanceData = ordonnanceRepository.findById(id);
this.ordonnanceRepository.save(ordonnance);
return ResponseEntity.ok("resource updated");
}

You can modify the fields by calling setters on the object which is returned from the repository.
#PatchMapping("/update/{id}")
public ResponseEntity<String> update(#Valid #RequestBody Ordonnance ordonnance, #PathVariable("id") String id){
Optional<Ordonnance> dbOrdonnance = ordonnanceRepository.findById(id);
if (!ordonnanceData.isPresent()) {
// The ID entered could not be found.
return ResponseEntity.notFound("Resource with id " + id + " was not found");
}
// Modify the values of the Ordonnance object retrieved from the database
Ordonnance ordonnanceToEdit = dbOrdonnance.get();
ordonnanceToEdit.setField1(ordonnance.getField1());
ordonnanceToEdit.setField2(ordonnance.getField2());
ordonnanceToEdit.setField3(ordonnance.getField3());
// Save to repository
this.ordonnanceRepository.save(ordonnanceToEdit);
return ResponseEntity.ok("Resource with ID " + id + " was successfully updated.");
}
This code should work, however you should create separate Java DTO Classes which are generally used to transfer data. This way you can only pass in the ID and the fields you would like to update, instead of having to pass in the entire object.

Related

return a response diferrent in the deleteById, spring

I'm a newbie in spring boot and I'm creating the method deleteById and I want check that user exist before.
How can i do to return a diferent message if the user exist or not?
Controller
#GetMapping(value = "/delete/{id}")
public ResponseEntity<Personaje> deleteCharacter(#PathVariable("id") long id){
Personaje p = this.characterService.deteleCharacter(id);
return new ResponseEntity<Personaje>(p, HttpStatus.OK);
}
Service
public Character deteleCharacter(long id) {
Character ch = this.repository.findById(id);
for example, if the id no exits, return a message "the id not found"
In the response entity, you can have something like this:
return new ResponseEntity<>("The ID is not found", HttpStatus.NOT_FOUND)
As for the return statement, you can leave it as a generic so from ResponseEntity<Personaje> you instead do it ResponseEntity<>.
This way you can return a generic response entity, and then populate it with data if needed.

Is it possible to verify empty input from the user in spring boot?

I'm writing a spring boot application and I'm having some troubles in verifying empty input from the user.
Is there a way to validate an empty input from the user?
For example:
#PostMapping("/new_post/{id}")
public int addNewPost(#PathVariable("id") Integer id, #RequestBody Post post) {
return postService.addNewPost(id, post);
}`
Here I want to add a new post only if the user exists in the database but when I send this post request I am getting the regular 404 error message and I am not able to provide my own exception although in my code I validate if the id equals to null.
http://localhost:8080/new_post/
Any idea what can I do?
Thanks
You can do something like this
#PostMapping(value = {"/new_post/{id}", "/new_post"})
public int addNewPost(#PathVariable(required = false, name="id") Integer id, #RequestBody Post post) {
return postService.addNewPost(id, post);
}
But the ideal way to handle this is using #RequestParam. #RequestParam is meant exactly for this purpose.
I think you need to do it like this:
#PostMapping(value = {"/new_post/", "/new_post/{id}"})
public int addNewPost(#PathVariable(value = "id", required = false) Integer id, #RequestBody Post post) {
This way you are also handling the URL when ID is null
I Think This is a Better Answer for Two Others :
#PostMapping("/new_post/{id}")
public int addNewPost(#PathVariable("id") Integer id, #RequestBody Post post)
{
if(!ObjectUtils.isEmpty(post))
{
return postService.addNewPost(id, post);
}
else
return null; // You can throws an Exception or any others response
}
id : Not required to check 'id', because with out id the requested method is not call.

Spring Boot before Put, Post and Delete Validation

I have created Post, Put and Delete Request in my controller in spring boot.
I have added validations in my model and also added #Valid parameter in method on controller.
I want to what else I am supposed to add for validation for Post, Put and Delete operation?
public class Employee {
#NotNull(message = "Employee Id can not be null")
private Integer id;
#Min(value = 2000, message = "Salary can not be less than 2000")
#Max(value = 50000, message = "Salary can not be greater than 50000")
private Integer salary;
#NotNull(message = "designation can not be null")
private String designation;
}
My Post Method is :
#PostMapping("/employees")
public ResponseEntity<Void> addEmployee(#Valid #RequestBody Employee newEmployee) {
Employee emp= service.addEmployee(newEmployee);
if (emp== null) {
return ResponseEntity.noContent().build();
}
return new ResponseEntity<Void>(HttpStatus.CREATED);
}
My Put Method is :
#PutMapping("/employees/{id}")
public ResponseEntity<Vehicle> updateEmployee(#Valid #RequestBody Employee updateEmployee) {
Employee emp= service.EmployeeById(updateEmployee.getId());
if (null == emp) {
return new ResponseEntity<Employee>(HttpStatus.NOT_FOUND);
}
emp.setSalary(updateEmployee.getSalary());
emp.setDesignation(updateEmployee.getDesignation());
service.updateEmployee(emp);
return new ResponseEntity<Employee>(emp, HttpStatus.OK);
}
Delete Method
#DeleteMapping("/employees/{id}")
public ResponseEntity<Employee> deleteEmployee(#Valid #PathVariable int id) {
Employee emp = service.getEmployeeById(id);
if (null == employee) {
return new ResponseEntity<Employee>(HttpStatus.FOUND);
}
service.deleteEmployee(id);
return new ResponseEntity<Employee>(HttpStatus.NO_CONTENT);
}
What is your specific problem?
Please refer to the following source for further reading.
Validation in Spring Boot
To your question about PUT - update does not work properly ?
Although, code looks ok. But if you are using JPA, then please remember JPA has delay data writing to database mechanism meaning it does not write data to database right away. And if you want JPA to write/save your data right away then you will have to call respository.saveAndFlush() - to force the JPA to write all data in session.
So, instead of calling the repository.saveAndFlush() every time you save data, you can simply return the same request object in this case "updateEmployee" instead of "emp" object for updating record e.g. :
return new ResponseEntity(updateEmployee, HttpStatus.OK);
POST : You should not use "#NotNull(message = "Employee Id can not be null")" on private Integer id since you are using same object for both POST and PUT method because #Valid will validate all fields in class.

Fixed name in rest service's input parameters

I implemented a rest web service by Jax-RS and CXF.
#Path("/StudentServices")
#Produces({"application/json"})
public class Student
{
#POST
#Path("/save")
public String persist(#QueryParam("StudentName") String name,
#QueryParam("StudentAge") String age)
{
System.out.println("*******************************");
System.out.println(" Incomming student with = " + name + " " + age);
System.out.println("*******************************");
return "Hello " + name;
}
}
Actually, I want to call the service with the url: localhost:9000/StudentServices/save
and with the body message as JSON: {"StudentName": "John", "StudentAge": "30"}
but when the request arrived to persist method, its inputs is null or empty. I examined with some others way like Jackson annotations, JAXB annotations but no one worked correctly.
Furthermore, I want to fix parameters' name when my service has input primitive types and String, because when I use a class for input, it works fine.
You cannot use #QueryParam to read the body of the request.
As specified in the #QueryParam docs, It binds the value(s) of a HTTP query parameter to a resource method parameter, resource class field, or resource class bean property. Values are URL decoded unless this is disabled using the Encoded annotation. so if you forward the request like below your exisiting code should work:
localhost:9000/StudentServices/save?StudentName=John& StudentAge=30
Now if you want to accept json request Then you will have to create seprate javaBean.
#XmlRootElement
public class StudentRequest {
private String studentName;
private int studentAge;
// getter and setter
}
And in your Controller. (i.e. Student.)
#Path("/StudentServices")
public class Student {
#POST
#Path("/save")
#Produces({"application/json"})
public String persist(StudentRequest studentRequest)
{
//your custom logic
}
}
Also specify your produces or consumes annotation on method level. It gives flexibility to return some other content type from other method.
You are defining the Parameter as QueryParam this means, that JAX-RS is expecting them as parameter added to your url, e.g. localhost:9000/StudentServices/save?StudentName=John&StudentAge=30
What you want is that the data is send in the body. So you can define a simple POJO:
public class Student {
private String StudentName;
private int StudentAge;
// getters and setters
}
And use it as parameter in the JAX-RS method:
#POST
#Path("/save")
public String persist(Student student) {
System.out.println("*******************************");
System.out.println(" Incomming student with = " + student.getStudentName() + " " + student.getStudentAge());
System.out.println("*******************************");
return "Hello " + student.getStudentName();
}
The JAXB provider is transforming your body data (JSON) into the corresponding POJO and you can access the data via the getters.

How to access the "findById" method of a RESTful service through "getJSON"?

This is the following code of my RESTful service class:
#RequestScoped
#Path("/empresas")
public class EmpresaEndpoint {
#Inject
private EmpresaRB empresaRB;
#GET
#Path("/{id:[0-9][0-9]*}")
#Produces("application/json")
public Response findById(#PathParam("id") final Long id) {
//TODO: retrieve the empresas
Empresa empresas = null;
if (empresas == null) {
return Response.status(Status.NOT_FOUND).build();
}
return Response.ok(empresas).build();
}
#GET
#Produces("application/json")
public List<Empresa> listAll(
#QueryParam("start") final Integer startPosition,
#QueryParam("max") final Integer maxResult) {
//TODO: retrieve the empresa
return empresaRB.getEmpresas();
}
}
If I wanted to access all the data stored on "Empresa" via jQuery, I would do:
$.getJSON( "rest/empresas", function( data ) {
//whatever is needed.
}
The code above would access the "listAll" method. So how can I access the "findById" method and pass the necessary parameter?
Assuming you have a variable called empresaId that holds the id for the entity, this should work.
$.getJSON( "rest/empresas/" + empresaId, function(data) {
// Whatever is required here
}
Well without having used that particular framework, it looks like it's mapping to the right method based on the path - it will use findById if the path has an ID, e.g.
$.getJSON("rest/empresas/100", function(data) {
// ...
}
(That will find the item with ID 100... obviously substitute the ID of the item you want to find. We don't know where that's coming from, but "rest/empresas/" + id may well be all you need.)
In my initial code, there was no query being connected to the variable "empresa", on the method findById().
I created a query on the repository class and assigned it to the variable. Problem Solved.
Thank you all for the time lended.

Categories

Resources