Angular2 and Spring Boot. How to maintain the interface?

I have Spring Boot as back-end and Angular2 as front-end. I want to develop them separately and deploy them to Heroku .

They should not have common dependencies and should be in a separate git -repos.

As I understand it, there are two main ways to implement it:

  • run npm build and copy the dist folder to the resource folder of the Spring application so that the latter will process it as static content

  • start the server to serve only the Angular application, which will interact with the Spring application (does the CORS problem appear here?), so there are two servers in total

I think the first way is a little "dirty", since I don’t think copying a folder from one project to another is good.

And the second way is brute force, because I have two servers ( Tomcat and Node.js , for example). Why do I need a server with an Angular app if I can just put Angular inside Spring ?

Is there a more legitimate way to do this?

Thanks.

+6
source share
3 answers

In my organization, we have many Spring Boot and Angular applications. When two servers are not needed, Spring Boot can serve static content from any supported URL (for example, "http:" or "file:"). Just pass this argument to your application at startup:

 --spring.resources.static-locations=<url> 

Spring Boot can also support single-page routing of Angular applications, including the following web MVC configuration. This ensures that even if the user refreshes the page in the browser, Spring Boot will still serve the contents of index.html for other Angular routes.

 public class SinglePageAppWebMvcConfigurer extends WebMvcConfigurerAdapter { @Autowired private ResourceProperties resourceProperties; private String apiPath = "/api"; public SinglePageAppWebMvcConfigurer() { } public SinglePageAppWebMvcConfigurer(String apiPath) { this.apiPath = apiPath; } protected String getApiPath() { return apiPath; } @Override public void addResourceHandlers(ResourceHandlerRegistry registry) { registry.addResourceHandler("/**") .addResourceLocations(resourceProperties.getStaticLocations()) .setCachePeriod(resourceProperties.getCachePeriod()).resourceChain(true) .addResolver(new SinglePageAppResourceResolver()); } private class SinglePageAppResourceResolver extends PathResourceResolver { @Override protected Resource getResource(String resourcePath, Resource location) throws IOException { Resource resource = location.createRelative(resourcePath); if (resource.exists() && resource.isReadable()) { return resource; } else if (getApiPath() != null && ("/" + resourcePath).startsWith(getApiPath())) { return null; } else { LoggerFactory.getLogger(getClass()).info("Routing /" + resourcePath + " to /index.html"); resource = location.createRelative("index.html"); if (resource.exists() && resource.isReadable()) { return resource; } else { return null; } } } } } 
+7
source

So far I have created applications with angular and spring-boot using one git repository, but two different maven projects, one for the backend, one for the interface.

With Maven, than I built one thick jar with built-in Tomcat and deployed it on Amazon EC2.

I also experimented with Heroku, and you could precisely deploy the exact same heap of fat.

For the next project, I would take another approach and deploy all static resources such as html, javascript, etc. for Amazon S3 and only a spring-boot application for a provider such as heroku.

Implementing Frontend in this way seems a lot easier, faster, and cheaper.

There is also a blog post about Using AWS S3 to Store Static Assets and Download Files

+2
source

Option 1 One server process hosting the REST API and another server process supporting Angular UI

This option is the recommended option in the MicroServices architecture, where separate APIs (or a small associated API group) are launched and scaled separately, placing them in separate server processes. In such scenarios, if the Angular user interface is also associated with the REST API, this will mean that every bug fix or extension in the Angular user interface will require rebuilding and redistributing your services. And when we begin to do this, it will defeat the goal of microservices architecture.

Therefore, in such an architecture, only one Angular user interface will host one or more server instances. The Angular user interface, in turn, calls the individual APIs through the API gateway using some service discovery mechanism. However, microservice-based architecture is not trivial - it is complex with many moving parts. This level of complexity can be justified for large projects.

Option 2 One server process that hosts both the REST API and Angular UI

This parameter is the recommended option for small and medium-sized projects, where the user base is several hundred users.

In such projects, create a single repository in which the Maven project will contain two submodules: one for the REST API, and the other for the Angular interface.

Use the Maven frontend-maven-plugin plugin to create part of the user interface. This will automatically download the specified version of NodeJs and invoke the appropriate npm commands to create the Angular project. Finally, using the Maven element, copy the Angular dist folder to the static Spring Boot folder in the resources folder. (Exclude the static folder in the .gitignore file so that the Angular distribution files are not checked in the source control along with the REST API).

Now that Java build starts, it will automatically include a static folder in the fat jar, which will now serve both the API and the Angular user interface.

+2
source

Source: https://habr.com/ru/post/1014536/


All Articles