Closed Rezar00 closed 1 year ago
Just use a CrudRepository (which is not pageable) and consult the Spring documentation.
@toedter Thanks for your response. My issue is not CrudRepository. I don't have a Database. I just call a third-party service and the response is A model which contains a list of another object. I want to expose this list and its data based on your implementation. How can I do that?
Ah, now I understand.
I guess this "list of other objects" does not contain REST resources but just data. In this case you would not even need a Spring HATEOAS Collection recourse, you could just include a List
data structure in your DTO.
If you want to convert the list of objects to a collection of REST resources, you could use the builder from my library.
I called a rest API and get the response. The model is a Product object:
{ "productName": "Statutenwijziging", "productUrl": null, "orderLink": null, "deliveryVariants": [ { "format": "PdfNietGewaarmerkt", "price": 345, "orderLink": null, "link": null, "emailRequired": true }, { "format": "PdfGewaarmerkt", "price": 845, "orderLink": null, "link": null, "emailRequired": true } ], "fromPrice": 345, "productId": "090299cc2099d937", "productCode": "75376498", "boekjaar": null, "boekjaren": null, "deponeringsDatum": "2013-10-01T00:00:00", "tapedForAvg": true, "concernNaam": null, "links": [] },
I have a list of Products. I Used :
@GetMapping(value = "{number}/{productType}", produces = "application/vnd.api+json") public ResponseEntity<List<RepresentationModel<?>>> getAvailableProducts(@PathVariable String number, @PathVariable ProductType productType) {
AvailableProductsResponse availableProducts =
this.productService.getAvailableProducts(number, productType);
List<RepresentationModel<?>> products = new ArrayList<>();
availableProducts.getProducts().forEach(product -> {
products.add(JsonApiModelBuilder.jsonApiModel().model(product).build());
});
return ResponseEntity.ok(products);
}
but in the response json i see: [ { "productName": "Statutenwijziging", "productUrl": null, "orderLink": null, "deliveryVariants": [ { "format": "PdfNietGewaarmerkt", "price": 345, "orderLink": null, "link": null, "emailRequired": true }, { "format": "PdfGewaarmerkt", "price": 845, "orderLink": null, "link": null, "emailRequired": true } ], "fromPrice": 345, "productId": "090299cc2099d937", "productCode": "75376498", "boekjaar": null, "boekjaren": null, "deponeringsDatum": "2013-10-01T00:00:00", "tapedForAvg": true, "concernNaam": null, "links": [] }, { "productName": "Statutenwijziging", "productUrl": null, "orderLink": null, "deliveryVariants": [ { "format": "PdfNietGewaarmerkt", "price": 345, "orderLink": null, "link": null, "emailRequired": true }, { "format": "PdfGewaarmerkt", "price": 845, "orderLink": null, "link": null, "emailRequired": true } ], "fromPrice": 345, "productId": "090299cc0b7ac73b", "productCode": "75376498", "boekjaar": null, "boekjaren": null, "deponeringsDatum": "2013-07-17T00:00:00", "tapedForAvg": true, "concernNaam": null, "links": [] }, { "productName": "Akte van oprichting", "productUrl": null, "orderLink": null, "deliveryVariants": [ { "format": "PdfNietGewaarmerkt", "price": 345, "orderLink": null, "link": null, "emailRequired": true }, { "format": "PdfGewaarmerkt", "price": 845, "orderLink": null, "link": null, "emailRequired": true } ], "fromPrice": 345, "productId": "090299ccda056cfe", "productCode": "13227082", "boekjaar": null, "boekjaren": null, "deponeringsDatum": "1997-06-03T00:00:00", "tapedForAvg": true, "concernNaam": null, "links": [] } ]
Can't represent it as JSON:API standard?
@Data
@JsonIgnoreProperties(ignoreUnknown = true)
@JsonApiTypeForClass(value = "products")
public class Product {
private String productName;
private String productUrl;
private String orderLink;
private List
@Data
public static class DeliveryVariant {
private DeliveryFormat format;
private int price;
private String orderLink;
private String link;
private boolean async;
@JsonProperty("emailRequired")
public void setAsync(String required) {
this.async = StringUtils.equalsIgnoreCase("yes", required);
}
}
}
this is my product class
@Data
@JsonIgnoreProperties(ignoreUnknown = true)
public class AvailableProductsResponse {
@JsonProperty("number")
public String number;
public List
}
You have to use the builder differently and return the result of the builder, like
final JsonApiModelBuilder jsonApiModelBuilder = jsonApiModel().model(availableProducts.getProducts());
return ResponseEntity.ok(jsonApiModelBuilder.build());
Hope this helps.
I got: "Content must not be a collection! Use CollectionModel instead!"
Then convert your collection in a collection model, like
final JsonApiModelBuilder jsonApiModelBuilder =
jsonApiModel().model(CollectionModel.of(availableProducts.getProducts()));
return ResponseEntity.ok(jsonApiModelBuilder.build());
Now I get :
{ "_embedded": { "products": [ { "productName": "Statutenwijziging", "productUrl": null, "orderLink": null, "deliveryVariants": [ { "format": "PdfNietGewaarmerkt", "price": 345, "orderLink": null, "link": null, "emailRequired": true }, { "format": "PdfGewaarmerkt", "price": 845, "orderLink": null, "link": null, "emailRequired": true } ], "fromPrice": 345, "productId": "090299cc2099d937", "productCode": "75376498", "boekjaar": null, "boekjaren": null, "deponeringsDatum": "2013-10-01T00:00:00", "tapedForAvg": true, "concernNaam": null }, { "productName": "Statutenwijziging", "productUrl": null, "orderLink": null, "deliveryVariants": [ { "format": "PdfNietGewaarmerkt", "price": 345, "orderLink": null, "link": null, "emailRequired": true }, { "format": "PdfGewaarmerkt", "price": 845, "orderLink": null, "link": null, "emailRequired": true } ], "fromPrice": 345, "productId": "090299cc0b7ac73b", "productCode": "75376498", "boekjaar": null, "boekjaren": null, "deponeringsDatum": "2013-07-17T00:00:00", "tapedForAvg": true, "concernNaam": null }, { "productName": "Akte van oprichting", "productUrl": null, "orderLink": null, "deliveryVariants": [ { "format": "PdfNietGewaarmerkt", "price": 345, "orderLink": null, "link": null, "emailRequired": true }, { "format": "PdfGewaarmerkt", "price": 845, "orderLink": null, "link": null, "emailRequired": true } ], "fromPrice": 345, "productId": "090299ccda056cfe", "productCode": "13227082", "boekjaar": null, "boekjaren": null, "deponeringsDatum": "1997-06-03T00:00:00", "tapedForAvg": true, "concernNaam": null } ] } }
But still need to have a : {data[ attributes]} structure. Does it need something else?
You have to provide an accept
request header with value application/vnd.api+json
, when you do HTTP requests.
Or, if you want it to be the default, use an annotation for your REST Controller like:
@RequestMapping(produces = JSON_API_VALUE)
public YourRestController {
...
Also take a look at the example in this repo., like the the MovieController
.
@toedter I got "Failed to write request".
Thanks for your answer. I will check the MovieController
How can return a List of objects as JSON:API standard with this implementation? I can see the example is used PageModel. I show a list of objects without PageModel.