2.2 Reusable API Fragments, ResourceTypes & Traits
Key Takeaways
- API Fragments are modular, reusable RAML components published to Anypoint Exchange and incorporated into API specifications via the '!include' tag or RAML Libraries.
- RAML defines 7 specialized fragment types: DataType, Trait, ResourceType, Library, SecurityScheme, Example (or NamedExample), and DocumentationItem, each requiring a specific '#%RAML 1.0 <FragmentType>' header.
- Traits encapsulate cross-cutting method-level patterns (such as pagination query parameters, client-id enforcement headers, and standard 4xx/5xx error responses) and are applied using the 'is: [ traitName ]' node.
- ResourceTypes standardize resource-level behavior and methods (such as 'collection' for GET/POST and 'item' for GET/PUT/DELETE) and are applied using the 'type: resourceTypeName' node.
- ResourceTypes and Traits support dynamic parameterization using built-in reserved variables (<<resourcePathName>>, <<resourcePath>>, <<methodName>>) and transform functions like '!singularize' and '!pluralize'.
Reusable API Fragments, ResourceTypes & Traits
In enterprise application networks, designing monolithic, single-file API specifications creates severe maintenance overhead, code duplication, and inconsistent consumer experiences across development teams. To achieve the API-led connectivity vision of speed, consistency, and reusability, RAML 1.0 provides a modular architecture centered on API Fragments, Traits, ResourceTypes, and RAML Libraries.
1. Modular API Architecture & The Fragment Ecosystem
An API Fragment is a self-contained, versioned RAML definition that represents a discrete architectural component. API fragments are developed in API Designer, published to Anypoint Exchange as reusable catalog assets, and referenced across dozens of API specifications throughout the enterprise.
+---------------------------------------------------------------------------------------------------+
| RAML MODULAR FRAGMENT ARCHITECTURE |
| |
| [Main API Specification: order-exp-api.raml] |
| | |
| +---> !include exchange_modules/.../types/Order.raml (DataType Fragment) |
| +---> !include exchange_modules/.../traits/client-id-auth.raml (Trait Fragment) |
| +---> !include exchange_modules/.../traits/pageable.raml (Trait Fragment) |
| +---> !include exchange_modules/.../resourceTypes/item.raml (ResourceType Fragment) |
| +---> uses: { CommonLib: libraries/enterprise-library.raml } (Library Fragment) |
+---------------------------------------------------------------------------------------------------+
The 7 Official RAML 1.0 Fragment Types:
Every standalone fragment file must declare its specific fragment type on line 1 of the file:
| Fragment Header | Purpose | Example Use Case |
|---|---|---|
#%RAML 1.0 DataType | Defines a single data model or entity schema | Customer.raml, Address.raml |
#%RAML 1.0 Trait | Defines cross-cutting method-level behaviors | pageable.raml, client-id-enforced.raml |
#%RAML 1.0 ResourceType | Defines structural patterns and methods for resources | collection.raml, member-item.raml |
#%RAML 1.0 Library | Bundles multiple types, traits, and resourceTypes together | EnterpriseCoreLibrary.raml |
#%RAML 1.0 SecurityScheme | Declares authentication and authorization mechanisms | oauth2-security.raml, custom-token.raml |
#%RAML 1.0 NamedExample | Contains a sample data payload with a display name | customer-sample.json, order-example.raml |
#%RAML 1.0 DocumentationItem | Contains a single Markdown documentation topic | getting-started.raml, legal-terms.raml |
2. Inclusion Syntax with the !include Tag
The !include tag is a RAML keyword used to pull the contents of an external file into the parent specification at parse time. The path can be relative to the local project structure or reference an imported Exchange module.
#%RAML 1.0
title: Warehouse Fulfillment API
version: v1
types:
Item: !include fragments/dataTypes/ItemDataType.raml
ErrorResponse: !include exchange_modules/orgId/common-types/1.0.4/ErrorDataType.raml
traits:
secured: !include fragments/traits/ClientIdEnforceableTrait.raml
pageable: !include fragments/traits/PageableTrait.raml
/items:
is: [ secured, pageable ]
get:
responses:
200:
body:
application/json:
type: Item[]
example: !include examples/items-example.json
[!IMPORTANT] Fragment Header Validation Rule: When a file with a
#%RAML 1.0 <FragmentType>header is included using!include, the RAML parser validates that the included file matches the expected context (e.g., you cannot include a#%RAML 1.0 Traitfile under thetypes:node).
3. RAML Traits: Cross-Cutting Method Behaviors
A Trait is like a mixin for HTTP methods. It extracts repetitive method-level properties—such as query parameters, request headers, and standard error responses—into a single reusable definition applied via the is: [ traitName ] declaration.
+---------------------------------------------------------------------------------------------------+
| APPLYING TRAITS TO HTTP METHODS |
| |
| [Trait: pageable] [Trait: client-id-enforced] [Trait: error-responses] |
| - queryParams: offset, limit - headers: client_id, secret - responses: 400, 404, 500 |
| \ | / |
| +----------------------------+----------------------------+ |
| | |
| v |
| /accounts: get: is: [ pageable, client-id-enforced, error-responses ] |
+---------------------------------------------------------------------------------------------------+
Enterprise Trait Definitions:
#%RAML 1.0 Trait
# File: traits/pageable.raml
description: Standard pagination query parameters for collection endpoints
queryParameters:
offset:
type: integer
required: false
minimum: 0
default: 0
description: The zero-based index of the first item in the collection
limit:
type: integer
required: false
minimum: 1
maximum: 100
default: 20
description: Maximum number of records to return in a single page
#%RAML 1.0 Trait
# File: traits/client-id-enforced.raml
description: Requires Client ID and Secret headers for API Manager policy enforcement
headers:
client_id:
type: string
required: true
description: Client application identifier issued by Anypoint Exchange
client_secret:
type: string
required: true
description: Client application secret key
responses:
401:
description: Unauthorized - Invalid or missing client credentials
body:
application/json:
type: !include ../types/ErrorResponse.raml
403:
description: Forbidden - Application is not approved or SLA tier exceeded
body:
application/json:
type: !include ../types/ErrorResponse.raml
4. RAML ResourceTypes: Standardizing Resource Structure
A ResourceType is a template for resources. While Traits apply to methods (GET, POST), ResourceTypes define the entire shape of a resource, including which HTTP verbs it supports, what payloads it expects, and what responses it emits.
Core ResourceType Patterns:
- Collection: Defines
get(returns list of items) andpost(creates new item, returns 201). - Member Item: Defines
get(returns single item),put(replaces item),patch(updates item), anddelete(removes item).
#%RAML 1.0 ResourceType
# File: resourceTypes/collection.raml
description: A collection of <<resourcePathName>>
get:
description: Retrieve all <<resourcePathName>>
responses:
200:
body:
application/json:
type: <<itemType>>[]
post:
description: Create a new <<resourcePathName | !singularize>>
body:
application/json:
type: <<itemType>>
responses:
201:
headers:
Location:
type: string
example: /<<resourcePathName>>/12345
body:
application/json:
type: <<itemType>>
Applying ResourceTypes in the Root API:
resourceTypes:
collection: !include resourceTypes/collection.raml
/customers:
type:
collection:
itemType: Customer
/invoices:
type:
collection:
itemType: Invoice
5. Dynamic Parameterization & Reserved Variables
RAML provides built-in reserved variables and transformation functions that allow ResourceTypes and Traits to adapt dynamically based on the resource where they are applied:
+---------------------------------------------------------------------------------------------------+
| RAML RESERVED VARIABLES & FILTERS |
| |
| For Resource: /customers/{customerId} |
| - <<resourcePath>> --> "/customers/{customerId}" (Full URI path) |
| - <<resourcePathName>> --> "customers" (Rightmost path component without parameters) |
| - <<methodName>> --> "get" / "post" (Current HTTP verb) |
| |
| String Transformation Functions: |
| - !singularize --> <<resourcePathName | !singularize>> => "customer" |
| - !pluralize --> <<param | !pluralize>> => "customers" |
| - !uppercamelcase --> <<resourcePathName | !uppercamelcase>> => "Customers" |
| - !lowercamelcase --> <<resourcePathName | !lowercamelcase>> => "customers" |
+---------------------------------------------------------------------------------------------------+
Parameterized Trait Example:
#%RAML 1.0 Trait
traits:
contentCacheable:
headers:
If-None-Match?:
type: string
description: ETag of the <<resourcePathName | !singularize>> known by client
responses:
200:
headers:
ETag:
type: string
Cache-Control:
type: string
default: public, max-age=<<maxAge>>
6. RAML Libraries: Packaging Namespaced Modules
A RAML Library (#%RAML 1.0 Library) packages multiple related Data Types, Traits, ResourceTypes, and Security Schemes into a single module. Rather than importing 15 separate files via !include, a specification imports the entire library under a designated namespace using the uses: keyword.
#%RAML 1.0 Library
# File: libraries/BankingCoreLibrary.raml
types:
Account: !include ../types/Account.raml
Transaction: !include ../types/Transaction.raml
Money: !include ../types/Money.raml
traits:
auditLogged:
headers:
X-Audit-User:
type: string
rateLimited:
responses:
429:
description: Rate limit exceeded
resourceTypes:
auditedCollection: !include ../resourceTypes/auditedCollection.raml
Consuming a Library in a Root API Specification:
#%RAML 1.0
title: Retail Banking API
version: v1
uses:
BankingCore: libraries/BankingCoreLibrary.raml
/accounts:
type: BankingCore.auditedCollection
get:
is: [ BankingCore.rateLimited ]
responses:
200:
body:
application/json:
type: BankingCore.Account[]
Key Differences: !include vs. uses:
| Dimension | !include Tag | uses: Keyword |
|---|---|---|
| Target | Single fragment file (DataType, Trait, ResourceType, JSON) | Full #%RAML 1.0 Library file |
| Namespace | No namespace; content is merged directly into current context | Explicit namespace required (e.g., CoreLib.Customer) |
| Scope | Point-to-point inclusion | Global module reference across the entire specification |
| Collisions | Risk of name collisions if multiple files define same keys | Clean namespace separation prevents naming conflicts |
7. Exam Watch: Core Developer Scenarios & Traps
[!IMPORTANT] Exam Rule 1: Applying Traits vs ResourceTypes Traits are applied using the
is: [ trait1, trait2 ]keyword under methods or resources (for method inheritance). ResourceTypes are applied using thetype: resourceTypeNamekeyword on a resource. Mixing these keywords (e.g., writingis: collectionortype: [ pageable ]) will fail RAML compilation.
[!WARNING] Exam Rule 2: Singularize and Parameter Syntax When applying transformation functions to parameter variables inside ResourceTypes or Traits, the function must be preceded by an exclamation mark and separated by a pipe:
<<resourcePathName | !singularize>>. Forgetting the!or double angle brackets<< >>will result in literal string output rather than dynamic interpolation.
[!TIP] Exam Rule 3: Library Headers vs Root API Headers A library file must begin with
#%RAML 1.0 Library. It cannot contain root API properties likebaseUri,version, or top-level/resources. If an exam question shows a file withbaseUriunder#%RAML 1.0 Library, it is invalid RAML.
A developer is designing an enterprise REST API and wants to standardize pagination query parameters ('limit' and 'offset') across 12 different collection resources. What is the most maintainable, reusable RAML 1.0 approach to implement this standard?
A team publishes a reusable RAML fragment named 'BankingTypes.raml' that contains multiple data types, traits, and resource types. In the main API specification, which keyword and syntax must the developer use to import and reference the data types from this file?
Consider the following RAML 1.0 ResourceType definition: #%RAML 1.0 ResourceType post: description: Create a new <<resourcePathName | !singularize>> body: application/json: type: <<itemType>> responses: 201: body: application/json: type: <<itemType>> When this ResourceType is applied to a resource defined as '/customers' with 'itemType: Customer', what description and request body type will API Designer generate for the POST method?
A developer creates a standalone file named 'CustomerDataType.raml' with the following content: #%RAML 1.0 Trait type: object properties: id: string name: string In the main API specification, the developer adds: types: Customer: !include CustomerDataType.raml What happens when this specification is parsed by API Designer or Anypoint Studio?