-
Notifications
You must be signed in to change notification settings - Fork 858
Breaking Changes
These changes list where implementation differs between versions as the spec is simplified and inconsistencies are corrected.
For full list of breaking changes see the breaking change issues.
Previously, RAML 0.8 supported repeat
on named parameters. As any named parameter has been removed from RAML 1.0 in favour the more powerful RAML data types, `repeat is no longer supported and replaced by defining the type of a specific, for example, headers as an array. See description of the behaviour for this example here in the spec (paragraph about arrays).
In RAML 0.8, you could define either schemas or form parameters for either a request or response body. Since RAML 1.0 introduces RAML types and therefore unifies modeling data, there was no need for a special node anymore. To migrate existing RAML 0.8 definitions that uses form parameters to 1.0, you only need to replace formParameters
with properties
.
Example
RAML 0.8:
body:
application/x-www-form-urlencoded:
formParameters:
name:
description: name on account
type: string
example: Naruto Uzumaki
gender:
enum: ["male", "female"]
RAML 1.0
body:
application/x-www-form-urlencoded:
properties:
name:
description: name on account
type: string
example: Naruto Uzumaki
gender:
enum: ["male", "female"]
See here for more details.
RAML 1.0 is the first major release, and with that we want to be very close to one of our missions to introduce simple ways to share and collaborate pieces of your API design. In the past, we introduced concepts to define reusable definitions globally or in separated files, which could be easily included on or composed with other definitions. An example of such may be the following:
traits.raml
# external traits definition
pagination:
queryParameters:
offset:
description: Skip over a number of elements by specifying an offset value for the query
type: integer
example: 20
default: 0
limit:
description: Limit the number of elements on the response
type: integer
example: 80
secondTrait:
description: just a second trait
api.raml
#%RAML 0.8
title: Pagination API
traits:
- !include traits.raml # composing with includes from traits.raml
- otherTrait: # explicit trait definition
description: just another trait
RAML 1.0 takes the concepts of reusability or modularization one step further with introducing fragments and libraries. Both add significant value to the core concepts already mentioned and make some of the previous mechanism introduced above obsolete; especially composition. The above example can be also perfectly expressed using libraries.
traits.raml
#%RAML 1.0 Library
# external library
traits:
pagination:
queryParameters:
offset:
description: Skip over a number of elements by specifying an offset value for the query
type: integer
example: 20
default: 0
limit:
description: Limit the number of elements on the response
type: integer
example: 80
secondTrait:
description: just a second trait
api.raml
#%RAML 1.0
title: Pagination API
uses:
externalTraits: traits.raml
traits:
otherTrait:
description: just another trait
Using libraries, and also fragments, are coming with a couple of advantages; one being able to give better support for design-time validation and suggestions, and more.
Since we believe that these new mechanism will give significantly more benefits to anyone in the RAML community, we effectively decided to remove the ability to compose any external definitions with global definitions in RAML 1.0. So in any future version of RAML, you will be not allowed to do the following anymore:
traits:
- !include traits.raml # composing with includes from traits.raml
- otherTrait: # explicit trait definition
description: just another trait
This change does not only influence the way how you modularize and reuse definitions throughout a RAML API specification, but also the syntax on how to declare them. With 0.8, the syntax for defining global or external definition was not consistent. To define traits: !include traits.raml
your external file had to be a sequence (starting with dash) of traits, whereas you could not use the same file for composition since the requirements for that are a file that contains a map of traits (no dash).
Therefore, with RAML 1.0, we also generalize the syntax for global or external definitions to be much more consistent with the rest of the specification. Where you could define sequences in the past (introduced for being able to compose), you will be only allowed to define maps in the future, and not both depending on the context.
# using maps in 1.0
pagination:
queryParameters:
offset:
description: Skip over a number of elements by specifying an offset value for the query
type: integer
example: 20
default: 0
limit:
description: Limit the number of elements on the response
type: integer
example: 80
secondTrait:
description: just a second trait
vs
# using sequences in 0.8
- pagination:
queryParameters:
offset:
description: Skip over a number of elements by specifying an offset value for the query
type: integer
example: 20
default: 0
limit:
description: Limit the number of elements on the response
type: integer
example: 80
- secondTrait:
description: just a second trait
The root-level nodes that will be influenced by this change are traits
, resourceTypes
, securitySchemes
, and schemas
.
One will still be able to directly include an external traits definition into the global traits
node (traits: !include external.raml
) or single traits that is either a trait fragment or just a map of key-value pairs that defines a trait by doing the following:
traits:
trait1: !include trait1.raml
otherTrait: !include otherTrait.raml
In summary, the following should help to migrate your existing definitions using the new syntax and functionalities from RAML 1.0:
-
If you defined everything as global definitions without using external files; simply remove the dash to migrate from sequences to maps
Example
RAML 0.8:
traits: - pagination: ... - secondTrait: ...
RAML 1.0:
traits: pagination: ... secondTrait: ...
-
If you externalized a single definitions and referenced them as a value for a global definition; simply migrate the file into a typed fragment by adding the respective fragment identifier (e.g.,
#%RAML 1.0 Trait
) and done.Example
RAML 0.8:
# external file pagination.raml queryParameters: offset: ... limit: ...
#%RAML 0.8 # main api.raml traits: - pagination: !include pagination.raml /products: get: is: [ pagination ]
RAML 1.0
#%RAML 1.0 Trait # external file pagination.raml queryParameters: offset: ... limit: ...
#%RAML 1.0 # main api.raml traits: pagination: !include pagination.raml /products: get: is: [ pagination ]
-
If you externalized all definitions and referenced them using, for example,
traits: !include defs.raml
; simply migrate the external file to a library and change to pass validations (mostly it is about adding the identifier for what your definitions are such astraits:
,resourceTypes:
, or something else), and also update the root API definition to use the library and update the references inside your API specificationExample
RAML 0.8:
# external file traits.raml - pagination: ... - secondTrait: ...
#%RAML 0.8 # main api.raml traits: !include traits.raml /products: get: is: [ pagination ]
RAML 1.0
#%RAML 1.0 Library # external file traits.raml traits: pagination: ... secondTrait: ...
#%RAML 1.0 # main api.raml uses: traits: traits.raml /products: get: is: [ traits.pagination ]
-
If you externalized definitions and use composition; simply migrate the external definition file to be a library, update the root API definition to use library, remove the composition and also the sequences if not done already, and update all references to use definitions out of the library
Example
RAML 0.8:
# external file traits.raml pagination: ... secondTrait: ...
#%RAML 0.8 # main api.raml traits: - !include traits.raml - third: ... /products: get: is: [ pagination ]
RAML 1.0
#%RAML 1.0 Library # external file traits.raml traits: pagination: ... secondTrait: ...
#%RAML 1.0 # main api.raml uses: traits: traits.raml traits: third: ... /products: get: is: [ traits.pagination ]
See here more details.
In RAML 1.0, the date
type has been replaced by a set of more specialised types such as date-only
(yyyy-mm-dd
), time-only
(hh:mm:ss[.ff...]
), datetime-only
(yyyy-mm-ddThh:mm:ss[.ff...]
), and datetime
. Depending on the date/time you use, you should replace with the appropriate new type. On the other hand, you might also create your own date using the new type system.
See here more details.
In RAML 1.0, the authorization grant types changed to better reflect the OAuth 2.0 specification. In this process code
and credentials
were renamed to authorization_code
and client_credentials
, whereas token
and owner
were replaced by implicit
and password
respectively.
See here more details.
In RAML 0.8 you were able to define inline (anonymous) traits, resource types, and security schemes either explicitly or implicitly using !include
. This syntax is a shortcut that promotes a bad design practice, as you will not be able to reuse the trait in your api unless you include the same file more than once which does not look very DRY. Also the feature is crippled as you can inline only certain types of traits or resource types, those that do not use parameters.
As there might be some advantages, they are very small compared with the complexity and bad design you introduce into the spec and your API design. Therefore, the suggestion is to remove the ability to define inline definitions (implicit or explicit) for traits, resource types, and security schemes.
So the following are example is not valid in RAML 1.0 anymore:
/resource:
get:
is:
- !include trait1.raml
- !include trait2.raml
It is always recommended to use the global definitions to encourage consistency across multiple places in an API spec and across multiple API specs.
RAML 0.8:
/users:
type: !include types/collectionBase.raml
RAML 1.0:
resourceTypes:
baseCollection: !include types/collectionBase.raml
/users:
type: baseCollection
See here more details.
Before RAML 1.0, you were able to define any node to be optional when defining a resource type or trait. That was very ambiguous and therefore RAML 1.0 limits this ability to methods in resource types only.
Example
#%RAML 1.0
title: Example of Optional Properties
resourceTypes:
corpResource:
post?: # optional method; fully valid
description: Some info.
In RAML 0.8 it was valid to define baseUriParameters
also on non root-level nodes such as resources. RAML 1.0 removes that ability and supports the declaration of any base URI parameters only at the root-level of your API definition.