javaspringspring-bootspring-hateoashateoas

Return link from Hateos


I have this old Spring Hateos code which I want to migrate to the latest version:

    Map<String, Link> links = new HashMap<>();

    links.put(Link.REL_NEXT, response.getLink(Link.REL_NEXT));
    links.put(Link.REL_PREVIOUS, response.getLink(Link.REL_PREVIOUS));

    addLink(url, response, links, Link.REL_NEXT);
    addLink(url, response, links, Link.REL_PREVIOUS);

  ....

    private void addLink(String baseUrl, WebResource response, Map<String, Link> links, String rel) {
    if (links.get(rel) == null) {
      return;
    }
    Link link = links.get(rel);
    String href = baseUrl;
    if (link.getHref().contains("?")) {
      href = href + link.getHref().substring(link.getHref().indexOf('?'));
    }
    link = Link.of(href, rel);
    response.add(link);
  }

I tried this:

    Map<LinkRelation, Optional> links = new HashMap<>();


    links.put(IanaLinkRelations.SELF, response.getLink(IanaLinkRelations.SELF));

    links.put(IanaLinkRelations.NEXT, response.getLink(IanaLinkRelations.NEXT));

    links.put(IanaLinkRelations.PREVIOUS, response.getLink(IanaLinkRelations.PREVIOUS));


    addLink(apmCoreBaseUrl, response, links, IanaLinkRelations.SELF);

    addLink(apmCoreBaseUrl, response, links, IanaLinkRelations.NEXT);

    addLink(apmCoreBaseUrl, response, links, IanaLinkRelations.PREVIOUS);


private void addLink(String baseUrl, RegistrationsResource response, Map<LinkRelation, Optional> links, LinkRelation rel) {
    if (links.get(rel) == null) {
      return;
    }
    Link link = links.get(rel);
    String href = baseUrl;
    if (link.getHref().contains("?")) {
      href = href + link.getHref().substring(link.getHref().indexOf('?'));
    }
    link = Link.of(href, rel);
    response.add(link);
  }

I get error at this line:

Link link = links.get(rel);

Required type:  Link
Provided:       Optional

Can you advise what is the correct way to implement this?


Solution

  • Based on your comments & question for migration this is what I am suggesting:

    Map<LinkRelation, Optional<Link>> links = new HashMap<LinkRelation, Optional<Link>>();
    
    links.put(IanaLinkRelations.SELF, Optional.of(response.getLink(IanaLinkRelations.SELF)));
    
    links.put(IanaLinkRelations.NEXT, Optional.of(response.getLink(IanaLinkRelations.NEXT)));
    
    links.put(IanaLinkRelations.PREVIOUS, Optional.of(response.getLink(IanaLinkRelations.PREVIOUS)));
    

    ....

    //calling addLinlk

    addLink(apmCoreBaseUrl, response, links, IanaLinkRelations.SELF);
    
    addLink(apmCoreBaseUrl, response, links, IanaLinkRelations.NEXT);
    
    addLink(apmCoreBaseUrl, response, links, IanaLinkRelations.PREVIOUS);
    

    And inside addLink:

    private void addLink(String baseUrl, RegistrationsResource response, Map<LinkRelation, Optional> links, LinkRelation rel) {
    
        links.get(rel).ifPresent(x->{
         Link link = x;
         String href = baseUrl;
        if (link.getHref().contains("?")) {
          href = href + link.getHref().substring(link.getHref().indexOf('?'));
        }
        link = Link.of(href, rel);
        response.add(link);
        });
      }
    

    Tested with Java 11 & spring-hateoas 1.5.0. If you have any different versions, please let me know.

    Edit

    As per OP mentioned, they are using hateoas version 2.6.7. The response reference in OP's code is custom class which extending RepresentationModel. So response.getLink(..) will return type of Optional<Link>. So below workaround will work :

    Map<LinkRelation, Optional<Link>> links = new HashMap<LinkRelation, Optional<Link>>();
    
    links.put(IanaLinkRelations.SELF, response.getLink(IanaLinkRelations.SELF));
    

    ...

    No changes in addLink & no changes in calling addLink required, my original answer still valid for other operations.