2015-10-08 25 views
8

Ich habe derzeit ein Projekt mit einem Spring-Controller und Thymeleaf, um eine kleine Browser-App zu erstellen. Die Controller-Klasse deklariert alsSpring MVC, Thymeleaf & REST

@Controller public class MyController { 

Innerhalb der Controller habe ich einen GET definiert als

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

Der Anruf Repository und bekommen foobarList ist ein Aufruf einer MongoRepository wie folgt definiert:

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

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

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

Wieder der Br Owser App sieht gut aus. Die GET ruft das Repository, füllt das Modell mit der Liste der Foobars und Thymeleaf macht es Sache mit dieser Liste.

PROBLEM: Jetzt muss ich von einer Android App, die gleichen Daten zugreifen, und ich würde es vorziehen, REST zu verwenden und nur konsumieren JSON in der Android App. Ich möchte Thymeleaf behalten, werde aber die Browser-App bei Bedarf umgestalten.

FRAGE: Gibt es eine Möglichkeit, den gleichen @Controller irgendwie zu verwenden, oder muss ich einen zweiten FoobarRestController mit @RestController mit/RestFoobars Endpunkten verwalten? Der zweite REST-Controller funktioniert sicher, aber es scheint irgendwie schlampig ... schlechtes Design.

Ihre Gedanken und Empfehlungen?

Nochmals vielen Dank. -Rich

Antwort

1

Mein bevorzugter Ansatz hier ist die Vererbung zu verwenden:

@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 
    } 
} 

Alternativ kann, wenn es signifikante ist Arbeit Eingänge oder dergleichen Überprüfung getan werden, können Sie das in den BaseController implementieren und ein abstract listAllResponse(DomainObject foo) haben, dass gibt dann das entsprechende (HTML) oder DTO (JSON) zurück.

Die eine pitfall dieses Ansatzes ist, dass Sie nicht nur ein Teil der @RequestMapping außer Kraft setzen kann, so dass man die Klasse des Teil des Mappings wiederholen müssen, wenn Sie den produces Parameter angeben, aber Sie können die Methode Ebene erben Mappings ohne Problem.

1

Expose Crud

Verwenden Sie die @Controller die Arbeit der Umgang mit HTML-Seite und mit dem Repository tun Sie das Unternehmen über Rest-API für die grundlegenden Aktionen wie crud SPRING-DATA-REST unter Verwendung aussetzen können Ihre Einheiten zu belichten. Ich glaube, Sie tun es bereits von

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

Geschäftslogik Blick auf den Code

Expose Wenn Sie Business-Logik verfügbar machen möchten, müssen Sie eine Service Ebene erstellen und sie rufen Sie einfach über Ihre @Controller für die Webseite.und erstellen Sie einen anderen Controller als @RestController für die Web-API-Schnittstelle.

Sie werden feststellen, dass Sie hier keinen Code duplizieren, da die Logik an dem einzelnen Punkt in der Service-Ebene geschrieben wird. Aber verschiedene Controller für verschiedene Zwecke verwenden.

Wie Sie die gesamte Logik in Web-Seite nicht brauchen API ausgesetzt werden, die Verwendung von separaten Controller für REST kann eine saubere Design-Implementierung für Ihren Code, wenn Sie Ihren Code als app.web und app.api Namespace können.

Denkanstösse

für Web-Seiten und android eine vollständige REST-API-Implementierung verwenden. Verwenden Sie dann AngualarJS oder backboneJs, um die clientseitige Implementierung mit HTML5 durchzuführen. Ich denke, das ist die Zukunft.

+0

Obwohl Sie dies vor zwei Jahren geantwortet haben, und ich stimme der Verwendung einer kompletten Rest API für das Back-End und dann mit einem Javascript-Framework für das Front-End sollte logisch sein, was die Gemeinschaft anstreben sollte, aber es gibt noch fast keine Fragen auf stackoverflow und immer noch fast keine dokumentationen oder tutorials, wie dies zu tun ist, ist die java community sehr resistent zu ändern, oder das funktioniert auf lange sicht nicht so gut, was denkst du? –

Verwandte Themen