UI
Frontend-backend separation architecture design adjustments and explanation
Role definitions:
All sources originate from the protocol generated by proto
, which then generates the application foundation, and the application links to ui
. The general process is:
UI generation rules need to be configured for the app, and the app triggers UI generation.
Open the vue generation flag in {app}/build.gradle
:
hopeStub {
enableFrontVue = true
}
{app}/ui.json
:
{
"projectDir": "../good-app-ui"
}
Last Update: 1.3.9-M2
(2025-05-27 Frontend architecture is changing rapidly, some variables are also changing, use with caution)
auto router
has been moved into the built-in plugin, no longer through app, router is now purely frontend work!
Property | Comment |
---|---|
uiModuleDir | UI module relative path |
httpVendor | ../http , provides useGet /Post |
apiDir | packages/service/src , API output directory(relative to uiModuleDir ) |
requestType | RequestItem form type |
requestModule | ../types form type reference path |
responseType | ResponseItem column type |
responseModule | ../types column type reference path |
pathToUrl | import { pathToUrl } from '../utils' path parsing helper function |
langDir | packages/common/locales/src/langs internationalization output path(relative to uiModuleDir ) |
firstLanguage | zh-CN internationalization, first language |
secondLanguage | en-US internationalization, second language |
typesDir | src/types type output path(relative to uiModuleDir ) |
authSplit | Authorization separator, used for assembling tree structure, default : |
noMerger | false reserved, unused |
alwaysEraseOld | false reserved, unused |
Router
The project has a built-in plugin that automatically scans pages and generates routing rules according to the file directory structure.
router.json
configuration is located under the {module}-ui
module, used to configure the automatic route generation rules for applications under the ui module.
Multiple modules are supported. For example, under apps
there are web1
, web2
, each can be configured independently and isolated from each other.
{
"items": [
{
"moduleDir": "apps/web1"
},{
"moduleDir": "apps/web2"
}
]
}
Property | Comment |
---|---|
moduleDir | Submodule directory under ui module, such as apps/web |
pagesDir | src/pages page directory relative path for this module |
pagesPath | @/pages page module path |
routerOutDir | src/router/auto automatic route output directory |
menuItem | MenuItem menu class name |
menuItemImport | ./types menu class import path |
disable | false whether to disable |
firstLanguage | First language |
secondLanguage | Second language |
langDir | src/locales/langs language output directory |
Simply execute the stub
command to generate UI content:
./gradlew.bat {app}:clean stub build -x test -x stubTest
├─assets
│....
├─locales
│ │
│ └─langs
│ ├─en-US
│ │ app.json
│ │
│ └─zh-CN
│ app.json
├─service
│ │ http.ts
│ │ index.ts
│ │ type.ts
│ │ utils.ts
│ │
│ ├─api
│ │ api-example-api.ts
│ │ api-system-system.ts
│ │ index.ts
│ │
│ ├─form
│ │ TemplateExampleRequest.ts
│ │ UploadBookCoverToLocalRequest.ts
│ │
│ ├─model
│ │ api-example-request-example.ts
│ │ api-example-response-example.ts
│ │ index.ts
│ │ _common.ts
│ │ _error.ts
│ │
│ └─table
│ TemplateExampleResponse.ts
├─types
│ api.d.ts
│ app.d.ts
│ auth.d.ts
Since modern frameworks all use SPA(Single Page Application) architecture, which brings challenges to frontend-backend collaboration, ApiHug attempts to reduce the complexity of understanding and synchronization delays in multi-person frontend-backend collaboration. Therefore, it adopts:
gradle
+ vite
, seamless integration, tasks can call each otherThis achieves maximum collaboration between frontend and backend personnel with minimal context switching and understanding difficulty.
Package resources depend on UI project build, while copying UI resources dist
to runtime static file directory:
//Really Static resource of the UI to Output Dir
tasks.register('copyUIResources', Copy) {
dependsOn project(':good-app-ui').tasks.named('build')
from project(':good-app-ui').layout.projectDirectory.dir('dist')
into "${layout.buildDirectory.get()}/resources/main/static"
}
tasks.named('processResources') {
dependsOn 'copyUIResources'
}
Whether the hope.open.api.spa
flag is enabled:
hope.common.spring.api.spa.wbmvc.SpaMvcConfiguration
controls SPA configuration under SERVLET
hope.common.spring.api.spa.webflux.SpaFluxConfiguration
controls SPA configuration under REACTIVE
URL reverse proxy rules are defined in SpaPathChecker
:
SpaPathChecker DEFAULT =
path ->
!path.startsWith("/api")
&& !path.startsWith("/management")
&& !path.startsWith("/v3/api-docs")
&& !path.startsWith("/hope/meta")
&& !path.startsWith("/h2-console")
&& !path.contains(".")
&& path.matches("/(.*)");
if (checker.passToSpa(path)) {
request.getRequestDispatcher("/index.html").forward(request, response);
return;
}
Default rules:
/api
/management
/v3/api-docs
/h2-console
.
)/(.*)
”For example:
/api/users
→ request goes to backend/about
→ request is forwarded to index.html/static/image.jpg
→ request is served directlyThen you can fully enjoy the same smooth convenience and experience as the frontend!