Base path doesn't appear in ResourceProcessor custom links
Asked Answered
M

1

3

In Spring Data REST I'm creating custom links using a ResourceProcessor:

@Component
public class ServiceInstanceProcessor
        implements ResourceProcessor<Resource<ServiceInstance>> {

    @Override
    public Resource<ServiceInstance> process(Resource<ServiceInstance> resource) {
        Long id = resource.getContent().getId();
        ServiceInstanceController controller =
                methodOn(ServiceInstanceController.class);

        resource.add(linkTo(controller.getNodeSummary(id))
                .withRel("nodeSummary"));
        resource.add(linkTo(controller.getHealthBreakdown(id))
                .withRel("healthBreakdown"));
        resource.add(linkTo(controller.getRotationBreakdown(id))
                .withRel("rotationBreakdown"));
        return resource;
    }
}

However the generated links don't include the base path, even though I've marked the controller as @BasePathAwareController and even though the default links do include the base path:

{
  ...

  "_links" : {
  "self" : {
    "href" : "http://localhost:8080/api/serviceInstances/101"
  },
  "serviceInstance" : {
    "href" : "http://localhost:8080/api/serviceInstances/101{?projection}",
    "templated" : true
  },
  "nodeSummary" : {
    "href" : "http://localhost:8080/serviceInstances/101/nodeSummary"
  },
  "healthBreakdown" : {
    "href" : "http://localhost:8080/serviceInstances/101/healthBreakdown"
  },
  "rotationBreakdown" : {
    "href" : "http://localhost:8080/serviceInstances/101/rotationBreakdown"
  },

  ...
}

}

Is there anything else I need to do to get the base path to appear in the links?

Malignant answered 13/10, 2015 at 0:48 Comment(0)
P
1

I suppose it is connected with bug ControllerLinkBuilder does not take Spring Data REST's base path into account and Custom Controller + changed base path doesn't show up in HAL

As workaround I do next:

@Autowired
private final RepositoryRestConfiguration config;

private Link fixLinkSelf(Object invocationValue) {
    return fixLinkTo(invocationValue).withSelfRel();
}

@SneakyThrows
private Link fixLinkTo(Object invocationValue) {
    UriComponentsBuilder uriComponentsBuilder = linkTo(invocationValue).toUriComponentsBuilder();
    URL url = new URL(uriComponentsBuilder.toUriString());
    uriComponentsBuilder.replacePath(config.getBasePath() + url.getPath());
    return new Link(uriComponentsBuilder.toUriString());
}

usage is the same as linkTo:

resources.add(fixLinkSelf(methodOn(VoteController.class).history()));    
resources.add(fixLinkTo(methodOn(VoteController.class).current()).withRel("current"));

Other workaround for simple case based on current request with addPath:

new Link(ServletUriComponentsBuilder.fromCurrentRequest().path(addPath).build().toUriString())
Psi answered 7/8, 2018 at 22:56 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.