Including Complex Nested schema's and using Multiple schema definition in one RAML


#1

Hi,

I’ve a RAML File and its schema’s are defined in other files but include in this RAML file.
The problem is, how do I perform reference of an object of one schema file into another?
Also, how do I define myschema: Portion of RAML to include 2 different schema’s?

My Example JSON is:

{
“employee”: {
“name”: “Kishore”,
“projects”: [
{
“name”: “testProject”
},
{
“name”: “anotherTestProject”
}
]
},
“security”: {
“token”: “abchdyaj17253456”
}
}

My Schema’s are:

In Project.schema

{
“type”: “object”,
“properties”: {
“name”: {
“type”: “string”,
“required”: false
}
}
}

In Employee.schema

{
“type”: “object”,
“properties”: {
“name”: {
“type”: “string”,
“required”: true
},
“projects”: {
“type”: “project[]”,
“required”: false
}
}
}

In Security.schema

{
“type”: “object”,
“properties”: {
“token”: {
“type”: “string”,
“required”: true
}
}
}

My RAML Looks like:

#%RAML 1.0
title: Test Complex API
version: v1
baseUri: http://api.testcomplex.com
mediaType: application/json
protocols: [ HTTPS ]

schemas:

  • project: !include schemas/Project.schema
  • security: !include schemas/Security.schema
  • employee: !include schemas/Employee.schema

/helloWorld:
get:
responses:
200:
body:
application/json:
schema: |
{
“employee” : employee,
“security” : security
}
example: |
{
“employee” :
{
“name” : “Kishore”,
“projects” : [
{“name” : “testProject”},
{“name” : “anotherTestProject”}
]
},
“security” : {
“token” : “abchdyaj17253456”
}
}

My Problem is:

  1. When I try to create a RAML like above, it gives me the error’s near schema: portion
    Error - It is not JSON schemaat line 19 col 13
    Error - Syntax error:Expected “(” or name but “{” found.at line 19 col 13
    How do I define the above complex structure as mentioned above?

  2. In employee.schema, I need to refer an object of project which is defined in project.schema.
    So how do we define nested schema’s? I cannot merge Project schema into Employee as I need to reuse this definition in other places.


#2

Hi,

It looks like you’re trying to mix a json-schema definition and RAML 1.0 types. In json-schema you cannot define an array of items with brackets, so the expression “type”: “project[]” is meaningless. The correct way in json-schema is:

projects: {
  "type": "array",
  "items": {
      "$ref": "http://testcomplex.com/api/project.schema"
   }
}

Here, the reference “http://testcomplex.com/api/project.schema” should match the id of Project.schema (which you didn’t define):

{
  "id": "http://testcomplex.com/api/project.schema",
  "type": "object",
  "properties": {
    "name": {
      "type": "string",
      "required": false
    }
  }
}

The full json-schema specs are found here.

Also, I think your schema reference in your /helloWorld resource should either define a new schema inline, or point to a single predefined schema like “schema: employee”. I don’t think what you try is valid. I have some json-schema examples here. If you want to use pure RAML 1.0 types, check the specs here on the RAML 1.0 site.


#3

@Peter_Rigole is right. You cannot define JSON Schemas the same way your do with RAML types. In fact, you can use RAML types from the beginning:

types:
  Project:
    properties:
      name:
        type: string
        required: false
  Employee:
    properties:
      name: string
      projects:
        type: Project[]
        required: true
  Security:
    properties:
      name: string

#4

Thanks @Peter_Rigole and @christian_vogel.
I followed the approach suggested by @Peter_Rigole and used JSON-Schema Definition instead of mixing it with RAML 1.0 types.

The problem with this approach is that I have to host these schema’s and expose them as http resources and then include them in “$ref” field. This worked for me, but needs a bit of workaround.

“$ref”: “http://testcomplex.com/api/project.schema

So If I start using RAML Types instead of JSON-schema definition, can I include them from other files and re-use them?

Example:
Assuming Project.schema and Security.schema is defined using RAML 1.0 types.


types:
  - project: !include schemas/Project.schema
  - security: !include schemas/Security.schema

  Employee:
    properties:
      name: string
      projects:
        type: project[]
        required: true
  

Can this be done? i.e., include multiple Types from different files and access them using the reference name provided?


#5

You can split up RAML Types into several files. Example:

project.raml

#%RAML 1.0 DataType

properties:
  name:
    type: string
    required: false

employee.raml

#%RAML 1.0 DataType

properties:
  name: string
  projects:
    type: array
    items: !include project.raml
    required: true

Please be aware that we are making some improvements based on feedback to the type system at the moment; as well as how you import and re-use these fragments in other types. Although, this is the current way.


#6

RAML 1.0 data types are much more compact than json-schema, so I would definitely look into that as well. In case you want to keep using json-schema, I must add that json-schema allows for both “canonical dereferencing” and “inline dereferencing”, see here. It implies that you don’t really have to host your files in order to resolve them. You may include the other files as a type (formerly called ‘schema’) in your main RAML file and parsers that process your json-schema should be able to resolve all types as long as you include the “id” field in every schema. The ‘$ref’ fields and ‘id’ fields should match when cross-referencing schemas. Check the RAML parser that you use to see if it also fully processes your json-schemas or not.


#7

@Peter_Rigole @christian_vogel

This is exactly what I’m facing.

I want to define things in JSON schema so I can reuse my examples / schemas in other tools and I’m struggling based on that.

Thanks for both of your input.

-Mark


#8

I agree; my plan is after the spec is finalised and the RAML type system does not need any change anymore, to get something working that basically transforms types into JSON or XSD. Although, I can’t promise you something but its on my todo list. (and its huge) :smiley: