Peter Müller
Peter Müller

Reputation: 273

Spring Data Rest - Add link to search endpoint

In our Spring-Data-Rest Project we have a custom (fuzzy) search on a /buergers/search/findBuergerFuzzy?searchString="..." endpoint.

Is it possible to add a link for it on the /buergers/search endpoint (Without overriding the automatically exposed Repository findBy Methods)?

The Controller exposing the search:

@BasePathAwareController
@RequestMapping("/buergers/search/")
public class BuergerSearchController {

    @Autowired
    QueryService service;

    @RequestMapping(value = "/findBuergerFuzzy", method = RequestMethod.GET)
    public
    @ResponseBody
    ResponseEntity<?> findBuergerFuzzy(PersistentEntityResourceAssembler assembler, @Param("searchString") String searchString) {
        if (searchString.length() < 3)
            throw new IllegalArgumentException("Search String must be at least 3 chars long.");
        List<Buerger> list = service.query(searchString, Buerger.class, new String[]{"vorname", "nachname", "geburtsdatum", "augenfarbe"});
        final List<PersistentEntityResource> collect = list.stream().map(assembler::toResource).collect(Collectors.toList());
        return new ResponseEntity<Object>(new Resources<>(collect), HttpStatus.OK);
    }
}

Upvotes: 7

Views: 2960

Answers (2)

Peter M&#252;ller
Peter M&#252;ller

Reputation: 273

UPDATE: This is an outdated workaround answer. Upgrade to Spring HATEOAS 1.0.


Old Workaround:

Digging the spring-data-rest source i found the RepositorySearchesResource which seems to solve the problem.

@Component
public class SearchResourcesProcessor implements ResourceProcessor<RepositorySearchesResource> {

    @Override
    public RepositorySearchesResource process(RepositorySearchesResource repositorySearchesResource) {
        final String search = repositorySearchesResource.getId().getHref();
        final Link findFullTextFuzzy = new Link(search + "/findFullTextFuzzy{?q}").withRel("findFullTextFuzzy");
        repositorySearchesResource.add(findFullTextFuzzy);

        return repositorySearchesResource;
    }
}

Because we generate this code by templates, this is sufficient and fullfills our needs. Make sure to check the comments for the right and safe way.

Upvotes: 7

Jess
Jess

Reputation: 3715

Version

migrate-to-1.0.changes

ResourceSupport is now RepresentationModel

Resource is now EntityModel

Resources is now CollectionModel

PagedResources is now PagedModel

Code

The code for new version:

import org.springframework.data.rest.webmvc.RepositorySearchesResource;
import org.springframework.hateoas.Link;
import org.springframework.hateoas.server.RepresentationModelProcessor;
import org.springframework.stereotype.Component;

@Component
public class RepositorySearchesProcessor implements RepresentationModelProcessor<RepositorySearchesResource> {

    @Override
    public RepositorySearchesResource process(RepositorySearchesResource model) {
        System.out.println(model.getDomainType());
        model.add(Link.of(model.getRequiredLink("self").getHref() + "/findFullTextFuzzy{?q}").withRel("findFullTextFuzzy"));
        return model;
    }
}

How

About how to find what resource or model you use, after setting breakpoints in each method of RepresentationModel, you maybe find something useful :

enter image description here

Upvotes: 2

Related Questions