2015-10-08 6 views
8

Attualmente ho un progetto utilizzando un controller Spring e Thymeleaf per creare una piccola app browser. La classe controller viene dichiarata comeSpring MVC, Thymeleaf & REST

@Controller public class MyController { 

all'interno del controllore ho una come

@RequestMapping(value = "/foobars", method = RequestMethod.GET) 
String index(Model model, --- more params ---) { 
    //call repository and get foobarsList 
    //model.addAttribute("foobars", foobarsList); 
      ... 
    return "foobars/foobarThymeleafTemplate" 
} 

Il repository chiamata GET definito e ottenere foobarList è una chiamata a un MongoRepository definito come:

public interface FoobarRepository extends MongoRepository< ... cut for brevity> { 

    @RestResource(rel = "by-id") 
    Marker findMarkerById(String id); 

    ... additional @RestResources cut for brevity ... 
} 

Ancora, il Br Owser App sembra grande. Il GET chiama il repository, popola il modello con l'elenco di foobars e Thymeleaf fa tutto ciò con quell'elenco.

PROBLEMA: Ora ho bisogno di accedere a quegli stessi dati da un Android App ed io preferirei usare REST e JSON solo consumare in App Android. Voglio mantenere Thymeleaf ma, se necessario, ridichiarò l'app del browser.

DOMANDA: C'è un modo per utilizzare in qualche modo lo stesso @Controller o dovrò mantenere un secondo FoobarRestController utilizzando @RestController con/restFoobars endpoint? Il secondo controller REST funziona di sicuro, ma sembra un po 'sciatto ... design scadente.

I vostri pensieri e raccomandazioni?

Grazie ancora. -Rich

risposta

1

Il mio approccio preferito è quello di utilizzare l'ereditarietà:

@RequestMapping('/foobars') 
abstract class FoobarBaseController { 

    @RequestMapping 
    abstract listAll() 
} 

@Controller 
class FoobarHtmlController extends FoobarBaseController { 
    @Override ModelAndView listAll() { 
     new ModelAndView('foobars/foobarThymeleafTemplate', [foobars: foobarsList]) 
    } 
} 

@RestController 
@RequestMapping('/foobars', produces = MediaType.APPLICATION_JSON_VALUE) 
class FoobarJsonController extends FoobarBaseController { 
    @Override Collection<Foobar> listAll() { 
     foobarsList 
    } 
} 

In alternativa, se c'è un lavoro significativo deve essere fatto controllare gli ingressi o simili, è possibile implementare che nel BaseController e hanno un abstract listAllResponse(DomainObject foo) che quindi restituisce l'appropriato ModelAndView (HTML) o DTO (JSON).

L'unica insidia di questo approccio è che non è possibile sovrascrivere solo una parte del @RequestMapping, quindi bisogna ripetere parte della classe del mapping quando si specifica il parametro produces, ma è possibile ereditare il-livello di metodo mappature senza problemi.

1

Esporre Crud

Utilizzare il @Controller per fare il lavoro di gestire pagina HTML e utilizzando il repository è possibile esporre l'entità tramite API REST per le azioni di base come CRUD usando SPRING-DATA-REST per esporre i vostri entità. Penso che si sta già facendo, cercando in codice

@RestResource(rel = "by-id") 
    Marker findMarkerById(String id); 

Esporre logica di business

Se si desidera esporre qualsiasi logica di business, è necessario creare un livello Service e semplicemente chiamarlo tramite il vostro @Controller per la pagina Web.e creare un altro controller come @RestController per l'interfaccia API Web.

È possibile notare che non si sta duplicando alcun codice qui, poiché la logica è scritta nel punto singolo nel livello Servizio. Ma usando diversi controller per scopi diversi.

Come non avete bisogno di tutta la logica di pagina web per ottenere esposti ad API, l'uso di controller separato per il riposo può essere un'implementazione design pulito per il codice se è possibile namespace il codice come app.web e app.api.

Cibo per la mente

Utilizzare una completa implementazione API REST per le pagine web e Android. Quindi utilizzare AngualarJS o backboneJs per eseguire l'implementazione lato client con HTML5. Penso che questo sia il futuro.

+0

anche se hai risposto a questo due anni fa, e sono d'accordo con una completa API di riposo per il back-end e quindi utilizzando un framework javascript per il front end dovrebbe essere logicamente quello che la comunità dovrebbe sforzarsi, tuttavia non ci sono ancora quasi domande su stackoverflow e ancora quasi nessuna documentazione o tutorial su come farlo, o la comunità Java è molto resistente a cambiare, o semplicemente non funziona così bene a lungo termine, cosa ne pensi? –