Tutorial: publish a user-management API
Documentation status: tutorial — see Maturity and evidence.
Goal
Build a small UserManagement module, validate the model, and then publish HTTP routes over Runtime capabilities.
The sequence is deliberate: model first, service second. A route should never be used to hide a model that does not load correctly.
Target structure
UserManagement/
├── packages/
│ └── UserManagement.package.yaml
├── meta/
│ └── models/
│ └── UserManagement/
│ ├── ClassItems.manifest.yaml
│ └── User.model.yaml
└── services/
└── UserManagement.service.yaml
1. Declare the package
package:
name: UserManagement
enabled: true
2. Declare the manifest
Use a project-owned application prefix. usr# is illustrative.
classes:
- class:
classId: usr#user
name: User
type: entity
Do not borrow a platform prefix for an application-owned concept.
3. Declare the User model
class:
classId: usr#user
name: User
type: entity
concepts:
- concept:
name: Entity
facets:
- facet:
type: hypergraph
name: main
fields:
- Name: String
- Age: Integer
- Email: String
- Company:
type: String
nullable: true
Add a persistence facet only when the scenario requires durable storage.
4. Validate before publishing
Start the application with the package enabled and verify:
ClassItems.manifest.yamlloads;usr#useris unique;Userresolves in the Runtime;- fields have the expected types;
- constraints are valid.
If this fails, do not add the HTTP service yet.
5. Add a service group
The package should make the service loadable using the publication mechanism supported by the release.
Conceptual example:
services:
- name: UserManagementApi
source: ../../services/UserManagement.service.yaml
enabled: true
The exact service descriptor is versioned. Use the reference for your release when producing a deployable file.
6. Define the HTTP service
The service publishes model capabilities, not a second copy of the domain.
service:
name: UserManagementApi
basePath: /api/users
routes:
- method: GET
path: /
action: ListUsers
- method: GET
path: /{id}
action: GetUser
- method: POST
path: /
action: CreateUser
- method: PUT
path: /{id}
action: UpdateUser
- method: DELETE
path: /{id}
action: DeleteUser
This snippet describes the publication pattern. Effective action names must match actions actually published by the model and the service grammar of the Runtime version in use.
7. Publish CRUD operations
| HTTP | Business capability | Note |
|---|---|---|
GET /api/users |
User collection |
filtering/paging according to service contract |
GET /api/users/{id} |
resolve one User |
return not-found when absent |
POST /api/users |
create | validate before commit |
PUT /api/users/{id} |
update | preserve identity and constraints |
DELETE /api/users/{id} |
delete | apply authorization and business rules |
8. Security
HTTP publication creates a separate security boundary. At minimum:
- authenticate callers when required;
- authorize at the business-capability boundary;
- never place secrets in object references;
- propagate audit context;
- treat local and remote execution as explicit trust boundaries.
9. Diagnostics
When a request fails, diagnose in this order:
- application and package;
- manifest;
Usermodel;- published actions/collections;
- service;
- route;
- transport;
- authentication/authorization.
Keep a correlation identifier for remote calls so client and Runtime diagnostics can be joined.
10. What this tutorial demonstrates
- a business model exists independently from its HTTP projection;
- publication comes after model validation;
- services expose published capabilities;
- the same Runtime model can sit behind local or remote execution;
- transport details should not leak into domain types.