angular - Spring Boot + Angular 项目结构和架构
问题描述
我正在构建一个由 Spring Boot 后端和 Angular 前端组成的应用程序。以下项目结构有哪些优点和缺点?
要求:
- 行家项目
- spring security(登录+注册)-> 表单?基本的?jwt?
- 角度前端
- Spring Boot 后端
我想到了以下几种可能:
在同一台服务器上运行的 spring 项目中的 Angular
Angular 项目文件夹位于 spring boot 项目中。在构建 Spring Boot 应用程序时,将构建 Angular 项目并将其包含在静态文件夹中。
优点:
- 只有一个可部署
- 轻松使用spring security(表单登录+会话)
- 单一代码库
缺点:
- ui高度依赖后端
- 负载平衡可能会更困难(我不确定)
Spring Boot + Angular 在一个项目和同一台服务器中
Angular 应用程序和 Spring Boot 应用程序位于不同的文件夹中(可能是包含这 2 个 maven 模块的根项目)。在构建 spring 项目时,将构建 angular 项目并将其包含在它的目标文件夹中(类似于:https ://github.com/FraktonDevelopers/spring-boot-angular-maven-build )
优点:
- 只有一个可部署
- 轻松使用spring security(表单登录+会话)
- 单一代码库
- 多模块maven项目
缺点:
- ui高度依赖后端
- 负载平衡可能会更困难(我不确定)
Spring Boot + Angular 在一个项目和不同的服务器中
Angular 项目文件夹与 spring boot 项目在同一个项目中(可能是一个根文件夹,其中有 ui 和后端项目作为单独的文件夹)。后端和 ui 在不同的服务器上运行(angular 不包含在 spring boot 的 jar/war 中)
优点:
- 单一代码库
- 将 ui 与后端解耦缺点:
- 安全性要困难得多(您需要检查用户是否在前端手动登录并手动接收会话/jwt)
Spring Boot + Angular 在不同的项目和不同的服务器中
这两个项目完全分开(两个 git repos)并且没有共同的代码。它们部署在不同的服务器上。
优点:
- 将 ui 与后端解耦缺点:
- 安全性要困难得多(您需要检查用户是否在前端手动登录并手动接收会话/jwt)
- 开发的时候要开两个项目
哪个项目结构是“最佳实践”?还有其他选择吗?我错过了任何优点/缺点?
有没有示例项目/开源项目?我更喜欢生产就绪的架构/结构,最好包括弹簧安全性。
解决方案
安全
“轻松使用spring security”可能没有你想象的那么简单。特别是,“表单登录和会话”部分不能开箱即用:
当客户端发送没有有效(或过期)凭据的请求时,Spring Security 将拦截该请求,并使用登录表单进行响应。如果请求是浏览器中的页面导航,那就太好了,但是如果无效请求到达 API 端点怎么办?发出 XMLHttpRequest 的 Angular 服务不知道如何处理这个意外的 HTML 文档。
还有,会话?我发现会话过期从可用性的角度来看真的很烦人,并且使用 Angular,应用程序状态可以很容易地保存在浏览器中,让我们摆脱服务器端会话(这也很好地防止了 CSRF 攻击,你的 API 可能否则易受攻击,简化负载平衡,并提高后端的可扩展性)。
因此,虽然 Spring Security 可以帮助进行访问控制,但它无法解决登录部分,因此无法从同一台服务器提供 UI 中受益。
其他注意事项
值得注意的是,开发和运行期间的“协同性”可以独立决定。
对于发展,我会考虑:
- 我可能想在不同的前端使用后端吗?
- 是由同一个人进行前端和后端更改,还是由不同的人在不同的时间进行?这些更改会一起发布还是单独发布?
- 我的测试策略是什么?前端和后端是单独测试还是一起测试?
因此,如果我有一群全栈开发人员,每个人都将在所有层上实现他们的功能,一起发布和测试,那么所有东西都将进入同一个存储库并构建(尽管我仍然保留构建前端的能力在开发过程中分开:当我更改我的角度代码时,无需等待弹簧启动重启)。
相比之下,如果我有一个单独的前端和后端团队,他们的版本可能会不同步,并且单独测试,我会创建单独的存储库和构建。
对于运行时,我会考虑:
- 易于部署:在我希望部署到的任何地方一起或单独部署是否更容易?
这几乎是唯一的考虑因素。特别是,不应该有超出 HTTP API 的耦合,因为这种耦合不会带来任何好处,并且会抑制系统的未来发展:如果操作偏好或最佳实践发生变化,我希望能够对此做出响应。例如,如果我以后想为我的 UI 使用 CDN,我应该能够轻松地做到这一点。
推荐阅读
- uwp - 如何为我的 UWP 项目编译 openssl 1.1.1?
- modal-dialog - SwiftUI - 以编程方式呈现工作表
- arrays - Postgresql:将对象附加到列表
- sql-server - Azure SQL DW 中的动态方法,仅从表中获取特定记录的值不为空的列名
- javascript - D3.js 无法更新文本/数字
- outlook-web-addins - 有没有一种方法可以为租户中的所有用户快速禁用 onsend Web 加载项?
- python - 如何在 tkinter 中更改顶级主题
- healthkit - watchos 上的 HealthKit 仅返回上周的结果
- python - Python Tkinter 弹出窗口未显示
- c++ - 求两个数之间的质数问题