In the case of aggregates the version of the aggregate must be the version of the last updated part. With event sourcing this is plain simple, because you can use the event id for versioning.
As of your item collection, the etag of the collection resource must be the etag of the last updated item resource. For each item you must describe the etag in their hyperlinks or if all the hyperlinks have the same version in the same resource, then you can describe the version in their containing resource.
So for example if item 4 was updated latest, then GET /items
should return something like:
{
"type": "/doc/ItemSet",
"version": "3q2teg3234",
"label": "The Collection of Expensive Items",
"size": 2,
"items": [
{
"type": "/doc/Item",
"version": "f233425wfsw",
"id": "1",
"label": "Bugatti Veyron",
"links": [
{
"label": "Read item",
"type": "/doc/Item/methods/read"
},
{
"label": "Update item",
"type": "/doc/Item/methods/update"
}
]
},
{
"type": "/doc/Item",
"version": "3q2teg3234",
"label": "Porsche 911",
"id": "4",
"links": [
{
"label": "Read item",
"type": "/doc/Item/methods/read"
},
{
"label": "Update item",
"type": "/doc/Item/methods/update"
}
]
},
],
"links": [
{
"label": "List items",
"type": "/doc/ItemSet/methods/list"
}
]
}
Ofc. you can send the hyperlink descriptions like /doc/Item/methods/update
in the same document too, but it is better to have something reusable, so for example:
{
"type": "/doc/HyperLinkTemplate",
"method": "PUT",
"uri": "/api/items/{id}",
"headers": {
"ETag": "{version}"
},
"body": {
"label": "{label}"
},
"parameters": {
"version": {
"type": "/doc/ResourceVersion",
"value": {
"type": "doc/Query",
"query": "{context/containingResource/version}"
},
"writeable": false
},
"id": {
"type": "/doc/Item/id",
"value": {
"type": "doc/Query",
"query": "{context/containingResource/id}"
},
"writeable": false
},
"label": {
"type": "/doc/Item/label",
"value": {
"type": "doc/Query",
"query": "{context/containingResource/label}"
},
"writeable": true
}
}
}
It is up to your client how it uses the hyperlink. It is even possible to generate a HTML form from it, though REST is mostly for M2M communication.