-
Notifications
You must be signed in to change notification settings - Fork 4
API & Backend
This page documents the REST API exposed by the methodologistUI-backend, how the frontend authenticates, and how the WebSocket-based LSP connections work.
The full interactive API reference is available via Swagger UI at:
http://localhost:9811/swagger-ui.html
All REST endpoints are prefixed with /api/v1. The base URL is configured per environment via REACT_APP_API_BASE_URL.
| Environment | Base URL |
|---|---|
| Local | http://localhost:9811 |
| Staging | BW-Cloud instance (see .env.staging) |
All endpoints except sign-up, login, forgot-password, and token refresh require a valid JWT in the Authorization header:
Authorization: Bearer <accessToken>
Tokens are issued by the backend after validating credentials against Keycloak. The frontend stores them in localStorage under auth.access_token and auth.refresh_token.
sequenceDiagram
actor User
participant FE as Frontend
participant BE as Backend
participant KC as Keycloak
User->>FE: Enter credentials
FE->>BE: POST /api/v1/users/login
BE->>KC: Validate
KC-->>BE: OK
BE-->>FE: { accessToken, refreshToken }
Note over FE,BE: Token expiry
FE->>BE: POST /api/v1/users/access-token/by-refresh-token
BE-->>FE: New tokens
| Method | Endpoint | Description | Auth required |
|---|---|---|---|
POST |
/api/v1/users/login |
Sign in with username + password, returns token pair | No |
POST |
/api/v1/users/sign-up |
Register a new account | No |
POST |
/api/v1/users/access-token/by-refresh-token |
Exchange refresh token for a new access token | No |
POST |
/api/v1/users/forgot-password |
Send password reset email | No |
POST |
/api/v1/users/verify-otp |
Verify email with OTP code | Yes (unverified) |
POST |
/api/v1/users/resend-otp |
Request a new OTP code | Yes (unverified) |
GET |
/api/v1/users |
Get current user info (from JWT) | Yes |
PUT |
/api/v1/users/{id} |
Update first name and last name | Yes |
PUT |
/api/v1/users/change-password |
Change password (requires current password) | Yes |
GET |
/api/v1/users/search |
Search users by name/email (for member invite) | Yes |
| Method | Endpoint | Description |
|---|---|---|
GET |
/api/v1/vsums/find-all |
List all VSUMs the user has access to (paginated) |
GET |
/api/v1/vsums/find-all-removed |
List soft-deleted VSUMs (paginated) |
POST |
/api/v1/vsums |
Create a new VSUM |
GET |
/api/v1/vsums/{id} |
Get a single VSUM |
GET |
/api/v1/vsums/{id}/details |
Get VSUM with metamodels and relations (canvas load) |
PUT |
/api/v1/vsums/{id} |
Rename a VSUM |
PUT |
/api/v1/vsums/{id}/sync-changes |
Save canvas state (metamodels + reaction edges) |
GET |
/api/v1/vsums/{id}/build/check |
Validate VSUM configuration |
GET |
/api/v1/vsums/{id}/build/artifact |
Build and download artifact as .zip
|
DELETE |
/api/v1/vsums/{id} |
Soft-delete a VSUM |
PUT |
/api/v1/vsums/{id}/recovery |
Recover a soft-deleted VSUM |
| Method | Endpoint | Description |
|---|---|---|
GET |
/api/v1/vsum-histories/find-all/vsumId={vsumId} |
List available saved versions of a VSUM |
PUT |
/api/v1/vsums/{versionId}/recovery |
Restore a specific VSUM version |
| Method | Endpoint | Description |
|---|---|---|
GET |
/api/v1/vsum-users/vsumId={vsumId} |
List all members of a VSUM |
POST |
/api/v1/vsum-users/add-member |
Add a user as a member of a VSUM |
DELETE |
/api/v1/vsum-users/{id}/remove-member |
Remove a member from a VSUM |
| Method | Endpoint | Description |
|---|---|---|
POST |
/api/v1/meta-models |
Create a metamodel record (after uploading files) |
GET |
/api/v1/meta-models |
List all metamodels accessible to the user |
GET |
/api/v1/meta-models/find-all |
Search/filter metamodels by domain, keyword, etc. |
GET |
/api/v1/meta-models/{id} |
Get a single metamodel |
PUT |
/api/v1/meta-models/{id} |
Update metamodel metadata |
DELETE |
/api/v1/meta-models/{id} |
Delete a metamodel |
| Method | Endpoint | Description |
|---|---|---|
POST |
/api/v1/files |
Upload a file (ECORE, GEN_MODEL, or REACTION type) |
GET |
/api/v1/files/{id} |
Download/read a file by ID |
PUT |
/api/v1/files/{id} |
Update an existing file (e.g. save reaction code) |
DELETE |
/api/v1/files/{id} |
Delete a file |
Files are uploaded separately and then referenced by ID when creating or updating a metamodel or reaction.
The save action on the canvas calls PUT /api/v1/vsums/{id}/sync-changes with the following payload:
{
"metaModelIds": [1, 2, 3],
"metaModelRelationRequests": [
{
"sourceId": 1,
"targetId": 2,
"reactionFileId": 42
}
]
}metaModelIds is the list of metamodels currently on the canvas. metaModelRelationRequests describes each reaction edge — source metamodel, target metamodel, and the ID of the .reactions file (0 if not yet initialized).
The backend exposes two WebSocket endpoints, one per LSP:
| LSP | WebSocket path | JAR |
|---|---|---|
| Reactions DSL | /lsp/reactions |
tools.vitruv.dsls.reactions.ide.jar |
| NeoJoin | /lsp/neojoin |
tools.vitruv.neojoin.frontend.ide.jar |
Each connection spawns a dedicated Xtext LSP process for that session. The frontend communicates with it using JSON-RPC over the WebSocket, proxied transparently by the backend.
sequenceDiagram
participant ME as Monaco Editor
participant BE as Backend WS endpoint
participant LSP as Xtext Process
ME->>BE: WS connect /lsp/reactions
BE->>LSP: Spawn process, write .ecore files to temp workspace
loop JSON-RPC
ME->>LSP: initialize, didOpen, didChange, completion/…
LSP-->>ME: diagnostics, completions, hover
end
ME->>BE: WS disconnect
BE->>LSP: Terminate process
All error responses from the backend follow this structure:
{
"message": "Human-readable error description",
"error": "SHORT_ERROR_CODE"
}The frontend extracts the message field for display. If neither field is present, the raw response text is shown as a fallback.
The KIT SSO flow does not go through the standard login endpoint. Instead:
- Frontend redirects user to
/auth(Keycloak authorization URL) - Keycloak authenticates and redirects back to
/auth/callbackwith an authorization code - Frontend sends the code to the backend, which exchanges it for a token pair
- Backend returns
{ accessToken, refreshToken }— same format as password login
sequenceDiagram
actor User
participant FE as Frontend
participant KC as Keycloak
participant BE as Backend
User->>FE: Click "KIT Login"
FE->>KC: Redirect to /auth (authorization URL)
KC->>User: KIT login form
User->>KC: Credentials
KC->>FE: Redirect to /auth/callback?code=...
FE->>BE: POST exchange authorization code
BE->>KC: Validate code
KC-->>BE: Token
BE-->>FE: { accessToken, refreshToken }