APIs
This page describes how to model APIs in the canonical model:
- services and their methods
- resources and resource methods (endpoints)
- how types are used as requests and responses
- how facility-provided method types define HTTP semantics
The focus is on the canonical model (.cmn). How platforms map these APIs to concrete technologies (REST, messaging, RPC, …) is configured in platform profiles and cartridges, covered on Profiles & platforms (.profile).
This page assumes you are familiar with the basics of data modeling in Entities & DTOs and with the general modeling principles from the Modeling overview.
1. Services
A service groups related operations that represent business capabilities. In the canonical model, services are technology-neutral:
- they do not mention HTTP methods, URLs or transport protocols;
- they are expressed in terms of types and operations;
- platforms decide how to implement them (REST, messaging, RPC, …).
Typical use cases for services:
- business service interfaces
- application services orchestrating domain logic
- ports in a hexagonal architecture
1.1 Service methods
Service methods:
- have a name,
- may have parameters,
- return a result type or
void-like outcome, - can be annotated with stereotypes or other metadata (via platforms).
Service methods usually consume and return complex types or simple types from your model. The exact DSL syntax is covered in the CMN reference; conceptually you should think of a service as a clean, technology-agnostic interface.
A facility can map service methods to implementation artifacts. The CMN service syntax itself does not promise Java interfaces, controllers, messaging handlers, or any other particular output.
2. Resources and endpoints
While services represent business operations, resources describe externally visible APIs, typically in a REST style.
A resource defines:
- a resource path (for example
/hello), - one or more resource methods (endpoints),
- the request and response types for each method,
- references to resource method types that define HTTP semantics.
2.1 Resource definition
A simplified excerpt (imports and the platform selection are omitted) is:
resource /hello as Greeting {
create()
read()
}Here:
/hellois the resource path,Greetingis the type that represents the resource,create()andread()are resource methods that reference method types imported from a facility model.
Conceptually, this describes an API where:
POST /hellocreates a greeting,GET /helloretrieves greeting data,
with concrete HTTP details provided by the imported method types.
2.2 Resource method types
Resource methods use method types defined in the same model or imported from another model. For example, the Base API model defines:
methodtype create POST consumes='*' produces=Id success=201
methodtype read GET instance=true produces='*' success=200 errorResponse=ErrorResponseThese method types describe:
- the HTTP method (
POST,GET), - whether the method operates on a collection or instance (
instance=true), - request/response semantics (body, status codes),
- optional Base properties such as
errorResponse=ErrorResponse.
Your resource simply writes create() or read() and inherits all these details. This keeps your canonical model concise and lets you reuse consistent semantics across many resources.
The HTTP verb belongs to the method-type declaration, while create and read are ordinary referenced model-element names. Base properties such as instance, consumes, produces, and errorResponse are contributed by the Base profile rather than fixed by the CMN grammar.
The Base OpenAPI cartridge uses this information for OpenAPI operations. SpringBoot cartridges can additionally generate controller methods and related implementation artifacts.
Named request headers follow the same separation: Base defines their static OpenAPI contract, while the selected target-platform Facility defines runtime binding. SpringBoot's generated controller and handler parameters are documented under Request headers and handler signatures.
2.3 Raw vs. opinionated method types
The Base facility ships two groups of resource method types. The simplified declarations below show their public contract shape; the imported Base model can supply additional defaults. An application model normally uses the names rather than declaring them again.
Raw method types – pure HTTP verbs without any defaults:
cmnmethodtype get GET methodtype post POST methodtype put PUT methodtype patch PATCH methodtype delete DELETE
Use these when you need an explicit HTTP contract. They contain no Base defaults, so properties such as consumes, produces, instance, and responses must be modeled on the concrete resource method as needed.
- Opinionated method types – REST-oriented defaults that cover most create, read, update and query scenarios:
methodtype create POST
consumes='*' produces=Id success=201
methodtype start POST
consumes='*' produces=Id success=201
methodtype execute POST
consumes='*' produces='*' success=201
methodtype read GET
instance=true produces='*' success=200
errorResponse=ErrorResponse
methodtype update PUT
instance=true consumes='*' produces='*' success=200
methodtype deleteInstance DELETE
instance=true produces=Id success=200
methodtype query GET
produces='*[]' success=200 pagination=true
responseContext=ResponseContext errorResponse=ErrorResponse
methodtype list GET
produces='*[]' success=200 errorResponse=ErrorResponseThe Base query contract combines pagination with an explicit response context. Its JSON response therefore has this structure:
{
"data": [],
"context": {
"filteredElements": 0,
"totalElements": 0
}
}An explicit responseContext takes precedence over the context-free pagination wrapper. Without it, pagination=true uses content, filteredElements, and totalElements at the response root. The deprecated paging property remains a separate legacy data-based contract. See the upgrade guide before migrating an existing API.
In practice:
- prefer the unambiguous opinionated methods for standard REST-style APIs;
- use
deleteInstance()for the opinionated Base item-deletion contract; - use raw
delete()when all DELETE details are modeled explicitly; - with SpringBoot, use the unambiguous
deleteEntitymethod type; - use raw method types when the default semantics do not fit your use case.
These recommendations concern the Base and SpringBoot facility models, not the CMN grammar. Another facility can provide a different set of method-type names and properties.
2.4 Requests and responses
The request and response types of a resource method are usually derived from:
- the resource's main type (
Greetingin the example), - additional method-specific types, if the DSL or platform defines them,
- method type configuration (for example indicating whether the request body is required, what is returned on success, etc.).
From the modeling perspective you usually have to decide:
- which type represents the resource as a whole,
- whether you need specialised request/response DTOs or can reuse the same type for both directions,
- which base method type best matches the behavior you need (
create,read,update,query, …).
Descriptions and examples belong in the CMN model as well. An operation can carry its general description and summary, request-specific documentation and documentation for its primary CMN result. An explicitly modeled status response can carry documentation for that particular status code. This metadata is platform-independent model input; the selected facility determines its generated representation.
Use the canonical syntax from Documentation, descriptions and examples and the placement rules from Resources and method results. For Base, the concrete target mapping is OpenAPI documentation and examples.
3. Relationship between services and resources
Services and resources can be used independently or together:
- In a pure REST style, you may focus on resources and resource methods only.
- In a layered architecture, you might:
- define services as your internal API,
- expose parts of those services through resources,
- let platforms generate controllers when a component provides a resource, and service interfaces from services.
From the canonical model's point of view there is no hard coupling between services and resources. The exact relationship is typically defined by platform profiles and generators, and may vary between projects.
Important points:
- Services capture business intent and often map to application or domain services.
- Resources capture external contracts (HTTP APIs, web endpoints, etc.).
- Both reuse the same underlying types (entities, DTOs, value objects), which keeps your model consistent.
4. Paths, method types and operation names
When you design your APIs in CMN, keep the following in mind:
- Use clear, stable resource paths that reflect your domain concepts.
- Reuse a suitable method type for the HTTP contract.
- Add an explicit local operation name when this particular use needs a stable generator-facing name.
- Keep facility-specific defaults in method types and profiles instead of repeating them everywhere.
A resource method has these distinct naming parts:
resource /customers as Customer[] by id {
read readCustomer()
}readis the referenced method-type name. It supplies the imported Base HTTP contract.readCustomeris an explicit local name for this resource operation. It neither declares nor renames thereadmethod type.
When no local name is present, the Base profile's operationName property can provide a literal or template used to derive a generated method name. operationName is a facility property, not a third CMN declaration form. The exact precedence and template variables are documented in Resources & method types.
5. How APIs are validated and generated
Validation and generation for APIs work like for the rest of the model, with some API-specific aspects.
5.1 Validation
The parser checks the resource and method syntax, and the linker reports unresolved resources, types, fields, and method-type references. The active core validator rejects duplicate method-type names within the same root model or subpackage block.
The Base OpenAPI cartridge validates the format of an operationName property. A source-generating cartridge can additionally validate the resolved name for its target language. These validations do not imply a general core check for path uniqueness or HTTP-contract compatibility. See Active validation boundaries.
5.2 Generation
Typical generators for API-related models include:
- the Base OpenAPI cartridge, which creates model-scoped documents from resources and additional component-scoped documents aggregating provided endpoints;
- SpringBoot controller generators, which create controllers or handlers for resource methods exposed through a component's
provideboundary.
Other facilities may provide different outputs. Because the API contract is defined in the canonical model, a supporting facility can:
- reuse its types and resources in several generated artifacts;
- interpret the same structural model for a different technology stack;
- derive documentation and implementation artifacts from the same source.
6. Next steps
From here you can:
- read about Components to see how APIs are grouped into logical provided boundaries;
- explore Profiles & platforms (.profile) to understand how platforms interpret services and resources;
- consult the CMN reference for the exact syntax of service, resource and method definitions.
