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"
}
}
}
Related
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 :)
I'm new in web development, I need your help & suggestion to make with easy ways vertical table in JSP or Javascript from the JSON data, like below image:
This is for table from database:
And here for the JSON data:
{
"_embedded" : {
"shipping" : [ {
"dayCd" : "1",
"shiftCd" : "1",
"qty" : "40",
"productName" : "Prod1",
"_links" : {
"self" : {
"href" : "http://127.0.0.1:8080/shipping/1001"
},
"shipping" : {
"href" : "http://127.0.0.1:8080/shipping/1001"
}
}
}, {
"dayCd" : "2",
"shiftCd" : "1",
"qty" : "40",
"productName" : "Prod1",
"_links" : {
"self" : {
"href" : "http://127.0.0.1:8080/shipping/1002"
},
"shipping" : {
"href" : "http://127.0.0.1:8080/shipping/1002"
}
}
}, {
"dayCd" : "3",
"shiftCd" : "1",
"qty" : "40",
"productName" : "Prod1",
"_links" : {
"self" : {
"href" : "http://127.0.0.1:8080/shipping/1003"
},
"shipping" : {
"href" : "http://127.0.0.1:8080/shipping/1003"
}
}
..........
I am executing this query :
{
"query" : {
"match" : {
"studyID" : {
"query" : 1,
"type" : "boolean"
}
}
},
"aggregations" : {
"25-34" : {
"date_range" : {
"field" : "timestamp",
"ranges" : [ {
"from" : "1992",
"to" : "1983"
} ],
"format" : "yyyy"
},
"aggregations" : {
"activityType" : {
"terms" : {
"field" : "activityType"
}
}
}
},
"84-*" : {
"date_range" : {
"field" : "timestamp",
"ranges" : [ {
"from" : "1933"
} ],
"format" : "yyyy"
},
"aggregations" : {
"activityType" : {
"terms" : {
"field" : "activityType"
}
}
}
},
"18-24" : {
"date_range" : {
"field" : "timestamp",
"ranges" : [ {
"from" : "1999",
"to" : "1993"
} ],
"format" : "yyyy"
},
"aggregations" : {
"activityType" : {
"terms" : {
"field" : "activityType"
}
}
}
},
"75-84" : {
"date_range" : {
"field" : "timestamp",
"ranges" : [ {
"from" : "1942",
"to" : "1933"
} ],
"format" : "yyyy"
},
"aggregations" : {
"activityType" : {
"terms" : {
"field" : "activityType"
}
}
}
},
"0-17" : {
"date_range" : {
"field" : "timestamp",
"ranges" : [ {
"from" : "2017",
"to" : "2000"
} ],
"format" : "yyyy"
},
"aggregations" : {
"activityType" : {
"terms" : {
"field" : "activityType"
}
}
}
},
"55-64" : {
"date_range" : {
"field" : "timestamp",
"ranges" : [ {
"from" : "1962",
"to" : "1953"
} ],
"format" : "yyyy"
},
"aggregations" : {
"activityType" : {
"terms" : {
"field" : "activityType"
}
}
}
},
"65-74" : {
"date_range" : {
"field" : "timestamp",
"ranges" : [ {
"from" : "1952",
"to" : "1943"
} ],
"format" : "yyyy"
},
"aggregations" : {
"activityType" : {
"terms" : {
"field" : "activityType"
}
}
}
},
"35-44" : {
"date_range" : {
"field" : "timestamp",
"ranges" : [ {
"from" : "1982",
"to" : "1973"
} ],
"format" : "yyyy"
},
"aggregations" : {
"activityType" : {
"terms" : {
"field" : "activityType"
}
}
}
},
"45-54" : {
"date_range" : {
"field" : "timestamp",
"ranges" : [ {
"from" : "1972",
"to" : "1963"
} ],
"format" : "yyyy"
},
"aggregations" : {
"activityType" : {
"terms" : {
"field" : "activityType"
}
}
}
}
}
}
Where I just want to aggregation activity based on date ranges and then sub aggregate those ranges by activity type but Elastic search is giving me this exception :
{
"error": {
"root_cause": [
{
"type": "aggregation_execution_exception",
"reason": "Invalid number format [yyyy#]"
}
],
"type": "search_phase_execution_exception",
"reason": "all shards failed",
"phase": "query",
"grouped": true,
"failed_shards": [
{
"shard": 0,
"index": "study",
"node": "MWkXAAOCSYuM-ubdkulNnw",
"reason": {
"type": "aggregation_execution_exception",
"reason": "Invalid number format [yyyy#]"
}
}
]
},
"status": 500
}
Any Ideas what am I missing?
The format parameter is to specify in which format the dates should be returned in the response, not in which format they are specified in the request. So depending on the date format of the timestamp field you have specified in your mapping type, your request needs to contain full-fledge dates, like this:
"25-34" : {
"date_range" : {
"field" : "timestamp",
"ranges" : [ {
"from" : "1992-01-01T00:00:00.000Z",
"to" : "1983-12-31T23:59.59.999Z"
} ],
"format" : "yyyy"
},
"aggregations" : {
"activityType" : {
"terms" : {
"field" : "activityType"
}
}
}
},
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.