change default structure of HATEOAS links - spring-hateoas

How to change the default structure of Hateoas links:
"first": {
"href": "http://localhost:8081/api/offer/?page=0&size=20"
},
"self": {
"href": "http://localhost:8081/api/offer/"
},
"next": {
"href": "http://localhost:8081/api/offer/?page=1&size=20"
},
"last": {
"href": "http://localhost:8081/api/offer/?page=2&size=20"
}
to be like this:
{
"href": "http://localhost:8081/api/offer/?page=0&size=20",
"rel" : "next",
"method": "GET"
},

Related

How to de (serialize) _links so that value of "rel" value appear as element and _link as nested json

Spring hatios latest is keeping links as array rather than nested json and keeping relation name as "rel". We want "rel" value as child jsons root name. Please see the current and expected behaviour.
CURRENT BEHAVIOUR:
[
{
"id": "id-1",
"name": "abc",
"description": "abc",
"enrollments": [
{
"links": [
{
"rel": "fees",
"id": "feesId-1",
"href": "xyz"
},
{
"rel": "rates",
"id": "ratesId-1",
"href": "abc"
}
]
}
]
}
]
EXPECTED:
[
{
"id": "id-1",
"name": "abc",
"description": "abc",
"enrollments": [
{
"id": "1",
"end_timestamp": "2025-12-31T16:06:05Z",
"_links": {
"rates": {
"id": "ratesId-1",
"href": "abc"
},
"fees": {
"id": "feesId-1",
"href": "xyz"
}
}
}
]
}
]
Returning CollectionModel instead of List resoloved the issue in my case.

Parametarized links in HAL json

Assuming I have an endpoint GET /api/foos/{id} which has optional parameters: includes, query, type should I create a link for each of the 'usecases' or can I include it as a single link?
Should it look more like this:
"_links":{
"self": { "href": "/api/foos/1" },
"includes": { "href": "/api/foos/1{?includes}", "templated": true },
"query": { "href": "/api/foos/1{?query}", "templated": true },
"type": { "href": "/api/foos/1{?type}", "templated": true },
}
Or maybe like this:
"_links":{
"self": { "href": "/api/foos/1" },
"query": { "href": "/api/foos/1{?includes}{?query}{?type}", "templated": true },
}
What if I also have paging related links, like next, prev etc. Should I include these templates for them, too? For example:
"next": { "href": "/api/foos?page=2{?includes}", "templated": true }
According to RFC6570, Section 3.2.1 (which is the foundation for URL templating) you can add multiple parameters and parameter without a value will be ignored:
A variable that is undefined (Section 2.3) has no value and is ignored by the expansion process.
That means for your example that you can use following HAL response:
"_links":{
"self": { "href": "/api/foos/1" },
"query": { "href": "/api/foos/1{?includes,query,type}", "templated": true },
}
And it should work for your paging example as well.

Troble finding URN of Item from BIM 360 using Autodesk Forge

