I'm currently learning about Spring Boot and am undertaking a project where users can make posts, view those posts, etc.
A user's post(s) can be viewed via http://localhost:8080/users/{user_id}/posts and http://localhost:8080/users/{user_id}/posts/{post_id}
As a result I have the following UserPostController
#RestController
#RequestMapping("/users")
public class UserPostController {
#Autowired
private UserPostService postService;
#GetMapping("/{user_id}/posts")
public List<Post> retrieveUserPosts(#PathVariable int user_id) {
return postService.retrieveUserPostList(user_id);
}
#GetMapping("/{user_id}/posts/{post_id}")
public EntityModel<Post> retrieveUserPost(#PathVariable int user_id, #PathVariable int post_id) {
return postService.retrieveUserPost(user_id, post_id);
}
#PostMapping("/{user_id}/posts")
public ResponseEntity<Object> createUserPost(#PathVariable int user_id, #Valid #RequestBody Post post) {
return postService.saveUserPost(user_id, post);
}
}
Every request to the links work correctly. For example a GET request to http://localhost:8080/users/1/posts returns [{"id":1,"description":"This is a post"},{"id":2,"description":"This is another post"}], which is the expected action.
However, for some reason I am able to visit http://localhost:8080/posts which then returns a list of all posts:
{
"_embedded" : {
"posts" : [ {
"description" : "This is a post",
"_links" : {
"self" : {
"href" : "http://localhost:8080/posts/1"
},
"post" : {
"href" : "http://localhost:8080/posts/1"
},
"user" : {
"href" : "http://localhost:8080/posts/1/user"
}
}
}, {
"description" : "This another post",
"_links" : {
"self" : {
"href" : "http://localhost:8080/posts/2"
},
"post" : {
"href" : "http://localhost:8080/posts/2"
},
"user" : {
"href" : "http://localhost:8080/posts/2/user"
}
}
}, {
"description" : "This is yet another post",
"_links" : {
"self" : {
"href" : "http://localhost:8080/posts/3"
},
"post" : {
"href" : "http://localhost:8080/posts/3"
},
"user" : {
"href" : "http://localhost:8080/posts/3/user"
}
}
} ]
},
"_links" : {
"self" : {
"href" : "http://localhost:8080/posts"
},
"profile" : {
"href" : "http://localhost:8080/profile/posts"
}
},
"page" : {
"size" : 20,
"totalElements" : 3,
"totalPages" : 1,
"number" : 0
}
}
Through HATEOAS I am able to also see available links of the format http://localhost:8080/posts/{user_id}/user which I have also not created methods for, but they still exist.
Is there a reason why these unwanted routes exist? If so how do I change this?
Thank you :)
Related
I am building an REST API with Spring Boot. The question is really simple, how can I enable pagination for dependency request?
This how the results look for a non dependency request http://localhost:8080/dimensionAttributes:
{
"_embedded" : {
"dimensionAttribute" : [ {
"name" : "SollFreitag",
"description" : "Sollstunden Freitags",
"dataType" : "DEC",
"hasHistory" : true,
"hasTrigger" : null,
"allowInterface" : true,
"readOnly" : null,
"discrete" : null,
"mandatory" : false,
"_links" : {
"self" : {
"href" : "http://localhost:8080/dimensionAttributes/20"
},
"dimensionAttribute" : {
"href" : "http://localhost:8080/dimensionAttributes/20"
},
"dimension" : {
"href" : "http://localhost:8080/dimensionAttributes/20/dimension"
},
"dimensionAttributeValue" : {
"href" : "http://localhost:8080/dimensionAttributes/20/dimensionAttributeValue"
}
}
} ]
},
"_links" : {
"first" : {
"href" : "http://localhost:8080/dimensionAttributes?page=0&size=20"
},
"self" : {
"href" : "http://localhost:8080/dimensionAttributes{?page,size,sort}",
"templated" : true
},
"next" : {
"href" : "http://localhost:8080/dimensionAttributes?page=1&size=20"
},
"last" : {
"href" : "http://localhost:8080/dimensionAttributes?page=1&size=20"
},
"profile" : {
"href" : "http://localhost:8080/profile/dimensionAttributes"
},
"search" : {
"href" : "http://localhost:8080/dimensionAttributes/search"
}
},
"page" : {
"size" : 20,
"totalElements" : 35,
"totalPages" : 2,
"number" : 0
}
}
But running an dependency request (in this case its "dimensionAttributeValue" ) http://localhost:8080/dimensionAttributes/20/dimensionAttributeValue, the page section, as well as the next url and other links are missing.
{
"_embedded" : {
"dimensionAttributeValue" : [ {
"chrValue" : "Mihal, Matus",
"intValue" : null,
"decValue" : null,
"datValue" : null,
"startDate" : null,
"_links" : {
"self" : {
"href" : "http://localhost:8080/dimensionAttributeValues/18993"
},
"dimensionAttributeValue" : {
"href" : "http://localhost:8080/dimensionAttributeValues/18993"
},
"lstValue" : {
"href" : "http://localhost:8080/dimensionAttributeValues/18993/lstValue"
},
"dimensionAttribute" : {
"href" : "http://localhost:8080/dimensionAttributeValues/18993/dimensionAttribute"
},
"masterData" : {
"href" : "http://localhost:8080/dimensionAttributeValues/18993/masterData"
}
}
} ]
},
"_links" : {
"self" : {
"href" : "http://localhost:8080/dimensionAttributes/1/dimensionAttributeValue?page=0,&size=1"
}
}
}
Please find my mapping query below for the filename field.
PUT /articles
{
"settings" : {
"analysis" : {
"analyzer" : {
"filename_search" : {
"tokenizer" : "filename",
"filter" : ["lowercase"]
},
"filename_index" : {
"tokenizer" : "filename",
"filter" : ["lowercase","edge_ngram"]
}
},
"tokenizer" : {
"filename" : {
"pattern" : "[^\\p{L}\\d]+",
"type" : "pattern"
}
},
"filter" : {
"edge_ngram" : {
"side" : "front",
"max_gram" : 50,
"min_gram" : 1,
"type" : "edgeNGram"
}
}
}
},
"mappings" : {
"doc" : {
"properties" : {
"filename" : {
"type" : "text",
"search_analyzer" : "filename_search",
"analyzer" : "filename_index"
}
}
}
}
}
If am trying to query series1333372 doc623258 and am expecting karthik_series1333372_oracle_page_doc623258_v1_en-EU.pdf. But it's giving all the files which is having series1333372, not even checking for doc623258.
Please find my query below
get articles/_search
{
"query" : {
"match" : {
"filename" : "series1333372 doc623258"
}
}
}
I am inserting the following sample documents for testing from Kibana
POST articles/doc/1
{
"filename" : "karthik_series1333372_oracle_page_doc623258_v1_en-EU.pdf"
}
POST articles/doc/2
{
"filename" : "karthik_series1333372_sun_page_doc658_v1_en-EU.pdf"
}
POST articles/doc/3
{
"filename" : "series1333372_oracle_page_doc623_v1_en-US.pdf"
}
POST articles/doc/4
{
"filename" : "Engineering series1333372 valve_page doc6232 v1_en-US.pdf"
}
POST articles/doc/5
{
"filename" : "Machines_series1333372_page_doc62258_v1_en-US.pdf"
}
POST articles/doc/6
{
"filename" : "AIX series1333372 IBM page doc62358 v1_en-EU.pdf"
}
The default operator of match is OR. If you want all your terms to be present change it like this
GET articles/_search
{
"query" : {
"match" : {
"filename" : {
"query": "series1333372 doc623258",
"operator" : "and"
}
}
}
}
How can i get any object id from Hal representation?
Exactly i want to get this from specific user from allUser list. There is example:
{
"_embedded" : {
"users" : [ {
"login" : "user1",
"firstName" : "Bolek",
"lastName" : "Kowal",
"email" : null,
"password" : null,
"gender" : null,
"birthDate" : null,
"_links" : {
"self" : {
"href" : "http://localhost:8080/games-organizer/api/users/1"
},
"user" : {
"href" : "http://localhost:8080/games-organizer/api/users/1"
},
"roles" : {
"href" : "http://localhost:8080/games-organizer/api/users/1/roles"
}
}
}, {
"login" : "user2",
"firstName" : "Lolek",
"lastName" : "Kowalski",
"email" : null,
"password" : null,
"gender" : null,
"birthDate" : null,
"_links" : {
"self" : {
"href" : "http://localhost:8080/games-organizer/api/users/2"
},
"user" : {
"href" : "http://localhost:8080/games-organizer/api/users/2"
},
"roles" : {
"href" : "http://localhost:8080/games-organizer/api/users/2/roles"
}
}
}
Eventually how can i delete specific user using rest spring api and angular/spring? I don't know how can i do this without having id from any user(object).
Update:
I want to use this id, in invoke some method like this:
$scope.$on('deleteUser', function (event, id) {
userService.delete({id: id}).$promise.then(
function () {
// Broadcast the event to refresh the grid.
$rootScope.$broadcast('refreshUserGrid');
// Broadcast the event to display a delete message.
$rootScope.$broadcast('userDeleted');
$scope.clearForm();
},
function () {
// Broadcast the event for a server error.
$rootScope.$broadcast('error');
});
});
I want to delete some record from database in springRestAPI.
Suppose you want to delete details of user2 then you can do this :
For (var i=0;i<allUser.users.length;i++){
if(allUser.users[i].login=="user2"){
allUser.users.splice(i-1,i);
}
}
I have simple Spring Boot application. My controller looks like this:
#RequestMapping(value = "/", method = RequestMethod.GET)
public List<Employee> getAllEmployees() {
return employeeRepository.findAll();
}
This code produce this json:
{
"_embedded" : {
"employees" : [ {
"firstName" : "firstName1",
"lastName" : "lastName1",
"_links" : {
"self" : {
"href" : "http://localhost:8080/employees/1"
},
"employee" : {
"href" : "http://localhost:8080/employees/1"
}
}
}, {
"firstName" : "firstName 1",
"lastName" : "lastName 1",
"_links" : {
"self" : {
"href" : "http://localhost:8080/employees/2"
},
"employee" : {
"href" : "http://localhost:8080/employees/2"
}
}
}, {
"firstName" : "firstName 3",
"lastName" : "lastName 3",
"_links" : {
"self" : {
"href" : "http://localhost:8080/employees/4"
},
"employee" : {
"href" : "http://localhost:8080/employees/4"
}
},
"_links" : {
"self" : {
"href" : "http://localhost:8080/employees"
},
"profile" : {
"href" : "http://localhost:8080/profile/employees"
}
},
"page" : {
"size" : 20,
"totalElements" : 7,
"totalPages" : 1,
"number" : 0
}
}
But I need something like this:
[
{
"firstName" : "firstName1",
"lastName" : "lastName1",
},
{
"firstName" : "firstName2",
"lastName" : "lastName2",
},
]
The solution is removing spring-boot-starter-data-rest module.
How to get expected output below where OrderProjection uses ItemProjection to render Items using Spring Data REST
GET /orders/1?projection=with_items
Projections :
#Projection(name = "summary", types = Item.class)
public interface ItemProjection {
String getName();
}
#Projection(name = "with_item", types = Order.class)
public interface OrderProjection {
LocalDateTime getOrderedDate();
Status getStatus();
Set<ItemProjection> getItems(); // this is marshalling as Set<Item> (full Item graph)
}
Currently getting as output:
{
"status" : "PAYMENT_EXPECTED",
"orderedDate" : "2014-11-09T11:33:02.823",
"items" : [ {
"name" : "Java Chip",
"quantity" : 1,
"milk" : "SEMI",
"size" : "LARGE",
"price" : {
"currency" : "EUR",
"value" : 4.20
}
} ],
"_links" : {
"self" : {
"href" : "http://localhost:8080/orders/1{?projection}",
"templated" : true
},
"restbucks:items" : {
"href" : "http://localhost:8080/orders/1/items"
},
"curies" : [ {
"href" : "http://localhost:8080/alps/{rel}",
"name" : "restbucks",
"templated" : true
} ]
}
}
Expected Output:
{
"status" : "PAYMENT_EXPECTED",
"orderedDate" : "2014-11-09T11:33:02.823",
"items" : [ {
"name" : "Java Chip"
} ],
"_links" : {
"self" : {
"href" : "http://localhost:8080/orders/1{?projection}",
"templated" : true
},
"restbucks:items" : {
"href" : "http://localhost:8080/orders/1/items"
},
"curies" : [ {
"href" : "http://localhost:8080/alps/{rel}",
"name" : "restbucks",
"templated" : true
} ]
}
}
You're running into DATAREST-394 which has been fixed a few days a go and will be making it into 2.2.2 and 2.3 RC1. It's already available in the snapshots for said versions, feel free to give them a spin.