mdv
Version:
Markdown Validator
1,083 lines (870 loc) • 173 kB
Markdown
# RAML Version 1.0: RESTful API Modeling Language
## Abstract
RAML is a language for the definition of HTTP-based APIs that embody most or all of the principles of Representational State Transfer (REST). This document constitutes the RAML specification, an application of the [YAML 1.2 specification](http://yaml.org/spec/1.2/spec.html). The RAML specification provides mechanisms for defining practically-RESTful APIs, creating client/server source code, and comprehensively documenting the APIs for users.
## Status of this Document
This document constitutes the RAML 1.0 specification. The consensus of specification authors and RAML 0.8 users determines the contents of this document. We strongly recommend that implementers and users of the RAML 0.8 specification update their software and API definitions to the RAML 1.0 specification.
## Terminology and Conformance Language
Normative text describes one or both of the following kinds of elements:
* Vital elements of the specification
* Elements that contain the conformance language key words as defined by [IETF RFC 2119](https://www.ietf.org/rfc/rfc2119.txt) "Key words for use in RFCs to Indicate Requirement Levels"
Informative text is potentially helpful to the user, but dispensable. Informative text can be changed, added, or deleted editorially without negatively affecting the implementation of the specification. Informative text does not contain conformance keywords.
All text in this document is, by default, normative.
The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in [IETF RFC 2119](https://www.ietf.org/rfc/rfc2119.txt) "Key words for use in RFCs to Indicate Requirement Levels".
## Definitions and Terminology
### General
In this specification, **API definition** means an API using this specification.
**RAML Specification** refers to this document.
**REST** is used in the context of an API implemented using some or all of the principles of REST (Representational State Transfer), which was introduced and first defined in 2000 in Chapter 5, [REST](http://www.ics.uci.edu/~fielding/pubs/dissertation/rest_arch_style.htm), of the doctoral dissertation *"Architectural Styles and the Design of Network-based Software Architecture"* by Roy Fielding.
A **resource** is the conceptual mapping to an entity or set of entities.
A trailing question mark, for example **description?**, indicates an optional property.
### Template URI
A template URI refers to a URI parameter, which is a variable element, enclosed in curly brackets (`{}`) inside a relative URI of a resource.
RAML fully supports Level 2 as defined in [RFC6570](https://tools.ietf.org/html/rfc6570) for URI Templates.
### Markdown
Throughout this specification, **Markdown** means [GitHub-Flavored Markdown](https://help.github.com/articles/github-flavored-markdown/).
## Table of Content
<!-- TOC -->
- [Introduction](#introduction)
- [What's New and Different in RAML 1.0](#whats-new-and-different-in-raml-10)
- [Markup Language](#markup-language)
- [The Root of the Document](#the-root-of-the-document)
- [User Documentation](#user-documentation)
- [Base URI and Base URI Parameters](#base-uri-and-base-uri-parameters)
- [Protocols](#protocols)
- [Default Media Types](#default-media-types)
- [Default Security](#default-security)
- [RAML Data Types](#raml-data-types)
- [Introduction](#introduction)
- [Overview](#overview)
- [Defining Types](#defining-types)
- [Type Declarations](#type-declarations)
- [Built-in Types](#built-in-types)
- [The "Any" Type](#the-any-type)
- [Object Type](#object-type)
- [Property Declarations](#property-declarations)
- [Additional Properties](#additional-properties)
- [Object Type Specialization](#object-type-specialization)
- [Using Discriminator](#using-discriminator)
- [Array Type](#array-type)
- [Scalar Types](#scalar-types)
- [String](#string)
- [Number](#number)
- [Integer](#integer)
- [Boolean](#boolean)
- [Date](#date)
- [File](#file)
- [Nil Type](#nil-type)
- [Union Type](#union-type)
- [Using XML and JSON Schema](#using-xml-and-json-schema)
- [User-defined Facets](#user-defined-facets)
- [Determine Default Types](#determine-default-types)
- [Type Expressions](#type-expressions)
- [Multiple Inheritance](#multiple-inheritance)
- [Inline Type Declarations](#inline-type-declarations)
- [Defining Examples in RAML](#defining-examples-in-raml)
- [Multiple Examples](#multiple-examples)
- [Single Example](#single-example)
- [Example of how to define example/examples in RAML](#example-of-how-to-define-exampleexamples-in-raml)
- [XML Serialization of Type Instances](#xml-serialization-of-type-instances)
- [Using Types in RAML](#using-types-in-raml)
- [Resources and Nested Resources](#resources-and-nested-resources)
- [Resource Property](#resource-property)
- [Template URIs and URI Parameters](#template-uris-and-uri-parameters)
- [Methods](#methods)
- [Headers](#headers)
- [Query Strings and Query Parameters](#query-strings-and-query-parameters)
- [The Query String as a Whole](#the-query-string-as-a-whole)
- [Query Parameters in a Query String](#query-parameters-in-a-query-string)
- [Bodies](#bodies)
- [Responses](#responses)
- [Resource Types and Traits](#resource-types-and-traits)
- [Declaring Resource Types and Traits](#declaring-resource-types-and-traits)
- [Applying Resource Types and Traits](#applying-resource-types-and-traits)
- [Resource Type and Trait Parameters](#resource-type-and-trait-parameters)
- [Declaring HTTP Methods as Optional](#declaring-http-methods-as-optional)
- [Algorithm of Merging Traits and Methods](#algorithm-of-merging-traits-and-methods)
- [Resource Types and Traits Effect on Collections](#resource-types-and-traits-effect-on-collections)
- [Security Schemes](#security-schemes)
- [Security Scheme Types](#security-scheme-types)
- [Security Scheme Declaration](#security-scheme-declaration)
- [describedBy](#describedby)
- [Settings](#settings)
- [OAuth 1.0](#oauth-10)
- [OAuth 2.0](#oauth-20)
- [Basic Authentication](#basic-authentication)
- [Digest Authentication](#digest-authentication)
- [Pass Through](#pass-through)
- [x-<other>](#x-other)
- [Applying Security Schemes](#applying-security-schemes)
- [Annotations](#annotations)
- [Declaring Annotation Types](#declaring-annotation-types)
- [Applying Annotations](#applying-annotations)
- [Annotating Scalar-valued Nodes](#annotating-scalar-valued-nodes)
- [Annotation Targets](#annotation-targets)
- [Modularization](#modularization)
- [Includes](#includes)
- [Typed Fragments](#typed-fragments)
- [Resolving Includes](#resolving-includes)
- [Libraries](#libraries)
- [Overlays and Extensions](#overlays-and-extensions)
- [Overlays](#overlays)
- [Extensions](#extensions)
- [Merging Rules](#merging-rules)
- [References](#references)
<!-- /TOC -->
## Introduction
This specification describes the RESTful API Modeling Language (RAML). RAML is a human- and machine-readable language for the definition of a RESTful application programming interface (API). RAML is designed to improve the specification of the API by providing a format that the API provider and API consumers can use as a mutual contract. RAML can, for example, facilitate providing user documentation and source code stubs for client and server implementations. Such provisions streamline and enhance the definition and development of interoperable applications that utilize RESTful APIs.
RAML introduces the innovative concept of resource types and traits for characterizing and reusing patterns of resources and associated methods. Using resource types and traits minimizes the repetition in a RESTful API design and promotes consistency within and across APIs.
This document is organized as follows:
* **Basic Information**. How to describe core aspects of the API, such as its name, title, location (or URI), and defaults and how to include supporting documentation for the API.
* **Data Types**. Modeling API data through a streamlined type system that encompasses JSON and XML Schema.
* **Resources**. How to specify API resources and nested resources, as well as URI parameters in any URI templates.
* **Methods**. How to specify the methods on API resources and their request headers, query parameters, and request bodies.
* **Responses**. The specification of API responses, including status codes, media types, response headers, and response bodies.
* **Resource Types and Traits**. The optional use of RAML resource types and traits to characterize resources.
* **Security**. Specifying an API security scheme in RAML.
* **Annotations**. Extending a RAML specification by defining strongly-typed annotations and applying them throughout the specification.
* **Includes, Libraries, Overlays, and Extensions**. How an API definition can consist of externalized definition documents, packaging collections of such definitions into libraries, separating and overlaying layers of metadata on a RAML document, and extending an API specification with additional functionality.
## What's New and Different in RAML 1.0
* **Data types**: a unified, streamlined, and powerful way to model data wherever it appears in an API.
* Uniformly covers bodies, URI parameters, headers, and query parameters and eliminates the need for a separate formParameters construct
* Supports wrapping XML Schema and JSON Schema and even referring to sub-schemas, but in many cases just obviates the schemas
* Simplifies coding, compared to the JSON Schema or XML Schema, by virtue of being YAML-based
* **Examples**: multiple examples, expressible in YAML, and annotatable, so semantics can be injected
* **Annotations**: a tried-and-tested, strongly-typed mechanism for extensibility
* **Libraries**: improved modularity for broad reuse of API artifacts
* **Overlays** and **Extensions**: increased extensibility through separated files
* **Improved Security Schemes**:
* Wider OAuth support
* Support for pass-through (key-based) security schemes
* **Several smaller changes** for consistency and expressivity
## Markup Language
This specification uses [YAML 1.2](http://www.yaml.org/spec/1.2/spec.html) as its underlying format. YAML is a human-readable data format that aligns well with the design goals of this specification. As in YAML, all nodes such as keys, values, and tags, are case-sensitive.
RAML API definitions are YAML 1.2-compliant documents that begin with a REQUIRED YAML-comment line that indicates the RAML version, as follows:
```yaml
#%RAML 1.0
title: My API
```
The first line of a RAML API definition document MUST begin with the text _#%RAML_ followed by a single space followed by the text _1.0_ and nothing else before the end of the line. RAML fragment documents begin similarly with the RAML version comment and a [fragment identifier](#typed-fragments), but are not in themselves RAML API definition documents.
The media type _application/raml+yaml_ and its associated file extension _.raml_ SHALL be used to designate files containing RAML API definitions, RAML fragments, and files that contain RAML markup. RAML is also capable of including documents of other media types, such as “application/schema+json” and “application/yaml”.
To facilitate the automated processing of RAML documents, RAML imposes the following restrictions and requirements in addition to the core YAML 1.2 specification:
* The first line of a RAML file consists of a YAML comment that specifies the RAML version. Therefore, RAML processors cannot completely ignore all YAML comments.
* The order of some properties at certain levels within a RAML document is significant. Therefore, processors are expected to preserve this ordering.
## The Root of the Document
The root section of the RAML document describes the basic information about an API, such as its title and version. The root section also defines assets used elsewhere in the RAML document, such as types and traits.
Nodes in a RAML-documented API definition MAY appear in any order. Processors MUST preserve the order of nodes of the same kind within the same node of the definition tree. Examples of such nodes are resources that appear at the same level of the resource tree, methods for a given resource, parameters for a given method, and nodes at the same level in a given type. Processors MUST also preserve the order of items within arrays.
This example shows a small part of a RAML API definition for the GitHub v3 public API.
```yaml
#%RAML 1.0
title: GitHub API
version: v3
baseUri: https://api.github.com
mediaType: application/json
securitySchemes:
oauth_2_0: !include securitySchemes/oauth_2_0.raml
types:
Gist: !include types/gist.raml
Gists: !include types/gists.raml
resourceTypes:
collection: !include types/collection.raml
traits:
securedBy: [ oauth_2_0 ]
/search:
/code:
type: collection
get:
```
The following table enumerates the possible nodes at the root of a RAML document:
| Name | Description |
|:----------|:----------|
| title | A short, plain-text label for the API. Its value is a string.
| description? | A substantial, human-friendly description of the API. Its value is a string and MAY be formatted using [markdown](#markdown).
| version? | The version of the API, for example "v1". Its value is a string.
| baseUri? | A URI that serves as the [base for URIs](#base-uri-and-base-uri-parameters) of all resources. Often used as the base of the URL of each resource containing the location of the API. Can be a [template URI](#template-uri).
| baseUriParameters? | Named parameters used in the [baseUri](#base-uri-and-base-uri-parameters) (template).
| protocols? | The [protocols](#protocols) supported by the API.
| mediaType? | The [default media types](#default-media-types) to use for request and response bodies (payloads), for example "application/json".
| documentation? | Additional overall [documentation](#user-documentation) for the API.
| schemas? | An alias for the equivalent "types" node for compatibility with RAML 0.8. Deprecated - API definitions SHOULD use the "types" node because a future RAML version might remove the "schemas" alias with that node. The "types" node supports XML and JSON schemas.
| types? | Declarations of [(data) types](#defining-types) for use within the API.
| traits? | Declarations of [traits](#resource-types-and-traits) for use within the API.
| resourceTypes? | Declarations of [resource types](#resource-types-and-traits) for use within the API.
| annotationTypes? | Declarations of [annotation types](#declaring-annotation-types) for use by annotations.
| (<annotationName>)? | [Annotations](#annotations) to be applied to this API. An annotation is a map having a key that begins with "(" and ends with ")" where the text enclosed in parentheses is the annotation name, and the value is an instance of that annotation.
| securitySchemes? | Declarations of [security schemes](#security-schemes) for use within the API.
| securedBy? | The [security schemes](#applying-security-schemes) that apply to every resource and method in the API.
| uses? | Imported external [libraries](#libraries) for use within the API.
| /<relativeUri>? | The resources of the API, identified as relative URIs that begin with a slash (/). A [resource node](#resources-and-nested-resources) is one that begins with the slash and is either at the root of the API definition or a child of a resource node. For example, /users and /{groupId}.
The "schemas" and "types" nodes are mutually exclusive and synonymous: processors MUST NOT allow both to be specified at the root-level of an API definition. We recommended using the "types" node instead of "schemas" because the schemas alias is deprecated and might be removed in a future RAML version.
### User Documentation
The OPTIONAL **documentation** node includes a variety of documents that serve as user guides and reference documentation for the API. Such documents can clarify how the API works or provide technical and business context.
The value of the documentation node is a sequence of one or more documents. Each document is a map that MUST have exactly two key-value pairs described in following table:
| Name | Description |
|:----------|:----------|
| title | Title of the document. Its value MUST be a non-empty string.
| content | Content of the document. Its value MUST be a non-empty string and MAY be formatted using [markdown](#markdown).
This example shows an API definition having two user documents.
```yaml
#%RAML 1.0
title: ZEncoder API
baseUri: https://app.zencoder.com/api
documentation:
- title: Home
content: |
Welcome to the _Zencoder API_ Documentation. The _Zencoder API_
allows you to connect your application to our encoding service
and encode videos without going through the web interface. You
may also benefit from one of our
[integration libraries](https://app.zencoder.com/docs/faq/basics/libraries)
for different languages.
- title: Legal
content: !include docs/legal.markdown
```
### Base URI and Base URI Parameters
The OPTIONAL **baseUri** node specifies a URI as an identifier for the API as a whole, and MAY be used the specify the URL at which the API is served (its service endpoint), and which forms the base of the URLs of each of its resources. The value of the baseUri node is a string that MUST conform to the URI specification [RFC2396](https://www.ietf.org/rfc/rfc2396.txt) or a [Template URI](#template-uri).
If the baseUri value is a [Template URI](#template-uri), the following reserved base URI parameter is available.
| URI Parameter | Value |
|:----------|:----------|
| version | The value of the root-level version node
Any other URI template variables appearing in the baseUri MAY be described explicitly within a **baseUriParameters** node at the root of the API definition. The baseUriParameters node has the same structure and semantics as the [uriParameters](#template-uris-and-uri-parameters) node on a resource node, except that it specifies parameters in the base URI rather than the relative URI of a resource.
The following example RAML API definition uses a [Template URI](#template-uri) as the base URI.
```yaml
#%RAML 1.0
title: Salesforce Chatter REST API
version: v28.0
baseUri: https://na1.salesforce.com/services/data/{version}/chatter
```
The following example declares an explicit base URI parameter.
```yaml
#%RAML 1.0
title: Amazon S3 REST API
version: 1
baseUri: https://{bucketName}.s3.amazonaws.com
baseUriParameters:
bucketName:
description: The name of the bucket
```
When the base URI ends in one or more slashes (`/`), those trailing slashes are omitted in the absolute paths for the resources using that base URI. For example, in the following snippet, the absolute paths for the resources are `http://api.test.com/common/users` and `http://api.test.com/common/users/groups`.
```yaml
baseUri: http://api.test.com/common/
/users:
/groups:
```
In the following, more complicated example with consecutive slashes in multiple places, only trailing slashes in the base URI are collapsed, leading to these absolute paths to resources: `//api.test.com//common/`, `//api.test.com//common//users/`, and `//api.test.com//common//users//groups//`.
```yaml
baseUri: //api.test.com//common//
/:
/users/:
/groups//:
```
### Protocols
The OPTIONAL **protocols** node specifies the protocols that an API supports. If the protocols node is not explicitly specified, one or more protocols included in the baseUri node is used; if the protocols node is explicitly specified, the node specification overrides any protocol included in the baseUri node. The protocols node MUST be a non-empty array of strings, of values HTTP and/or HTTPS, and is case-insensitive.
The following is an example of an API endpoint that accepts both HTTP and HTTPS requests.
```yaml
#%RAML 1.0
title: Salesforce Chatter REST API
version: v28.0
protocols: [ HTTP, HTTPS ]
baseUri: https://na1.salesforce.com/services/data/{version}/chatter
```
### Default Media Types
Specifying the OPTIONAL **mediaType** node sets the default media type for responses and requests that have a body. You do not need to specify the media type within every body definition.
The value of the mediaType node MUST be a sequence of media type strings or a single media type string. The media type applies to requests having a body, the expected responses, and examples using the same sequence of media type strings. Each value needs to conform to the media type specification in [RFC6838](https://tools.ietf.org/html/rfc6838).
This example shows a RAML snippet for an API that accepts and returns a JSON-formatted body. If the remainder of this API specification does not explicitly specify another media type, this API accepts and returns only JSON-formatted bodies.
```yaml
#%RAML 1.0
title: New API
mediaType: application/json
```
This example shows a RAML snippet for an API that accepts and returns JSON- or XML-formatted bodies.
```yaml
#%RAML 1.0
title: New API
mediaType: [ application/json, application/xml ]
```
Explicitly defining a `mediaType` node for a [body](#bodies) of an API request or response overrides the default media type, as shown in the following example. The resource `/list` returns a `Person[]` body represented as either JSON or XML. The resource `/send` overrides the default media type by explicitly defining an `application/json` node. Therefore, the resource `/send` returns only a JSON-formatted body.
```yaml
#%RAML 1.0
title: New API
mediaType: [ application/json, application/xml ]
types:
Person:
Another:
/list:
get:
responses:
200:
body: Person[]
/send:
post:
body:
application/json:
type: Another
```
### Default Security
Specifying the OPTIONAL **securedBy** node sets the default security schemes for, and protects, every method of every resource in the API. The value of the node is an array of security scheme names. See section [Applying Security Schemes](#applying-security-schemes) for more information, including how to resolve the application of multiple security schemes through inheritance.
The following example shows an API allowing access through either an OAuth 2.0 security scheme or an OAuth 1.1 security scheme.
```yaml
#%RAML 1.0
title: Dropbox API
version: 1
baseUri: https://api.dropbox.com/{version}
securedBy: [ oauth_2_0, oauth_1_0 ]
securitySchemes:
oauth_2_0: !include securitySchemes/oauth_2_0.raml
oauth_1_0: !include securitySchemes/oauth_1_0.raml
```
## RAML Data Types
### Introduction
RAML 1.0 introduces the notion of **data types**, which provide a concise and powerful way of describing the data in an API. Data types add rules for validating data against a type declaration. Valid data adheres to all rules for the type. Data types can describe a base or resource URI parameter, a query parameter, a request or response header, or a request or response body. Data types are built-in or custom. A built-in type can be used anywhere the API expects data. Custom types can be defined by extending the built-in types as well as named and used like built-in type. Extending types MUST NOT create any cyclic dependencies. A type can be extended inline.
The following RAML example defines a User type that includes type declarations for the firstname, lastname, and age properties. The example declares the properties to be of built-in types string and number. Later, the User type serves to describe the type (schema) for a payload.
```yaml
#%RAML 1.0
title: API with Types
types:
User:
type: object
properties:
firstname: string
lastname: string
age: number
/users/{id}:
get:
responses:
200:
body:
application/json:
type: User
```
A RAML type declaration resembles a JSON schema definition. In fact, RAML types can be used instead of JSON and XML schemas, or coexist with them. The RAML type syntax, however, is designed to be considerably easier and more succinct than JSON and XML schemas while retaining their flexibility and expressiveness. The following snippet shows a number of examples of type declarations:
```yaml
#%RAML 1.0
title: My API with Types
mediaType: application/json
types:
Org:
type: object
properties:
onCall: AlertableAdmin
Head: Manager
Person:
type: object
properties:
firstname: string
lastname: string
title?: string
Phone:
type: string
pattern: "[0-9|-]+"
Manager:
type: Person
properties:
reports: Person[]
phone: Phone
Admin:
type: Person
properties:
clearanceLevel:
enum: [ low, high ]
AlertableAdmin:
type: Admin
properties:
phone: Phone
Alertable: Manager | AlertableAdmin
/orgs/{orgId}:
get:
responses:
200:
body:
application/json:
type: Org
```
### Overview
This section is informative.
The RAML type system borrows from object oriented programming languages such as Java, as well as from XSD and JSON Schemas.
RAML Types in a nutshell:
- Types are similar to Java classes.
- Types borrow additional features from JSON Schema, XSD, and more expressive object oriented languages.
- You can define types that inherit from other types.
- Multiple inheritance is allowed.
- Types are split into four families: external, object, array, and scalar.
- Types can define two types of members: **properties** and **facets**. Both are inherited.
- **Properties** are regular, object oriented properties.
- **Facets** are special _configurations_. You specialize types based on characteristics of facet values.
Examples: minLength, maxLength
- Only object types can declare properties. All types can declare facets.
- To specialize a scalar type, you implement facets, giving already defined facets a concrete value.
- To specialize an object type, you define properties.
### Defining Types
Types can be declared inline where the API expects data, in an OPTIONAL **types** node at the root of the API, or in an included library. To declare a type, you use a map where the key represents the name of the type and its value is a [type declaration](#type-declarations).
```yaml
types:
Person: # key name
# value is a type declaration
```
### Type Declarations
A type declaration references another type, or wraps or extends another type by adding functional facets (e.g. properties) or non-functional facets (e.g. a description), or is a type expression that uses other types. Here are the facets that all type declarations can have; certain type declarations might have other facets:
| Facet | Description |
|:----------|:----------|
| default? | A default value for a type. When an API request is completely missing the instance of a type, for example when a query parameter described by a type is entirely missing from the request, then the API must act as if the API client had sent an instance of that type with the instance value being the value in the default facet. Similarly, when the API response is completely missing the instance of a type, the client must act as if the API server had returned an instance of that type with the instance value being the value in the default facet. A special case is made for URI parameters: for these, the client MUST substitute the value in the default facet if no instance of the URI parameter was given.
| schema? | An alias for the equivalent "type" facet for compatibility with RAML 0.8. Deprecated - API definitions SHOULD use the "type" facet because the "schema" alias for that facet name might be removed in a future RAML version. The "type" facet supports XML and JSON schemas.
| type? | The type which the current type extends or just wraps. The value of a type node MUST be either a) the name of a user-defined type or b) the name of a built-in RAML data type (object, array, or one of the scalar types) or c) an inline type declaration.
| example? | An example of an instance of this type that can be used, for example, by documentation generators to generate sample values for an object of this type. The "example" facet MUST NOT be available when the "examples" facet is already defined. See section [Examples](#defining-examples-in-raml) for more information.
| examples? | Examples of instances of this type. This can be used, for example, by documentation generators to generate sample values for an object of this type. The "examples" facet MUST NOT be available when the "example" facet is already defined. See section [Examples](#defining-examples-in-raml) for more information.
| displayName? | An alternate, human-friendly name for the type
| description? | A substantial, human-friendly description of the type. Its value is a string and MAY be formatted using [markdown](#markdown).
| (<annotationName>)? | [Annotations](#annotations) to be applied to this API. An annotation is a map having a key that begins with "(" and ends with ")" where the text enclosed in parentheses is the annotation name, and the value is an instance of that annotation.
| facets? | A map of additional, user-defined restrictions that will be inherited and applied by any extending subtype. See section [User-defined Facets](#user-defined-facets) for more information.
| xml? | The capability to configure [XML serialization of this type instance](#xml-serialization-of-type-instances).
| enum? | An enumeration of all the possible values of instances of this type. The value is an array containing representations of these possible values; an instance of this type MUST be equal to one of these values.
The "schema" and "type" facets are mutually exclusive and synonymous: processors MUST NOT allow both to be specified, explicitly or implicitly, inside the same type declaration. Therefore, the following examples are invalid:
```yaml
types:
Person:
schema: # invalid as mutually exclusive with `type`
type: # invalid as mutually exclusive with `schema`
```
```yaml
/resource:
get:
responses:
200:
body:
application/json: # start type declaration
schema: # invalid as mutually exclusive with `type`
type: # invalid as mutually exclusive with `schema`
```
We recommended using the "type" facet instead of "schema" because the schema alias is deprecated and might be removed in a future RAML version. Also, the "type" facet supports XML and JSON schemas.
### Built-in Types
The RAML type system defines the following built-in types:
* [any](#the-any-type)
* [object](#object-type)
* [array](#array-type)
* [union](#union-type) via type expression
* one of the following [scalar types](#scalar-types): number, boolean, string, date-only, time-only, datetime-only, datetime, file, integer, or nil
Additional to the built-in types, the RAML type system also allows to define [JSON or XML schema](#using-xml-and-json-schema).
The following diagram shows the inheritance tree, starting at the root-level with `any`.

#### The "Any" Type
Every type, whether built-in or user-defined, has the `any` type at the root of its inheritance tree. By definition, the `any` type is a type which imposes no restrictions, i.e. any instance of data is valid against it.
The "base" type of any type is the type in its inheritance tree that directly extends the `any` type at the root; thus, for example, if a custom type `status` extends the built-in type `integer` which extends the built-in type `number` which extends the `any` type, then the base type of `status` is `number`. Note that a type may have more than one base type.
The `any` type has no facets.
#### Object Type
All types that have the built-in object base type in its inheritance tree can use the following facets in their type declarations:
| Facet | Description |
|:----------|:----------|
| properties? | The [properties](#property-declarations) that instances of this type can or must have.
| minProperties? | The minimum number of properties allowed for instances of this type.
| maxProperties? | The maximum number of properties allowed for instances of this type.
| additionalProperties? | A Boolean that indicates if an object instance has [additional properties](#additional-properties).<br/><br/>**Default:** `true`
| discriminator? | Determines the concrete type of an individual object at runtime when, for example, payloads contain ambiguous types due to unions or inheritance. The value must match the name of one of the declared `properties` of a type. Unsupported practices are inline type declarations and [using `discriminator`](#using-discriminator) with non-scalar properties.
| discriminatorValue? | Identifies the declaring type. Requires including a `discriminator` facet in the type declaration. A valid value is an actual value that might identify the type of an individual object and is unique in the hierarchy of the type. Inline type declarations are not supported.<br/><br/>**Default:** The name of the type
An object type is created by explicit inheritance from the built-in type object:
```yaml
#%RAML 1.0
title: My API With Types
types:
Person:
type: object
properties:
name:
required: true
type: string
```
##### Property Declarations
Properties of object types are defined using the OPTIONAL **properties** facet. The RAML Specification calls the value of the "properties" facet a "properties declaration". The properties declaration is a map of keys and values. The keys are valid property names for declaring a type instance. The values are either a name of a type or an inline type declaration.
The properties declaration can specify whether a property is required or optional.
| Facet | Description |
|:----------|:----------|
| required? | Specifies that the property is required or not.<br /><br />**Default:** `true`.
The following example declares an object type having two properties:
```yaml
types:
Person:
properties:
name:
required: true
type: string
age:
required: false
type: number
```
The following example shows a common idiom:
```yaml
types:
Person:
properties:
name: string # equivalent to ->
# name:
# type: string
age?: number # optional property; equivalent to ->
# age:
# type: number
# required: false
```
When the `required` facet on a property is specified explicitly in a type declaration, any question mark in its property name is treated as part of the property name rather than as an indicator that the property is optional.
For example, in
```yaml
types:
profile:
properties:
preference?:
required: true
```
The `profile` type has a property named `preference?` that includes the trailing question mark. The following snippets show two ways of making `preference?` optional:
```yaml
types:
profile:
properties:
preference?:
required: false
```
or
```yaml
types:
profile:
properties:
preference??:
```
Note:
When an object type does not contain the "properties" facet, the object is assumed to be unconstrained and therefore capable of containing any properties of any type.
##### Additional Properties
By default, any instance of an object can have additional properties beyond those specified in its data type `properties` facet. Assume the following code is an instance of the data type `Person` that is described in the previous section.
```yaml
Person:
name: "John"
age: 35
note: "US" # valid additional property `note`
```
The property `note` is not explicitly declared in the `Person` data type, but is valid because all additional properties are valid by default.
To restrict the addition of properties, you can set the value of the `additionalProperties` facet to `false`, or you can specify regular expression patterns that match sets of keys and restrict their values. The latter are called "pattern properties". The patterns are delineated by pairs of opening and closing `/` characters, as follows:
```yaml
#%RAML 1.0
title: My API With Types
types:
Person:
properties:
name:
required: true
type: string
age:
required: false
type: number
/^note\d+$/: # restrict any properties whose keys start with "note"
# followed by a string of one or more digits
type: string
```
This pattern property restricts any additional properties whose keys start with "note" followed by a string of one or more digits. Consequently, the example of an object instance that declares an additional `note1` property with the value "US" is valid, but the property `note2` is invalid with a non-string value:
```yaml
Person:
name: "John"
age: 35
note2: 123 # not valid as it is not a string
note1: "US" # valid as it does not match the pattern
```
To force all additional properties to be strings, regardless of their keys, use:
```yaml
#%RAML 1.0
title: My API With Types
types:
Person:
properties:
name:
required: true
type: string
age:
required: false
type: number
//: # force all additional properties to be a string
type: string
```
If a pattern property regular expression also matches an explicitly declared property, the explicitly declared property definition prevails. If two or more pattern property regular expressions match a property name in an instance of the data type, the first one prevails.
Moreover, if `additionalProperties` is `false` (explicitly or by inheritance) in a given type definition, then explicitly setting pattern properties in that definition is not allowed. If `additionalProperties` is `true` (or omitted) in a given type definition, then pattern properties are allowed and further restrict the additional properties allowed in that type.
##### Object Type Specialization
You can declare object types that inherit from other object types. A sub-type inherits all the properties of its parent type. In the following example, the type `Employee` inherits all properties of its parent type `Person`.
```yaml
#%RAML 1.0
title: My API With Types
types:
Person:
type: object
properties:
name:
type: string
Employee:
type: Person
properties:
id:
type: string
```
A sub-type can override properties of its parent type with the following restrictions: 1) a required property in the parent type cannot be changed to optional in the sub-type, and 2) the type declaration of a defined property in the parent type can only be changed to a narrower type (a specialization of the parent type) in the sub-type.
##### Using Discriminator
When payloads contain ambiguous types due to unions or inheritance, it is often impossible to discriminate the concrete type of an individual object at runtime. For example, when deserializing the payload into a statically typed language, this problem can occur.
A RAML processor might provide an implementation that automatically selects a concrete type from a set of possible types, but a simpler alternative is to store some unique value associated with the type inside the object.
You set the name of an object property using the `discriminator` facet. The name of the object property is used to discriminate the concrete type. The `discriminatorValue` stores the actual value that might identify the type of an individual object. By default, the value of `discriminatorValue` is the name of the type.
Here's an example that illustrates how to use `discriminator`:
```yaml
#%RAML 1.0
title: My API With Types
types:
Person:
type: object
discriminator: kind # refers to the `kind` property of object `Person`
properties:
kind: string # contains name of the kind of a `Person` instance
name: string
Employee: # kind can equal `Employee`; default value for `discriminatorValue`
type: Person
properties:
employeeId: integer
User: # kind can equal `User`; default value for `discriminatorValue`
type: Person
properties:
userId: integer
```
```yaml
data:
- name: A User
userId: 111
kind: User
- name: An Employee
employeeId: 222
kind: Employee
```
You can also override the default for `discriminatorValue` for each individual concrete class. The following example replaces the default value of `discriminatorValue` in initial caps with lowercase:
```yaml
#%RAML 1.0
title: My API With Types
types:
Person:
type: object
discriminator: kind
properties:
name: string
kind: string
Employee:
type: Person
discriminatorValue: employee # override default
properties:
employeeId: string
User:
type: Person
discriminatorValue: user # override default
properties:
userId: string
```
```yaml
data:
- name: A User
userId: 111
kind: user
- name: An Employee
employeeId: 222
kind: employee
```
Neither `discriminator` nor `discriminatorValue` can be defined for any inline type declarations or union types.
```yaml
# valid whenever there is a key name that can identify a type
types:
Device:
discriminator: kind
properties:
kind: string
```
```yaml
# invalid in any inline type declaration
application/json:
discriminator: kind
properties:
kind: string
```
```yaml
# invalid for union types
PersonOrDog:
type: Person | Dog
discriminator: hasTail
```
#### Array Type
Array types are declared by using either the array qualifier `[]` at the end of a [type expression](#type-expressions) or `array` as the value of a `type` facet. If you are defining a top-level array type, such as the `Emails` in the examples below, you can declare the following facets in addition to those previously described to further restrict the behavior of the array type.
| Facet | Description |
|:----------|:----------|
| uniqueItems? | Boolean value that indicates if items in the array MUST be unique.
| items? | Indicates the type all items in the array are inherited from. Can be a reference to an existing type or an inline [type declaration](#type-declarations).
| minItems? | Minimum amount of items in array. Value MUST be equal to or greater than 0.<br /><br />**Default:** `0`.
| maxItems? | Maximum amount of items in array. Value MUST be equal to or greater than 0.<br /><br />**Default:** `2147483647`.
Both of the following examples are valid:
```yaml
types:
Email:
type: object
properties:
subject: string
body: string
Emails:
type: Email[]
minItems: 1
uniqueItems: true
example: # example that contains array
- # start item 1
subject: My Email 1
body: This is the text for email 1.
- # start item 2
subject: My Email 2
body: This is the text for email 2.
```
```yaml
types:
Email:
type: object
properties:
name:
type: string
Emails:
type: array
items: Email
minItems: 1
uniqueItems: true
```
Using `Email[]` is equivalent to using `type: array`. The `items` facet defines the `Email` type as the one each array item inherits from.
#### Scalar Types
RAML defines a set of built-in scalar types, each of which has a predefined set of restrictions.
##### String
A JSON string with the following additional facets:
| Facet | Description |
|:--------|:------------|
| pattern? | Regular expression that this string SHOULD match.
| minLength? | Minimum length of the string. Value MUST be equal to or greater than 0.<br /><br />**Default:** `0`
| maxLength? | Maximum length of the string. Value MUST be equal to or greater than 0.<br /><br />**Default:** `2147483647`
Example:
```yaml
types:
Email:
type: string
minLength: 2
maxLength: 6
pattern: ^note\d+$
```
##### Number
Any JSON number including [integer](#integer) with the following additional facets:
| Facet | Description |
|:--------|:------------|
|minimum? | The minimum value of the parameter. Applicable only to parameters of type number or integer.
|maximum? | The maximum value of the parameter. Applicable only to parameters of type number or integer.
|format? | The format of the value. The value MUST be one of the following: int32, int64, int, long, float, double, int16, int8
|multipleOf? | A numeric instance is valid against "multipleOf" if the result of dividing the instance by this keyword's value is an integer.
Example:
```yaml
types:
Weight:
type: number
minimum: 3
maximum: 5
format: int64
multipleOf: 4
```
##### Integer
A subset of JSON numbers that are positive and negative multiples of 1. The integer type inherits its facets from the [number type](#number).
```yaml
types:
Age:
type: integer
minimum: 3
maximum: 5
format: int8
multipleOf: 1
```
##### Boolean
A JSON boolean without any additional facets.
```yaml
types:
IsMarried:
type: boolean
```
##### Date
The following date type representations MUST be supported:
| Type | Description |
|:-----|:------------|
| date-only | The "full-date" notation of [RFC3339](http://xml2rfc.ietf.org/public/rfc/html/rfc3339.html#anchor14), namely `yyyy-mm-dd`. Does not support time or time zone-offset notation.
| time-only | The "partial-time" notation of [RFC3339](http://xml2rfc.ietf.org/public/rfc/html/rfc3339.html#anchor14), namely hh:mm:ss\[.ff...\]. Does not support date or time zone-offset notation.
| datetime-only | Combined date-only and time-only with a separator of "T", namely yyyy-mm-ddThh:mm:ss\[.ff...\]. Does not support a time zone offset.
| datetime | A timestamp in one of the following formats: if the _format_ is omitted or set to `rfc3339`, uses the "date-time" notation of [RFC3339](http://xml2rfc.ietf.org/public/rfc/html/rfc3339.html#anchor14); if _format_ is set to `rfc2616`, uses the format defined in [RFC2616](https://www.ietf.org/rfc/rfc2616.txt).
The additional facet _format_ MUST be available only when the type equals _datetime_, and the value MUST be either `rfc3339` or `rfc2616`. Any other values are invalid.
```yaml
types:
birthday:
type: date-only # no implications about time or offset
example: 2015-05-23
lunchtime:
type: time-only # no implications about date or offset
example: 12:30:00
fireworks:
type: datetime-only # no implications about offset
example: 2015-07-04T21:00:00
created:
type: datetime
example: 2016-02-28T16:41:41.090Z
format: rfc3339 # the default, so no need to specify
If-Modified-Since:
type: datetime
example: Sun, 28 Feb 2016 16:41:41 GMT
format: rfc2616 # this time it's required, otherwise, the example format is invalid
```
##### File
The **file** type can constrain the content to send through forms. When this type is used in the context of web forms it SHOULD be represented as a valid file upload in JSON format. File content SHOULD be a base64-encoded string.
| Facet | Description |
|:--------|:------------|
| fileTypes? | A list of valid content-type strings for the file. The file type `*/*` MUST be a valid value.
| minLength? | Specifies the minimum number of bytes for a parameter value. The value MUST be equal to or greater than 0.<br /><br />**Default:** `0`
| maxLength? | Specifies the maximum number of bytes for a parameter value. The value MUST be equal to or greater than 0.<br /><br />**Default:** `2147483647`
```yaml
types:
userPicture:
type: file
fileTypes: ['image/jpeg', 'image/png']
maxLength: 307200
customFile:
type: file
fileTypes: ['*/*'] # any file type allowed
maxLength: 1048576
```
##### Nil Type
In RAML, the type `nil` is a scalar type that allows only nil data values. Specifically, in YAML it allows only YAML's `null` (or its equivalent representations, such as `~`), in JSON it allows only JSON's `null`, and in XML it allows only XML's `xsi:nil`. In headers, URI parameters, and query parameters, the `nil` type only allows the string value "nil" (case-sensitive); and in turn an instance having the string value "nil" (case-sensitive), when described with the `nil` type, deserializes to a nil value.
In the following example, the type of an object and has two required properties, `name` and `comment`, both defaulting to type `string`. In `example`, `name` is assigned a string value, but comment is nil and this is _not_ allowed because RAML expects a string.
```yaml
types:
NilValue:
type: object
properties:
name:
comment:
example:
name: Fred
comment: # Providing no value here is not allowed.
```
The following example shows the assignment of the `nil` type to `comment`:
```yaml
types:
NilValue:
type: object
properties:
name:
comment: nil
example:
name: Fred
comment: # Providing a value here is not allowed.
```
The following example shows how to represent nilable properties using a union:
```yaml
types:
NilValue:
type: object
properties:
name:
comment: nil | string # equivalent to ->
# comment: string?
example:
name: Fred
comment: # Providing a value or not providing a value here is allowed.
```
Declaring the type of a property to be `nil` represents the lack of a value in a type instance. In a RAML context that requires *values* of type `nil` (vs just type declarations), the usual YAML `null` is used, e.g. when the type is `nil | number` you may use `enum: [ 1, 2, ~ ]` or more explicitly/verbosely `enum: [ 1, 2, !!null "" ]`; in non-inline notation you can just omit the value completely, of course.
#### Un