Saltar al contenido

Implementar métodos personalizados del repositorio de Spring Data y exponerlos a través de REST

Hola, encontramos la solución a lo que buscabas, deslízate y la encontrarás un poco más abajo.

Solución:

Después de dos días, lo he resuelto de esta manera.

Interfaz de repositorio personalizado:

public interface PersonRepositoryCustom 
    Page customFind(String param1, String param2, Pageable pageable);

Implementación de repositorios personalizados

public class PersonRepositoryImpl implements PersonRepositoryCustom

    @Override
    public Page customFind(String param1, String param2, Pageable pageable) 
        // custom query by mongo template, entity manager...
    

Repositorio de datos de Spring:

@RepositoryRestResource(collectionResourceRel = "person", path = "person")
public interface PersonRepository extends MongoRepository, PersonRepositoryCustom 
    Page findByName(@Param("name") String name, Pageable pageable);

Representación de recursos de frijol

public class PersonResource extends org.springframework.hateoas.Resource

    public PersonResource(Person content, Iterable links) 
        super(content, links);
    

Ensamblador de recursos

@Component
public class PersonResourceAssembler extends ResourceAssemblerSupport 

    @Autowired
    RepositoryEntityLinks repositoryEntityLinks;

    public PersonResourceAssembler() 
        super(PersonCustomSearchController.class, PersonResource.class);
    

    @Override
    public PersonResource toResource(Person person) 
        Link personLink = repositoryEntityLinks.linkToSingleResource(Person.class, person.getId());
        Link selfLink = new Link(personLink.getHref(), Link.REL_SELF);
        return new PersonResource(person, Arrays.asList(selfLink, personLink));
    


Controlador Spring MVC personalizado

@BasePathAwareController
@RequestMapping("person/search")
public class PersonCustomSearchController implements ResourceProcessor 

    @Autowired
    PersonRepository personRepository;

    @Autowired
    PersonResourceAssembler personResourceAssembler;

    @Autowired
    private PagedResourcesAssembler pagedResourcesAssembler;

    @RequestMapping(value="customFind", method=RequestMethod.GET)
    public ResponseEntity customFind(@RequestParam String param1, @RequestParam String param2, @PageableDefault Pageable pageable)  personPage.getContent().isEmpty())
            EmbeddedWrappers wrappers = new EmbeddedWrappers(false);
            EmbeddedWrapper wrapper = wrappers.emptyCollectionOf(Person.class);
            List embedded = Collections.singletonList(wrapper);
            adminPagedResources = new PagedResources(embedded, adminPagedResources.getMetadata(), adminPagedResources.getLinks());
        

        return new ResponseEntity(adminPagedResources, HttpStatus.OK);
    

    @Override
    public RepositorySearchesResource process(RepositorySearchesResource repositorySearchesResource) 
        final String search = repositorySearchesResource.getId().getHref();
        final Link customLink = new Link(search + "/customFind?param1,param2,page,size,sort").withRel("customFind");
        repositorySearchesResource.add(customLink);
        return repositorySearchesResource;
    


La razón por la que estos métodos no están expuestos es que básicamente eres libre de implementar lo que quieras en los métodos de repositorio personalizados y, por lo tanto, es imposible razonar sobre el método HTTP correcto para admitir ese recurso en particular.

En su caso, podría estar bien usar un simple GET, en otros casos puede que tenga que ser un POST ya que la ejecución del método tiene efectos secundarios.

La solución actual para esto es crear un controlador personalizado para invocar el método del repositorio.

Para GET métodos que he utilizado el siguiente enfoque:

  • crear un muñeco @Query método en el repositorio (LogRepository.java)
  • crear una interfaz personalizada con el mismo método declarado (LogRepositoryCustom.java)
  • crear una implementación de la interfaz personalizada (LogRepositoryImpl.java)

Con este enfoque, no tengo que administrar las proyecciones ni el ensamblaje de recursos.

@RepositoryRestResource(collectionResourceRel = "log", path = "log")
public interface LogRepository extends PagingAndSortingRepository, 
                                       LogRepositoryCustom 
    //NOTE: This query is just a dummy query
    @Query("select l from Log l where l.id=-1")
    Page findAllFilter(@Param("options") String options,
        @Param("eid") Long[] entityIds,
        @Param("class") String cls,
        Pageable pageable);



public interface LogRepositoryCustom 

    Page findAllFilter(@Param("options") String options,
        @Param("eid") Long[] entityIds,
        @Param("class") String cls,
        Pageable pageable);

En la implementación, puede usar los métodos del repositorio o ir directamente a la capa de persistencia:

public class LogRepositoryImpl implements LogRepositoryCustom{

    @Autowired
    EntityManager entityManager;

    @Autowired
    LogRepository logRepository;

    @Override
    public Page findAllFilter(
        @Param("options") String options,
        @Param( "eid") Long[] entityIds,
        @Param( "class"   ) String cls,
        Pageable pageable) 

Si para ti ha sido de provecho nuestro artículo, agradeceríamos que lo compartas con otros programadores de esta manera nos ayudas a extender esta información.

¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)



Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *