title: Create generic controller with spring
body: <p>I created this structure of code. it's more and less generic.</p>
  
  <p>I search to write more generic code.</p>
  
  <p>all my controller should have a save, get, getById</p>
  
  <p>How to have a more generic controller?, 
  how to pass service object, do i need to pass</p>
  
  <p>for other layer, if you think that could be more generic... don't hesitage</p>
  
  <pre><code>@RequestMapping(value = "/rest")
  @RestController
  public class CardsRestController extends BaseController {
  
      private final CardsService cardsService;
  
      @Autowired
      public CardsRestController(final CardsService cardsService) {
          this.CardsService = cardsService;
      }
  
       @GetMapping(value = "/cards")
      public ResponseEntity&lt;Page&lt;CardsDto&gt;&gt; getCards(Pageable page) {
  
          if (page == null) {
              page = getDefaultPageRequest();
          }
  
          return new ResponseEntity&lt;&gt;(cardsService.getCards(page), HttpStatus.OK);
      }
  
      @GetMapping(value = "/cards/{id}")
      public ResponseEntity&lt;CardsDto&gt; getCardsById(@PathVariable("id") Integer id) {
  
          CardsDto Cards = cardsService.getCardsById(id);
  
          return Cards != null
                  ? new ResponseEntity(Cards, HttpStatus.OK)
                  : new ResponseEntity(HttpStatus.NOT_FOUND);
      }
  
  }
  
  
  public abstract class BaseController {
  
      protected PageRequest getDefaultPageRequest() {
          return PageRequest.of(0, 20);
      }
  
  }
  
  
  
  public interface CardsService {
      public void saveCards(CardsDto cardDto);
      public Page&lt;CardsDto&gt; customSearch(CardSearch CardSearch, Pageable page);
      public Page&lt;CardsDto&gt; getCards(Pageable page);
      public CardsDto getCardsById(Integer id);
  }
  
  
  public class CardsServiceImpl extends BaseService&lt;Cards, CardsDto&gt; implements CardsService {
  
      @Autowired
      public CardsServiceImpl(CardsRepository cardsRepository) {
          super(Cards.class);
          this.cardsRepository = cardsRepository;
      }
  
      public CardsRepository cardsRepository;
  
      @Override
      public void saveCards(CardsDto cardDto) {
              save(cardDto);
      }
  
  }
  
  public abstract class BaseService&lt;T, R extends BaseDto&gt; {
      private JpaRepository&lt;T, Integer&gt; repository;
      private final Class&lt; T&gt; clsT;
      public BaseService(Class&lt;T&gt; clsT) {
          this.clsT = clsT;
      }
  
      public Page&lt;R&gt; get(Pageable page, JpaRepository&lt;T, Integer&gt; repository, Function&lt;T, R&gt; convert) {
          Page&lt;T&gt; pageR = repository.findAll(page);
          List&lt;R&gt; dtos = convertsToDto(pageR.getContent(), convert);
          return new PageImpl&lt;&gt;(dtos, page, pageR.getTotalElements());
      }
  
      public R getById(Integer id, Function&lt;T, R&gt; convert){
           Optional&lt;T&gt; beans = repository.findById(id);
  
          if (beans.isPresent()) {
              return convert.apply(beans.get());
          }
  
          return null;
      }
  }
  
  public interface CardsRepository extends JpaRepository&lt;Cards, Integer&gt;, CardsRepositoryCustom {
  }
  
  public interface CardsRepositoryCustom {
  }
  
  @Repository
  public class CardsRepositoryImpl  extends SimpleJpaRepository implements CardsRepositoryCustom{
  
       @PersistenceContext
      private EntityManager em;
  
      @Autowired
      public CardsRepositoryImpl(EntityManager em) {
          super(Cards.class, em);
      }
      ....
  }
  </code></pre>