Skip to content

Embedded curie causes two _links in API response #1540

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
dusan-turajlic opened this issue May 19, 2021 · 7 comments
Closed

Embedded curie causes two _links in API response #1540

dusan-turajlic opened this issue May 19, 2021 · 7 comments
Assignees
Labels
in: mediatypes Media type related functionality type: bug
Milestone

Comments

@dusan-turajlic
Copy link

Hi kindof new to this whole HATEOS thing, but I have gotten some suff working. I'm having a very weird issue related to CurieProvider

I have added the CurieProvider in to my application and it works quite well the weird part is now I'm getting two _links In my API here is an example response

{
  "_embedded": {
    "bp:channelList": [
      {
        "name": "general",
        "subscription": "/channel/general",
        "_links": {
          "self": {
            "href": "https://api.turkuforge.fi/channel/general"
          }
        }
      },
      {
        "name": "random",
        "subscription": "/channel/random",
        "_links": {
          "self": {
            "href": "https://api.turkuforge.fi/channel/random"
          }
        }
      }
    ]
  },
  "_links": {
    "curies": [
      {
        "href": "https://docs.turkuforge.fi/{#rel}",
        "name": "bp",
        "templated": true
      }
    ]
  },
  "_links": {
    "bp:sockjs-endpoint": {
      "href": "https://api.turkuforge.fi/connect"
    },
    "self": {
      "href": "https://api.turkuforge.fi"
    },
    "curies": [
      {
        "href": "https://docs.turkuforge.fi/{#rel}",
        "name": "bp",
        "templated": true
      }
    ]
  }
}

live API can be found here and all the code can be found here https://github.com/TurkuForge/baby-project-server

I have been digging in to the issue and it seems that when I do this (can be found on line 43 in RootApiController)

        val model = HalModelBuilder.halModel()
        getChannels().forEach {
            val link = linkTo<ChannelController> { message(it, null) }
            val channel = Channel(it, link.toUriComponentsBuilder().build().path)
            channel.add(link.withSelfRel())
            model.embed(channel)
        }

it also adds the second link. I'm not sure why this happens, but its very easaly reproducable since it happens no matter what I do

@odrotbohm
Copy link
Member

The API you link to actually shows this document:

{
  "_embedded": {
    "bp:channelList": [
      {
        "name": "general",
        "subscription": "/channel/general",
        "_links": {
          "self": {
            "href": "https://api.turkuforge.fi/channel/general"
          }
        }
      },
      {
        "name": "random",
        "subscription": "/channel/random",
        "_links": {
          "self": {
            "href": "https://api.turkuforge.fi/channel/random"
          }
        }
      }
    ]
  },
  "_links": {
    "bp:sockjs-endpoint": {
      "href": "https://api.turkuforge.fi/connect"
    },
    "self": {
      "href": "https://api.turkuforge.fi"
    },
    "curies": [
      {
        "href": "https://docs.turkuforge.fi/{#rel}",
        "name": "bp",
        "templated": true
      }
    ]
  }
}

which looks correct to me?

@dusan-turajlic
Copy link
Author

@odrotbohm I think you might be looking at something that is parsing the JSON. While developing the API I was looking at it in chrome with a JSON beautifying addon. That's why I didn't catch it before I deployed the API. But one of our engineers who was developing iOS said he is getting two links in the response and then I realized the problem was when adding the embedded.

I am aware I do it a bit weirdly with adding the links after I already run build on the mode but tested locally and adding the links using the model.link method produces the same results.

@odrotbohm
Copy link
Member

I've tried to actually debug the project for an hour now, but have to give up. Would you mind preparing something that's plain Java (so that I am not forced into IDEA) and ideally does not use Gradle? I've tried to run the test case, but IDEA tells me that the used Gradle version cannot run on JDK 16. Please be as simple as possible: Java 8/11, Maven, a failing test. That'd be incredibly helpful, thanks!

@odrotbohm
Copy link
Member

Nevermind, I think I got to the root cause. Working on it.

@odrotbohm odrotbohm added this to the 1.4 M1 milestone Jun 30, 2021
@odrotbohm odrotbohm added in: mediatypes Media type related functionality type: bug and removed process: waiting for feedback labels Jun 30, 2021
@odrotbohm odrotbohm changed the title Embedded Curie causes two _links in API response Embedded curie causes two _links in API response Jun 30, 2021
odrotbohm added a commit that referenced this issue Jun 30, 2021
Embedded elements assembled through a HalModelBuilder expose those through a CollectionModel to make sure that the individual elements get grouped by their link relation and those potentially curied. To indicate a curie link needing to be added because of curied embeds, the serialization adds a magic link to the list of links of that CollectionModel. As the latter is unwrapped, an additiona _links block rendering a curie had been added to the representation rendering the JSON representation invalid, as it now contained two _links fields (the latter stemming from the actual links added to the HAL representation model).

We now tweak the CollectionModel returned to override ….add(Link) and rather route the magic link to the outer representation model, causing the inner one to never accumulate any links in the first place and thus not render an invalid _links.
@odrotbohm
Copy link
Member

This should be fixed in the latest snapshots. Also backported to 1.3.x (#1570) and 1.2.x (#1571).

@dusan-turajlic
Copy link
Author

@odrotbohm Awesome that you got it fixed I was looking in to it my self and had a plan for how to fix it but you beat me to it and your solution is better then what I had in mind 👍🏼 And in the future I will remeber to simplify my examples. I am more use to gradle than maven so I always just use gradle. Also the project was still on java 15 so thats why 16 could not build. I will update it to 16 ASAP. Thanks again for the help!

@odrotbohm
Copy link
Member

odrotbohm commented Jul 1, 2021

Lovely, no worries. Gradle is generally fine, but the version used should work with the latest available Java version then. We generally work with those plus the LTS versions. Kotlin is slightly more problematic, as it restricts me to use IDEA, which – at least for me – reduces my productivity by a large margin. 😬

Anyway, hope you see this working now. Releases coming mid July.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
in: mediatypes Media type related functionality type: bug
Projects
None yet
Development

No branches or pull requests

2 participants