Reputation: 21
Based on the tutorial in https://spring.io/guides/gs/accessing-data-rest/, I use "CrudRepository" and "RepositoryRestResource" to make an address book. It works well for all the services such as adding a new contact, removing a contact, and etc. But, my problem is with deleting all the contacts (entries of the repository) from my address book. More specifically, when I want to delete them all by:
$curl -X DELETE http://localhost:8080/api/contact/
I get the following error:
{"timestamp":1518158144204,"status":404,"error":"Not Found","message":"No message available","path":"/api/contact/"}.
Note that spring.data.rest.basePath=/api is added to application.properties.
PersonRepository.java:
package hello;
import org.springframework.data.repository.CrudRepository;
import org.springframework.data.rest.core.annotation.RepositoryRestResource;
@RepositoryRestResource(collectionResourceRel = "contact", path = "contact")
public interface PersonRepository extends CrudRepository<Person,String>{
}
Person.java:
package hello;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
@Entity
public class Person {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private String id;
private String firstname;
private String familyname;
private String phonenumber;
private String email;
public String getfirstname() {
return firstname;
}
public void setfirstname(String firstName) {
this.firstname = firstName;
}
public String getfamilyname() {
return familyname;
}
public void setfamilyname(String familyName) {
this.familyname = familyName;
}
public String getphonenumber() {
return phonenumber;
}
public void setphonenumber(String phoneNumber) {
this.phonenumber = phoneNumber;
}
public String getemail() {
return email;
}
public void setemail(String Email) {
this.email = Email;
}
}
Upvotes: 2
Views: 8142
Reputation: 1
//You can use JPA Repository if you have no problem with it
//For Deleting all entities managed by the userRepository
@DeleteMapping("/users")
public void deleteAllUsers() {
userRepository.deleteAll();
}
import com.my.package.model.UserModel;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
@Repository
public interface UserRepository extends JpaRepository<UserModel, Long>
{
}
//You are welcome to ask where you don't understand.
Upvotes: 0
Reputation: 2935
In my experience it is better to write a delete function that works off the ids and not the entities because sometimes even if you delete the entity they are not deleted until the background process does it.
In your repository you can write something like
@Modifying
@Transactional
@Query("DELETE FROM Person p WHERE p.id = ?1)
void delete(Integer id);
@Modifying
@Transactional
@Query("DELETE FROM Person p WHERE p.id in ?1)
void delete(Set<Integer> ids);
The first one will allow you delete a single entity by id while the second one allows you to delete a set by ids.
What Urosh T states is true, you shouldn't be using your rest calls to call the repository directly. The rest calls should be going to a controller which then can act on the repository to do the delete.
Upvotes: 1
Reputation: 3814
Spring REST repositories have different methods that are exposed for collection resources and for individual item resources. More specifically GET, HEAD and POST are available out of the box for collection resources but DELETE is not.
Reference the docs here.
You can delete an individual item by passing a DELETE request with an item ID, just like the guide you are following says, for example curl -X DELETE http://localhost:8080/api/contact/23
.
IMHO, I think this was done right because of security reasons. Imagine if someone could delete your entire collection by accident if they happen not to pass an item id when deleting a single resource.
What you can do is write your own custom deleteAll
method if you want/need it however be careful.
You can write a custom delete method, for example:
public void deleteAllContacts();
And you can access that method via simple GET request:
http://localhost:8080/api/contact/search/deleteAllContacts
Now I have to mention that this is not really by REST principles, making a GET request and deleting a resource and this /search/delete...
part really sticks out as it kinda confuses the APi user. Does it searches, deletes or what??
This is one way to do what you want but I really do NOT recommend this as it is not an elegant way of doing things AND doesn't really follow good programming principles.
Maybe you should consider having a ContactController
that allows this functionality if a user passes a token or some other required parameter because you don't want to expose your API to the mercy of every google chrome out there and putting it at risk to erase all your data just with a single http request.
Upvotes: 1