raml-js-parser-2
raml-js-parser-2 copied to clipboard
Consistency on array type interpretation
Today I stumbled on an issue on array type parsing. While using the raml2html lib that depends on the parser as well as the datatype-expansion, I have discovered that the [] syntax and the array/items notation don't produce the same output out of the parser.
Let's take this RAML:
#%RAML 1.0
title: Nesting bug
version: v1
baseUri: http://www.bug.com
types:
Book:
type: object
properties:
id: integer
Library:
type: object
properties:
id: integer
books:
type: array
items: Book
/bug:
get:
responses:
200:
body:
application/json:
type: object
properties:
libraries:
type: array
items: Library
It will produce the following Library type after going through the parser:
"Library": {
"name": "Library",
"displayName": "Library",
"typePropertyKind": "TYPE_EXPRESSION",
"type": [
"object"
],
"properties": {
"id": {},
"books": {
"name": "books",
"displayName": "books",
"typePropertyKind": "TYPE_EXPRESSION",
"type": [
"array"
],
"required": true,
"items": [
"Book"
]
}
},
}
But if I use the [] notation, with the following RAML:
#%RAML 1.0
title: Nesting bug
version: v1
baseUri: http://www.bug.com
types:
Book:
type: object
properties:
id: integer
Library:
type: object
properties:
id: integer
books:
type: Book[]
/bug:
get:
responses:
200:
body:
application/json:
type: object
properties:
libraries:
type: Library[]
I get the following Library type:
"Library": {
"name": "Library",
"displayName": "Library",
"typePropertyKind": "TYPE_EXPRESSION",
"type": [
"object"
],
"properties": {
"id": {},
"books": {
"name": "books",
"displayName": "books",
"typePropertyKind": "TYPE_EXPRESSION",
"type": [
"array"
],
"required": true,
"items": "Book"
}
},
}
The difference is that in one case, the items field is an array and in the other, it is a string.
I wouldn't bother having two different syntax, but the issue is that the datatype-expansion's canonicalForm method doesn't support the array notation:
"books": {
"name": "books",
"displayName": "books",
"typePropertyKind": "TYPE_EXPRESSION",
"type": [
"array"
],
"required": true,
"items": [
"Book"
]
}
becomes that:
"books": {
"type": "array",
"displayName": "books",
"name": "books",
"typePropertyKind": "TYPE_EXPRESSION",
"required": true,
"items": {
"type": "any"
}
}
Whereas this (obtained when using the [] syntax):
"books": {
"name": "books",
"displayName": "books",
"typePropertyKind": "TYPE_EXPRESSION",
"type": [
"array"
],
"required": true,
"items": "Book"
}
Becomes that (which is the expected result):
"books": {
"type": "array",
"displayName": "books",
"name": "books",
"typePropertyKind": "TYPE_EXPRESSION",
"required": true,
"items": {
"type": "object",
"properties": {
"id": {
"displayName": "id",
"type": "integer",
"required": true
}
},
"additionalProperties": true,
"displayName": "Book"
}
}
Not sure that I completely missed something but both outputs you posted have items with a string value.
Right, bad copy paste ;)
OK if that's the case, I actually think that items should be an object and not a string or array. For example, what happens if you define your items to be a type declaration?
So my suggestion is that the outcome should be:
"Library": {
"name": "Library",
"displayName": "Library",
"typePropertyKind": "TYPE_EXPRESSION",
"type": [
"object"
],
"properties": {
"id": {},
"books": {
"name": "books",
"displayName": "books",
"typePropertyKind": "TYPE_EXPRESSION",
"type": [
"array"
],
"required": true,
"items": {
"type": "Book"
}
}
}
}
And in the newer improved schema, that you get calling load, you actually see it is defined as oneOf (here).
@ddenisenko we should avoid using oneOf as much as possible. Do you see any cases where we need it? In this case (items), I currently don't see any as everything can be described as an object (type declaration) again (see this option here).
Note that raml-js-parser-2 has been deprecated, the new official parser is webapi-parser. Feel free to attempt to reproduce this issue with webapi-parser and report any issue you may have on that repository.