We have our files in BIM 360 container. We are trying to create the viewer app which consume the BIM360 file and display it in browser, the sample code which available in Forge site for Viewer is working fine in our local environment but we are facing issue with accessing BIM360 urn in same app (we already tried with the 3- legged authentication token too ). Could you please guide us to get the right URN for the file which are stored in BIM360 container? Please find the sample URN (we have converted to base64 while accessing in viewer app)which belongs to the DWG file in BIM360 , kindly let us know whether it is right one or not.
urn:adsk.objects:os.object:wip.dm.prod/7c21a6f0-41c9-42ae-a2b2-4b5741fa4d0c.dwg
urn:adsk.objects:os.object:wip.dm.prod/9ece42b9-c71c-4a27-90bb-87775f370164.dwg
Also please find the item details response json,
{
"jsonapi": {
"version": "1.0"
},
"links": {
"self": {
"href": "https://developer.api.autodesk.com/data/v1/projects/b.56fded29-645c-44b6-9498-29c0f9517fec/items/urn:adsk.wipprod:dm.lineage:1sbrvwIVRJ6J_hnfeVDA2g"
}
},
"data": {
"type": "items",
"id": "urn:adsk.wipprod:dm.lineage:1sbrvwIVRJ6J_hnfeVDA2g",
"attributes": {
"displayName": "bandra ga.dwg",
"createTime": "2021-02-16T11:06:47.0000000Z",
"createUserId": "8DCHNK3XFCM2",
"createUserName": "VBSL System Integrator",
"lastModifiedTime": "2021-02-16T11:06:47.0000000Z",
"lastModifiedUserId": "8DCHNK3XFCM2",
"lastModifiedUserName": "VBSL System Integrator",
"hidden": false,
"reserved": false,
"extension": {
"type": "items:autodesk.bim360:File",
"version": "1.0",
"schema": {
"href": "https://developer.api.autodesk.com/schema/v1/versions/items:autodesk.bim360:File-1.0"
},
"data": {
"sourceFileName": "bandra ga.dwg"
}
}
},
"links": {
"self": {
"href": "https://developer.api.autodesk.com/data/v1/projects/b.56fded29-645c-44b6-9498-29c0f9517fec/items/urn:adsk.wipprod:dm.lineage:1sbrvwIVRJ6J_hnfeVDA2g"
},
"webView": {
"href": "https://docs.b360.autodesk.com/projects/56fded29-645c-44b6-9498-29c0f9517fec/folders/urn%3Aadsk.wipprod%3Afs.folder%3Aco.nPlZOfdwQQiTrkXjS0FVVw/detail/viewer/items/urn%3Aadsk.wipprod%3Adm.lineage%3A1sbrvwIVRJ6J_hnfeVDA2g"
}
},
"relationships": {
"tip": {
"data": {
"type": "versions",
"id": "urn:adsk.wipprod:fs.file:vf.1sbrvwIVRJ6J_hnfeVDA2g?version=1"
},
"links": {
"related": {
"href": "https://developer.api.autodesk.com/data/v1/projects/b.56fded29-645c-44b6-9498-29c0f9517fec/items/urn:adsk.wipprod:dm.lineage:1sbrvwIVRJ6J_hnfeVDA2g/tip"
}
}
},
"versions": {
"links": {
"related": {
"href": "https://developer.api.autodesk.com/data/v1/projects/b.56fded29-645c-44b6-9498-29c0f9517fec/items/urn:adsk.wipprod:dm.lineage:1sbrvwIVRJ6J_hnfeVDA2g/versions"
}
}
},
"parent": {
"data": {
"type": "folders",
"id": "urn:adsk.wipprod:fs.folder:co.nPlZOfdwQQiTrkXjS0FVVw"
},
"links": {
"related": {
"href": "https://developer.api.autodesk.com/data/v1/projects/b.56fded29-645c-44b6-9498-29c0f9517fec/items/urn:adsk.wipprod:dm.lineage:1sbrvwIVRJ6J_hnfeVDA2g/parent"
}
}
},
"refs": {
"links": {
"self": {
"href": "https://developer.api.autodesk.com/data/v1/projects/b.56fded29-645c-44b6-9498-29c0f9517fec/items/urn:adsk.wipprod:dm.lineage:1sbrvwIVRJ6J_hnfeVDA2g/relationships/refs"
},
"related": {
"href": "https://developer.api.autodesk.com/data/v1/projects/b.56fded29-645c-44b6-9498-29c0f9517fec/items/urn:adsk.wipprod:dm.lineage:1sbrvwIVRJ6J_hnfeVDA2g/refs"
}
}
},
"links": {
"links": {
"self": {
"href": "https://developer.api.autodesk.com/data/v1/projects/b.56fded29-645c-44b6-9498-29c0f9517fec/items/urn:adsk.wipprod:dm.lineage:1sbrvwIVRJ6J_hnfeVDA2g/relationships/links"
}
}
}
}
},
"included": [
{
"type": "versions",
"id": "urn:adsk.wipprod:fs.file:vf.1sbrvwIVRJ6J_hnfeVDA2g?version=1",
"attributes": {
"name": "bandra ga.dwg",
"displayName": "bandra ga.dwg",
"createTime": "2021-02-16T11:06:47.0000000Z",
"createUserId": "8DCHNK3XFCM2",
"createUserName": "VBSL System Integrator",
"lastModifiedTime": "2021-02-16T11:08:00.0000000Z",
"lastModifiedUserId": "8DCHNK3XFCM2",
"lastModifiedUserName": "VBSL System Integrator",
"versionNumber": 1,
"storageSize": 2227450,
"fileType": "dwg",
"extension": {
"type": "versions:autodesk.bim360:File",
"version": "1.0",
"schema": {
"href": "https://developer.api.autodesk.com/schema/v1/versions/versions:autodesk.bim360:File-1.0"
},
"data": {
"processState": "PROCESSING_COMPLETE",
"extractionState": "SUCCESS",
"splittingState": "NOT_SPLIT",
"reviewState": "NOT_IN_REVIEW",
"revisionDisplayLabel": "1",
"sourceFileName": "bandra ga.dwg"
}
}
},
"links": {
"self": {
"href": "https://developer.api.autodesk.com/data/v1/projects/b.56fded29-645c-44b6-9498-29c0f9517fec/versions/urn:adsk.wipprod:fs.file:vf.1sbrvwIVRJ6J_hnfeVDA2g%3Fversion=1"
},
"webView": {
"href": "https://docs.b360.autodesk.com/projects/56fded29-645c-44b6-9498-29c0f9517fec/folders/urn%3Aadsk.wipprod%3Afs.folder%3Aco.nPlZOfdwQQiTrkXjS0FVVw/detail/viewer/items/urn%3Aadsk.wipprod%3Afs.file%3Avf.1sbrvwIVRJ6J_hnfeVDA2g%3Fversion%3D1"
}
},
"relationships": {
"item": {
"data": {
"type": "items",
"id": "urn:adsk.wipprod:dm.lineage:1sbrvwIVRJ6J_hnfeVDA2g"
},
"links": {
"related": {
"href": "https://developer.api.autodesk.com/data/v1/projects/b.56fded29-645c-44b6-9498-29c0f9517fec/versions/urn:adsk.wipprod:fs.file:vf.1sbrvwIVRJ6J_hnfeVDA2g%3Fversion=1/item"
}
}
},
"links": {
"links": {
"self": {
"href": "https://developer.api.autodesk.com/data/v1/projects/b.56fded29-645c-44b6-9498-29c0f9517fec/versions/urn:adsk.wipprod:fs.file:vf.1sbrvwIVRJ6J_hnfeVDA2g%3Fversion=1/relationships/links"
}
}
},
"refs": {
"links": {
"self": {
"href": "https://developer.api.autodesk.com/data/v1/projects/b.56fded29-645c-44b6-9498-29c0f9517fec/versions/urn:adsk.wipprod:fs.file:vf.1sbrvwIVRJ6J_hnfeVDA2g%3Fversion=1/relationships/refs"
},
"related": {
"href": "https://developer.api.autodesk.com/data/v1/projects/b.56fded29-645c-44b6-9498-29c0f9517fec/versions/urn:adsk.wipprod:fs.file:vf.1sbrvwIVRJ6J_hnfeVDA2g%3Fversion=1/refs"
}
}
},
"downloadFormats": {
"links": {
"related": {
"href": "https://developer.api.autodesk.com/data/v1/projects/b.56fded29-645c-44b6-9498-29c0f9517fec/versions/urn:adsk.wipprod:fs.file:vf.1sbrvwIVRJ6J_hnfeVDA2g%3Fversion=1/downloadFormats"
}
}
},
"derivatives": {
"data": {
"type": "derivatives",
"id": "dXJuOmFkc2sud2lwcHJvZDpmcy5maWxlOnZmLjFzYnJ2d0lWUko2Sl9obmZlVkRBMmc_dmVyc2lvbj0x"
},
"meta": {
"link": {
"href": "https://developer.api.autodesk.com/modelderivative/v2/designdata/dXJuOmFkc2sud2lwcHJvZDpmcy5maWxlOnZmLjFzYnJ2d0lWUko2Sl9obmZlVkRBMmc_dmVyc2lvbj0x/manifest?scopes=b360project.56fded29-645c-44b6-9498-29c0f9517fec,O2tenant.5902118"
}
}
},
"thumbnails": {
"data": {
"type": "thumbnails",
"id": "dXJuOmFkc2sud2lwcHJvZDpmcy5maWxlOnZmLjFzYnJ2d0lWUko2Sl9obmZlVkRBMmc_dmVyc2lvbj0x"
},
"meta": {
"link": {
"href": "https://developer.api.autodesk.com/modelderivative/v2/designdata/dXJuOmFkc2sud2lwcHJvZDpmcy5maWxlOnZmLjFzYnJ2d0lWUko2Sl9obmZlVkRBMmc_dmVyc2lvbj0x/thumbnail?scopes=b360project.56fded29-645c-44b6-9498-29c0f9517fec,O2tenant.5902118"
}
}
},
"storage": {
"data": {
"type": "objects",
"id": "urn:adsk.objects:os.object:wip.dm.prod/9ece42b9-c71c-4a27-90bb-87775f370164.dwg"
},
"meta": {
"link": {
"href": "https://developer.api.autodesk.com/oss/v2/buckets/wip.dm.prod/objects/9ece42b9-c71c-4a27-90bb-87775f370164.dwg?scopes=b360project.56fded29-645c-44b6-9498-29c0f9517fec,O2tenant.5902118"
}
}
}
}
}
]
}
It's here: dXJuOmFkc2sud2lwcHJvZDpmcy5maWxlOnZmLjFzYnJ2d0lWUko2Sl9obmZlVkRBMmc_dmVyc2lvbj0x
"derivatives": {
"data": {
"type": "derivatives",
"id": "dXJuOmFkc2sud2lwcHJvZDpmcy5maWxlOnZmLjFzYnJ2d0lWUko2Sl9obmZlVkRBMmc_dmVyc2lvbj0x"
},
"meta": {
"link": {
"href": "https://developer.api.autodesk.com/modelderivative/v2/designdata/dXJuOmFkc2sud2lwcHJvZDpmcy5maWxlOnZmLjFzYnJ2d0lWUko2Sl9obmZlVkRBMmc_dmVyc2lvbj0x/manifest?scopes=b360project.56fded29-645c-44b6-9498-29c0f9517fec,O2tenant.5902118"
}
}
},
To get the storage location of the an item (in your case urn:adsk.wipprod:dm.lineage:1sbrvwIVRJ6J_hnfeVDA2g), query the data of the tip (latest version) of the item using {{FORGE_HOST}}/data/v1/projects/:project/items/:item/tip (in your case, you can simply add /tip to your .links.self.href, ie. https://developer.api.autodesk.com/data/v1/projects/b.56fded29-645c-44b6-9498-29c0f9517fec/items/urn:adsk.wipprod:dm.lineage:1sbrvwIVRJ6J_hnfeVDA2g/tip.
This will return details of the latest version of the item (docs).
There, you should find data.relationships.storage.data.id, which is the the storage urn.

How can I download plan pdf file by bim360 api or sdk?

According to the documentation (https://forge.autodesk.com/en/docs/data/v2/tutorials/download-file/)
I should get the storage object id from included.relationships.storage.data.id.
I can do it for all files uploaded to the bim360 except plans pdf files.
There is nothing about 'storage' in a whole response.
Here is "included" from my response:
'''
"included": [
{
"type": "versions",
"id": "XXX",
"attributes": {
"name": "1ST FLOOR PLAN",
"displayName": "1ST FLOOR PLAN",
"createTime": "2019-01-10T09:19:16Z",
"createUserId": "3MYGKJ73V3SD",
"createUserName": "XXX",
"lastModifiedTime": "2019-01-10T09:19:19Z",
"lastModifiedUserId": "XXX",
"lastModifiedUserName": "XXX",
"versionNumber": 1,
"extension": {
"type": "versions:autodesk.bim360:Document",
"version": "1.0",
"schema": {
"href": "https://developer.api.autodesk.com/schema/v1/versions/versions:autodesk.bim360:Document-1.0"
},
"data": {
"processState": "PROCESSING_COMPLETE",
"viewableId": "1",
"viewableGuid": "XXX",
"viewableName": "(1)",
"viewableOrder": 1,
"sourceFileName": "A1-1 DIMS FIRST FLOOR DIMENSION PLAN_V1_2019-01-10_09-54-54am.pdf"
}
}
},
"links": {
"self": {
"href": "XXX"
}
},
"relationships": {
"item": {
"data": {
"type": "items",
"id": "XXX"
},
"links": {
"related": {
"href": "XXX"
}
}
},
"refs": {
"links": {
"self": {
"href": "XXX"
},
"related": {
"href": "XXX"
}
}
},
"links": {
"links": {
"self": {
"href": "XXX"
}
}
},
"downloadFormats": {
"links": {
"related": {
"href": "XXX"
}
}
}
}
}
]
'''
How can I deal with it?
Yes, please call GET versions/:version_id/relationships/refs instead. Since the item listed in the Plan folder is a type of items:autodesk.bim360:Document, this type item won't have storage attribute shown in its responses of GET versions/:version_id and GET items/:item_id directly. see also here: Download a Document with Autodesk API

Trouble with JSON Array Form

I can't figure out why this is not valid JSON after testing it with jsonlint.com. It's just an array of objects and I don't see anything missing or out of place.
[
{
“rel”: “self”,
"href": "http://ourdomain/persons",
"name": {
"last": "best"
}
},
{
“rel”: “self”,
"href": "http://ourdomain/persons",
"name": {
"last": "bet"
}
},
{
“rel”: “self”,
"href": "http://ourdomain/persons",
"name": {
"last": "brown"
}
}
]
Look at the quotation marks wrapping rel and self.
[
{
"rel": "self",
"href": "http://ourdomain/persons",
"name": {
"last": "best"
}
},
{
"rel": "self",
"href": "http://ourdomain/persons",
"name": {
"last": "bet"
}
},
{
"rel": "self",
"href": "http://ourdomain/persons",
"name": {
"last": "brown"
}
}
]
DONE!
The problem you've got is the quotes are being replaced with another HTML character.
If you look here “rel”: “self”, you'll noticed that it's using “ and not ". Replace them and you should be fine.