Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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);
    }
}
like image 397
Peter Müller Avatar asked Sep 25 '15 09:09

Peter Müller


2 Answers

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.

like image 135
Peter Müller Avatar answered Nov 02 '22 12:11

Peter Müller


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

like image 27
kyakya Avatar answered Nov 02 '22 12:11

kyakya