I am not asking if it is possible, I know it is but I would like to know what's the best way to offer a rest service while having a front end in my application.
I'm developing a Spring Boot application, I currently have a controller that calls jsp pages, and a separate RestController. I want to be able to consume it with an Android application.
So is it correct to have both a Controller and a separate Restcontroller in my application? For example the Rest controller methods will be called from /api/*.
Edit :
I know the difference between the two, but since I want to be able to return a view ( and I shouldn't do that with a RestController) and I want to have a rest service I am wondering if I can have both of them (separately of course).
Thank you so much in advance.
I'd say that it's possible, but considered a bad practice (except for corner cases like a controller for Swagger in a REST application) in a typical, layered, spring app (will get back to that)
you may want to create a multi-module project, that may look like that:
parent project
-- core
-- web api (jsp based)
-- rest api (for android)
both web api and rest api depend on the core.
web api and rest api are separate deployment units. you can deploy them on the same server or run as separate applications (for example using spring boot). Depends on your usecase.
with that you can have your business logic in one place (core).
you may also want to read about ports and adapters architecture, which may give you an idea how to solve this in a more organized way than just having Controllers and RestControllers sitting side by side
Related
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 3 years ago.
Improve this question
So the project I want to convert is at https://github.com/zhongjis/keyword_search_engine_xlsm.
This program intends to build a search engine based on the user input files (xlsm). It extracts content from an XLSM (excel) file first and stores them to the DB. while building up the database, the program will also calculate some special numbers such as td-idf which will be used later for result ranking.
Current technology used:
Gradle
Java 13
MongoDB
What I am trying to do?
convert this console application to a full-stack web application that uses Spring Framework. which means that I want to add a GUI.
I am trying to keep as much original code as possible during this transition. For me, it is ok to modify them to fit the MVC design.
In one sentence, I want to make my current application runs on the Spring framework. it is OK only to have console output.
What are my questions?
even though I did a lot of research on Spring Framework (especially Spring boot). But I am still struggles with what should I do first in order to implement the framework. I would like some suggestions on how to start (or what should I change on my original project). All I learned from the internet is adding various dependencies to build.gradle. But I still have no idea what to do next. Should I start a new Web Application from scratch or try to convert the current one?
Thank you
I tried my best to fill in details. However, this post might still be vague or confusing on some parts and need some clarification. Please feel free to let me know and I am more than willing to do that :)
It appears that you want to create a Web Application.
The easiest way to get started is to use Spring Boot, which is the 'opinionated' version of Spring, meaning that it uses smart defaults. You should start by using the Initializer to generate your project: https://start.spring.io/. Keep generating and testing until you get what you want.
The simplest method is to build an executable JAR, which will contain your web server and can be run anywhere you have Java. This is the default setting on Initializer site above. My advice: Accept Spring Boot defaults until you know what you're doing.
GUI:
The simplest method is to use Thymeleaf templates to display your HTML.
Controller:
Learn how to write a basic controller to return a Thymeleaf template. The simplest way to begin is with standard HTML posting to your controller.
Docs
A great strength of Spring is the ample documentation.
See: https://spring.io/guides/gs/serving-web-content/
and: https://docs.spring.io/spring/docs/current/spring-framework-reference/web.html
I'd suggest you start with Spring Initializr to bootstrap a fully working Spring Boot application. Alternatively, you can use JHipster(https://www.jhipster.tech/) which will create a Spring Boot app AND a front-end for you which you may prefer.
Create a base application
https://start.spring.io/
Select the dependencies you need such a MongoDB:
Build out basic components
So the basic flow in a Spring Boot App is Controller -> Service layer -> Repository.
The Controller will allow you to create REST endpoints annotated with #RestController:
https://spring.io/guides/gs/rest-service/
Then put your business logic from your util package into a service class annotated with #Service.
https://medium.com/stackavenue/why-to-use-service-layer-in-spring-mvc-5f4fc52643c0
You will autowire your Service layer into the Controller using a #Autowired annotation.
Then create a Spring Repository for database operations:
https://docs.spring.io/spring-data/data-commons/docs/1.6.1.RELEASE/reference/html/repositories.html
Then #Autowire your Repository into your Service layer.
In summary, the whole flow is your front-end(Angular, ReactJS etc.) makes a HTTP call to your Spring App which is handled by the Controller which calls the service layer which calls the Repository to perform database operations.
Building a Front-end
You can use Angular for this. A lot of front-end devs prefer React but for a new user, Angular is a more holistic framework in my opinion. https://cli.angular.io/
Install npm(https://www.npmjs.com/get-npm)
Then do the following to get a fully functional Angular app up and running:
npm install -g #angular/cli
ng new my-dream-app
cd my-dream-app
ng serve
Then you can use the Angular HttpClient to make a call to your Spring Boot service: https://angular.io/guide/http
This repo is a couple years old but it contains a full-stack Angular/Spring Boot app that you can check out for reference: https://github.com/anataliocs/Exercise-files-full-stack-app-angular-spring-boot.
You could use Thymeleaf as well(https://spring.io/guides/gs/serving-web-content/) but most modern Full-stack web apps use a separate front-end app such as Angular, React(https://reactjs.org/), Vue.js(https://vuejs.org/) etc.
JHipster
Jhipster will do all this and also hook up a fully working front-end for you. https://www.jhipster.tech/
Courses
I also have full courses on building full-stack apps on LinkedIn learning, but full disclosure, it's not a free service but there is a 30 day trial.
Full-stack app with Angular and Spring Boot
Full-stack app with
JHipster
I will suggest the same as KevinB use SpringBoot/Thymeleaf for easy MVC style application to minimize using too many technology stack.
But before you jump into action remember any migration of project/application into new framework or architecture first needs breaking down the components (source as well as target and then mapping them).
The github project utilizes MONGODB which you would not need to re setup.
You can do the migration in 2 ways, based on functionality i.e build all of backend and front for a functionality at a time
or develop mock rest end points first and then do the UI making call to service end points in spring boot.
I am writing web application which exposes REST interface and web socket for clients. This project interacts with underlying database. The UI layer and overall business logic is handled as separate project. Now I wanted to apply layers in this web application.
I have split my web application as,
1. Service layer (Exposes REST and Websocket)
2. Domain layer (Handling web application's Business logic)
3. Persistance layer (DB access)
Is this separation right? or Should i consider REST as application layer? Is application layer a.k.a service layer? Which is more meaningful here?
The REST interface belongs in the same layer as the UI. It is a way of interacting with your app, just doesn’t have a user interface. I like to put the API in a separate project from the UI so it can be deployed separately and scaled separately. Ideally the UI would use the API for its data access.
With that said, asking this question implies you are designing your own architecture pattern, which is not a good idea. Much bigger brains that mine have attacked and solved this problems many times so you should pick one and use it. The one I find most flexible is the Onion Architecture (https://dzone.com/articles/onion-architecture-is-interesting), which fits well with DDD or Active Record. In the Onion Architecture, though, things are split between interface and implementation in a way that takes some getting used to so if you decide to migrate that way give yourself a little extra time to get accustomed to it. Once you do, you will be happy with the flexibility.
Regarding to the best way to design a system using spring-mvc (REST services) and jQuery . I think exists the following approaches.
One war file in which you have spring services and jQuery stuff, with this approach we have all the domain objects available to be used with spring-mvc, we can create initial jsp pages and then refresh some elements using jQuery calls to our services.
Two war files, one having the spring services and the other contains spring-mvc stuff and jquery, in this case the creation of pages could be done by jsp pages and also refresh elements with jquery calls to our services, but to make this possible we need to have a common library of domain objects to be used in the second war, also internally use restTemplate in some controllers that need to be created (It sounds like duplicate code).
Have one war file running the REST services and a other “package” without any java or spring stuff only jquery, it means all the call and information retrieval must to be done using jquery, initial jsp pages creation cannot be done with this option and all the content are obtained via REST services. (no need of use internal controllers to call services by java)
Thinking about it I realized that one and second have the following disadvantages.
Have services and web stuff in the same war file sound like a bad idea thinking in SOA, the movement of this war will result in move unneeded jquery and web stuff.
Have jsp and jquery stuff mixed not sound like a good idea but I think is a common practice (I wonder why?), using this I think we need to create some controllers in the second war to initially create the web pages, go using restTemplate to obtain initial information and then update or refresh using jquery calls. It feels that a have a controller just to retrieve data to the services, why don’t go directly …
I just want to implement the third approach but the question is: there is any disadvantages that I’m not seeing or any
advice that I should know before use that approach? Also there is any suggestion to handle this kind of systems it will be great to hear something from you, coming from java and jquery developers
I agree with you that version 3 gives you the most flexibility and is what you would typically see in the design world.
Treat the rest and the front end as separate applications entirely. If done correctly, you can have a very robust application capable of proper agility.
Version 1: Load the page in an initial controller call, and use jquery to make subsequent service calls. All code exists within one package.
The disadvantage is tight coupling. You are now restricted to the language of your api, and no longer providing a service based approach to your data and services.
I have seen this version applied mostly when the application developer cares more about async front end calls than a SOA based language.
Version 2: Have a war containing Spring Services, and a war for the JS.
The issues with this method can be overcome with the use of a jar instead of another server application. Though this approach is commonly used, the draw backs are still reliance on external packaging.
Using a jar that contains all the code to hit databases and create domain objects separate from the code that the controllers use to serialize and respond to web requests creates a very clean way to manage your api, however this creates a complexity and an extra component that can be avoided using version 3. It also gives the same odd behavior you see in version 1.
I have seen this approach taken by teams developing pure api applications. I have not seen this done on teams that also require a front end component. Method one or three has been used in these cases.
Version 3: Create an application that deals with just the front end responsibility Create an application that handles the server side responsibility.
In both version 2 and version 3, separate your service calls from your http calls. Make them different because it allows modularity.
For instance, we need to respond to http Requests
#Controller
class MyController{
#Autowired
private MyService service;
#GET
public String getData(String dataId){
return service.getData(dataId);
}
}
and we need to respond to active mq requests
Message m = queueReceiver.receive();
if (m instanceof DataRequest) {
DataRequest message = (DataRequest) request;
queueSender.send(service.getData(request.getDataId())); //service call
} else {
// Handle error
}
Also, it gives you the ability to manage what you need to handle on the http side different from your service side.
#GET
public String getData(HttpRequest request, String dataId){
if(!this.handleAuth(request)){
throw new 403();
}
try{
return service.getData(dataId);
catch(Exception e){
throw new WrappedErrorInProperHttpException(e);
}
}
This allows your service layer to handle tasks meaningful to just those services without needing to handle all the http crap. And lets you deal with all the HTTP crap separate from your service layer.
I have a general question about the correct (or maybe: the best) way to handle data from GUI to DAO.
I built a project where GUI input is being validated and sent directly to a DAO class which handles (via Hibernate) the database updates/inserts.
Now I decided to split DAO and GUI up into two separate projects and use a REST WS with Spring integration to handle the data. I considered this, because I thought this might be a good idea for future projects (advantage of course being the complete separation of the GUI from DAO).
For the moment I have a bit of a problem of making this all work (Spring error creating bean xStreamMarshaller). But before I try unnecessarily I wanted to know: Is that really a good approach?
Is this really a correct way or am I doing something completely unnecessary?
I think this post can be useful for you:
Spring MVC RESTful multiple view - 404 Not Found
I like the idea to work with restful, because you can really split the application not just in the back-end, but in the front-end as well. This way you can just get JSON in your javascript. But of course each case is different each other.
Follows a video about the subject: Designing a REST-ful API Using Spring 3
We have a Spring application which exposes all the business logic as RESTful web services, which is consumed by the jQuery front end. Our jQuery front end code is becoming unmanageable with javascript manipulating the html files. So we are planning to use grails with jquery/bootstrap to overcome these issues. Right now, we are doing a Poc to understand the implications of moving to new stack.
Our current understanding is that we will run two applications - one for grails and one for Spring backend. We can implement CAS to maintain the session between these two apps. Grails will use spring for all data as well as business logic. Our front end communicates only with grails, which in turn connects to Spring as need basis.
I am not sure what are the potential things to look for in the new approach. Can someone provide
feedback on our approach?
Thanks
--Venky
I would suggest to create only one app, in grails. Plug all your existing code into src/java and use groovy domains/services to get data from you existing business logic.
In this way you will not have the overhead to run 2 webapps that will communicate over http to serve one client request.