When I make a call to a Spring Data Rest Endpoint I am expecting to see the self links and related links within each object. None of the links appear.
RestTemplate Setup:
#HystrixCommand(fallbackMethod = "getFallbackScenicList")
#RequestMapping(value = "/s", method = RequestMethod.GET, produces= MediaType.APPLICATION_JSON_VALUE)
public PagedResources<Scenic> scenic() {
String url = "http://vr-dms-an-scenic/scenic";
ParameterizedTypeReference<PagedResources<Scenic>> ptr = new ParameterizedTypeReference<PagedResources<Scenic>>() {};
ResponseEntity<PagedResources<Scenic>> responseEntity =
this.restTemplate.exchange(url,HttpMethod.GET, null, ptr, 0,100
);
PagedResources<Scenic> resources = responseEntity.getBody();
return resources;
}
Expected Response:
{
"_embedded": {
"scenic": [
{
"id": 1,
"name": "Test1 scenic",
"description": "This is a description1 for displaying information while in development",
"shortDescription": "Short Description Scenic1",
"_links": {
"self": {
"href": "http://localhost:49218/scenic/1"
},
"scenic": {
"href": "http://localhost:49218/scenic/1"
}
}
}
]
},
"_links": {
"self": {
"href": "http://localhost:49218/scenic"
},
"profile": {
"href": "http://localhost:49218/profile/scenic"
},
"search": {
"href": "http://localhost:49218/scenic/search"
}
},
"page": {
"size": 20,
"totalElements": 1,
"totalPages": 1,
"number": 0
}
}
Actual Response:
{
"_embedded": {
"scenic": [
{
"id": 1,
"name": "Test1 scenic",
"description": "This is a description1 for displaying information while in development",
"shortDescription": "Short Description Scenic1"
}
]
},
"_links": {
"self": {
"href": "http://localhost:49218/scenic"
},
"profile": {
"href": "http://localhost:49218/profile/scenic"
},
"search": {
"href": "http://localhost:49218/scenic/search"
}
},
"page": {
"size": 20,
"totalElements": 1,
"totalPages": 1,
"number": 0
}
}
I assume that Scenic doesn't contain links. So instead of
PagedResources<Scenic>
you actually want
PagedResources<Resource<Scenic>>
Related
Hi I would like to draw from graphql only those records whose date is equal to the month - August
If I want to pull another month, it is enough to replace it only in the query. At the moment, my query takes all the months instead of the ones it gives inside the filter
schema.json
{
"kind": "collectionType",
"collectionName": "product_popularities",
"info": {
"singularName": "product-popularity",
"pluralName": "product-popularities",
"displayName": "Popularity",
"description": ""
},
"options": {
"draftAndPublish": true
},
"pluginOptions": {},
"attributes": {
"podcast": {
"type": "relation",
"relation": "manyToOne",
"target": "api::product.products",
"inversedBy": "products"
},
"value": {
"type": "integer"
},
"date": {
"type": "date"
}
}
}
My query
query {
Popularities(filters: {date: {contains: [2022-08]}}) {
data {
attributes {
date
value
}
}
}
}
Response
{
"data": {
"Popularities": {
"data": [
{
"attributes": {
"date": "2022-08-03",
"value": 50
}
},
{
"attributes": {
"date": "2022-08-04",
"value": 1
}
},
{
"attributes": {
"date": "2022-08-10",
"value": 100
}
},
{
"attributes": {
"date": "2022-07-06",
"value": 20
}
}
]
}
}
}
I am new to the mongoDB aggregation and I have this situation. I have this Json and I need to convert by "select" this object:
{
"type": "PF",
"code": 12345
"Name": Darth Vader,
"currency": "BRL",
"status": "SINGLE",
"adress": [
{
"localization": "DEATH STAR",
"createDate": 1627990848665
},
{
"localization": "TATOOINE",
"createDate": 1627990555665
},
]
}
this way:
{
"type": "PF",
"code": 12345
"Name": Darth Vader,
"currency": "BRL",
"status": "SINGLE",
"localization": "DEATH STAR",
"createDate": 1627990848665
},
{
"type": "PF",
"code": 12345
"Name": Darth Vader,
"currency": "BRL",
"status": "SINGLE",
"localization": "TATOOINE",
"createDate": 1627990555665
}
So, after my query is complete, I will have 02 objects instead of 01. How can I do this?
I would like to do this via select because after converting I will sort by createDate and limit the number of records to return to the API. I'm using Criteria em my project.
The way to do this is $unwind, this will make 1 copy of the document, for each member of the array.
Test code here
db.collection.aggregate([
{
"$unwind": {
"path": "$user.adress"
}
},
{
"$set": {
"user": {
"$mergeObjects": [
"$user",
"$user.adress"
]
}
}
},
{
"$unset": [
"user.adress"
]
},
{
"$sort": {
"createDate": 1
}
},
{
"$limit": 10
}
])
Edit1 (the above is if user is a field, if it was the name of the collection)
$$ROOT is a system variable that has as value all the document
Test code here
Query
db.collection.aggregate([
{
"$unwind": {
"path": "$adress"
}
},
{
"$replaceRoot": {
"newRoot": {
"$mergeObjects": [
"$$ROOT",
"$adress"
]
}
}
},
{
"$unset": [
"adress"
]
},
{
"$sort": {
"createDate": 1
}
},
{
"$limit": 10
}
])
After upgrade SpringBoot from 1.5.4 to 2.1.7, the existing Spring HATEOAS code does no longer generate '_embedded' and '_link' in the response, instead it generates 'embedded' and 'link'. I need help to find the root cause of this, and how to fix it. Thank you.
Here is a sample of response payload:
{
"embedded": {
"orders": [
{
"id": 3172,
"orderNumber": 148700990741,
"status": "FINISHED",
"userId": "ffffffff5e7c13a4da4a9d0132e95f73",
"createdAt": "2020-03-26T02:31:32.263Z",
"updatedAt": "2020-03-26T02:31:38.853Z",
"createdBy": "ffffffff57acb9e5e4b0e06a0a570080",
"addresses": [],
"updatedBy": "ffffffff57acb9e5e4b0e06a0a570080",
"successUrl": "http://example.com/success",
"cancelUrl": "http://example.com/cancel",
"link": {
"self": {
"href": "http://local.dev-openclass.com:8088/v1/orders/3172"
},
"order": {
"href": "http://local.dev-openclass.com:8088/v1/orders/3172"
},
"transactions": {
"href": "http://local.dev-openclass.com:8088/v1/orders/3172/transactions"
}
}
}
]
},
"link": {
"self": {
"href": "http://local.dev-openclass.com:8088/v1/orders/search/?userId=ffffffff5e7c13a4da4a9d0132e95f73"
}
}
}
I have a simple application containing Products, Prices and PricedProducts.
When I request the list of PricedProducts, I want the Price and the Product to be inlined. I marked my Price repository with #RestResource(exported = false), so for this one it works ok. Products, however, need to be self standing entities (I need to be able to build several PricedProducts using the same Product for example).
I created a projection for PricedProduct, added it as excerptProjection, and a GET to /pricedProducts returns:
{
"_embedded": {
"pricedProducts": [
{
"price": {
"value": "100.50",
"currency": "EUR"
},
"product": {
"name": "Poatato",
"description": null,
"pictureUrl": null
},
"_links": {
"self": {
"href": "http://localhost:4200/api/v1.0/pricedProducts/1"
},
"pricedProduct": {
"href": "http://localhost:4200/api/v1.0/pricedProducts/1{?projection}",
"templated": true
},
"product": {
"href": "http://localhost:4200/api/v1.0/pricedProducts/1/product"
}
}
}
]
},
"_links": {
"self": {
"href": "http://localhost:4200/api/v1.0/pricedProducts"
},
"profile": {
"href": "http://localhost:4200/api/v1.0/profile/pricedProducts"
}
}
}
This inlines my product, however it does not supply a self link for it. So in my client app, when somebody edits the name of the product, for example, I don't know which product I must update, unless I do an extra request.
What I did next was to create a projection for Product, which I use inside the projection for PricedProduct. A GET to /pricedProducts now yields:
{
"_embedded": {
"pricedProducts": [
{
"price": {
"value": "100.50",
"currency": "EUR"
},
"product": {
"pictureUrl": null,
"description": null,
"name": "Potato",
"_links": {
"self": {
"href": "http://localhost:4200/api/v1.0/products/1{?projection}",
"templated": true
}
}
},
"_links": {
"self": {
"href": "http://localhost:4200/api/v1.0/pricedProducts/1"
},
"pricedProduct": {
"href": "http://localhost:4200/api/v1.0/pricedProducts/1{?projection}",
"templated": true
},
"product": {
"href": "http://localhost:4200/api/v1.0/pricedProducts/1/product"
}
}
}
]
},
"_links": {
"self": {
"href": "http://localhost:4200/api/v1.0/pricedProducts"
},
"profile": {
"href": "http://localhost:4200/api/v1.0/profile/pricedProducts"
}
}
}
Now my Product has a self link, but it points to its projection (http://localhost:4200/api/v1.0/products/1{?projection}). What I want is:
{
"_embedded": {
"pricedProducts": [
{
"price": {
"value": "100.50",
"currency": "RON"
},
"product": {
"pictureUrl": null,
"description": null,
"name": "Potato",
"_links": {
"self": {
"href": "http://localhost:4200/api/v1.0/products/1
}
}
},
"_links": {
"self": {
"href": "http://localhost:4200/api/v1.0/pricedProducts/1"
},
"pricedProduct": {
"href": "http://localhost:4200/api/v1.0/pricedProducts/1{?projection}",
"templated": true
},
"product": {
"href": "http://localhost:4200/api/v1.0/pricedProducts/1/product"
}
}
}
]
},
"_links": {
"self": {
"href": "http://localhost:4200/api/v1.0/pricedProducts"
},
"profile": {
"href": "http://localhost:4200/api/v1.0/profile/pricedProducts"
}
}
}
Thanks!
I think the simplest, and more correct, thing to do is using a child projection and parse the self link on the client side.
It's a little bit old question, but I faced the same problem today and I found a solution:
All you have to do is to REMOVE the #Projection annotation from the embedded projection (ProductProjection) which is used inside the top level projection (PricedProductProjection).
Of course, in this case you cannot use that projection in GET queries, but I assume you don't even need it. (It was created especially for this purpose)
How do I remove a resource from a object's collection using HATEOAS?
A PUT will set the collection.
A PATCH will allow a partial update/add.
But how do I do partial update/remove?
Do I really need to POST the entire uri-list minus 1 in order to remove a single item?
Take this object as an example:
{
"name": "Bob Test",
"description": "this is the descript",
"_links": {
"self": {
"href": "http://localhost/example/1"
},
"example": {
"href": "http://localhost/example/1"
},
"citations": {
"href": "http://localhost/example/1/citations"
},
}
}
The object has many citations (collection):
{
"_embedded": {
"citations": [
{
"content": "asdfasdf",
"anchor": null,
"_links": {
"self": {
"href": "http://localhost/citations/1"
},
"citation": {
"href": "http://localhost/citations/1"
},
"bioMarker": {
"href": "http://localhost/citations/1/example"
}
}
},
{
"content": "c2",
"anchor": "prf",
"_links": {
"self": {
"href": "http://localhost/citations/2"
},
"citation": {
"href": "http://localhost/citations/2"
},
"bioMarker": {
"href": "http://localhost/citations/2/example"
}
}
}
]
},
"_links": {
"self": {
"href": "http://localhost/example/1/citations"
}
}
}
Now let's say I want to remove http://localhost/citations/2, how do I remove this particular item from the http://localhost/example/1/citations collection?
Get the content type from the response and send it in request header "Accept" . Usually it will be "application/xxxxx+json"