rest - Spring HATEOAS: Only show links when paging without serializing the resource/entity -
according spring hateoas guide, list of resources serialized in way each resource shown content , links:
{ "content": [ { "price": 499.00, "description": "apple tablet device", "name": "ipad", "links": [ { "rel": "self", "href": "http://localhost:8080/product/1" } ], "attributes": { "connector": "socket" } }, { "price": 49.00, "description": "dock iphone/ipad", "name": "dock", "links": [ { "rel": "self", "href": "http://localhost:8080/product/3" } ], "attributes": { "connector": "plug" } } ], "links": [ { "rel": "product.search", "href": "http://localhost:8080/product/search" } ] }
in case of large data structures, think better provide links resources , not resources (especially when paging):
{ "_links": { "items": [{ "href": "http://localhost:8080/product/1" },{ "href": "http://localhost:8080/product/3" }] } }
aside fact decrease size of transferred bytes, suggested hal specification. i'm doing way
@requestmapping(method = requestmethod.get, produces = mediatype.application_json_value) public responseentity root(pageable pageable, final pagedresourcesassembler<entity> assembler) { page<entity> entities = entityrepository.findall(pageable); pagedresources<resource> paged = assembler.toresource(entities, entityresourceassembler.getinstance()); collection<resource> resources = paged.getcontent(); resourcesupport support = new resourcesupport(); (resource r : resources) { link selflink = r.getlink(link.rel_self); support.add(new link(selflink.gethref(), "items")); } return new responseentity<resourcesupport>(support, httpstatus.ok); }
but bit ugly "manually" need fetch self link resources. there better/smarter way achieve want?
i'm going ignore why don't want embed sub-resources (and have less request-response cycles, more expensive part of client request) , answer question best can.
you cannot use built in pagedresourceassembler
want. instead derive resourcesupport
, add links yourself. in situations want link instead of embedding resource (because resource not available hal)
public class pageresource extends resourcesupport { @xmlattribute(name = "page") @jsonproperty("page") private pagemeta pagemeta; public pageresource() { this.pagemeta = new pagemeta(); } public pagemeta getpagemeta() { return pagemeta; } public void setpagemeta(pagemeta pagemeta) { this.pagemeta = pagemeta; } public static class pagemeta { //number of resources on page. @xmlattribute @jsonproperty private long size; //total number of matching resources @xmlattribute @jsonproperty private long totalelements; //total number of page @xmlattribute @jsonproperty private long totalpages; //current page number @xmlattribute @jsonproperty private long number; public pagemeta() { } public pagemeta(long size, long totalelements, long totalpages, long number) { this.size = size; this.totalelements = totalelements; this.totalpages = totalpages; this.number = number; } public long getsize() { return size; } public void setsize(long size) { this.size = size; } public long gettotalelements() { return totalelements; } public void settotalelements(long totalelements) { this.totalelements = totalelements; } public long gettotalpages() { return totalpages; } public void settotalpages(long totalpages) { this.totalpages = totalpages; } public long getnumber() { return number; } public void setnumber(long number) { this.number = number; } } }
is simple implementation, in controller responsible adding next , prev links, along item links.
at point build own pagedresourceassembler
links instead of embedding sub-resources.
small aside...you should consider adding links rel "item" , not "items". it's tempting think of collection of links , give json field key plural name, remember hal spec uses field key link relationship.
compare in html form
<link rel="items" src="http://1"/> <link rel="items" src="http://2"/>
to
<link rel="item" src="http://1"/> <link rel="item" src="http://2"/>
and it's apparent each link's target shared item relationship collection, not "items" each link targets single item in collection.
Comments
Post a Comment