raml-spec icon indicating copy to clipboard operation
raml-spec copied to clipboard

RAML 1.0 Arrays: inside an object or plain array?

Open thevangelist opened this issue 8 years ago • 12 comments

Here's what RAML 1.0 says about arrays: https://github.com/raml-org/raml-spec/blob/master/versions/raml-10/raml-10.md#array-type

However the specifications isn't exactly clear whether to use a Array... Assuming I have a of body: Pokemon[], where each Pokemon is:

type: object
description: Pokemon
properties:
  name:
    type: string
    description: Pokemon name
  description:
    type: string
    description: Description of Pokemon

Which is the correct JSON, A or B?

A)

{
    "pokemons": [{
        "name": "Pikachu",
        "description": "Electric"
    }, {
        "name": "Bulbasaur",
        "description": "Dual-type Grass/Poison"
    }]
}

or B)

[{
    "name": "Pikachu",
    "description": "Electric"
}, {
    "name": "Bulbasaur",
    "description": "Dual-type Grass/Poison"
}]

Both are valid json according to: http://jsonlint.com/

thevangelist avatar Jul 25 '16 11:07 thevangelist

Really depends. I would say its mostly A) since you always use a key-value pair for properties in RAML data types. In your example you would have:

types:
  Pokemon:
  PokemonGo:
    properties:
      pokemons: Pokemon[]

The only place where B) can be relevant is if you have something like:

types:
  Pokemon:
  Pokemons: Pokemon[]

sichvoge avatar Jul 25 '16 11:07 sichvoge

Hmm, shouldn't the specification be unambiguous? Say there's two companies implementing equivalents on each side and if the spec isn't unambiguous, both sides can implement it differently?

thevangelist avatar Jul 27 '16 07:07 thevangelist

Its unambiguous as far as you can get with plain English. The actual output just depends if you say a type is an array or a property. Same in JSON schema.

sichvoge avatar Jul 27 '16 10:07 sichvoge

For body: Pokemon[], I'd expect B only.

jsonlint.com is irrelevant here; both examples are JSON, but only B conforms with body: Pokemon[].

freddrake avatar Jul 27 '16 13:07 freddrake

@freddrake so you think we have to clarify anything in the specification? if yes, there are multiple places but maybe we should provide an additional reference document that explains how RAML data types do map into JSON schema?

sichvoge avatar Oct 04 '16 12:10 sichvoge

@sichvoge I think the specification is clear. If more examples are required (indicated by questions like this coming up), an informative document can be added. My interpretation is based on interpreting what's in the spec, without bringing in outside expectations based on what I'd like to see in an actual API.

(I think it's clear that my expectation of RAML is that I can use it to describe an API accurately and unambiguously, even if that API doesn't conform to best practices. Because humans have a hard time agreeing on the later. Best practices considerations are best left to linters.)

freddrake avatar Oct 04 '16 13:10 freddrake

OK. I think an informative document makes some sense especially around mapping into JSON schema. If one would like to start with that, go for it :) Otherwise, it would take me some time to consolidate something

sichvoge avatar Oct 04 '16 13:10 sichvoge

I think this is cleared out, and can be closed.

If anyone has a spare minute, quick question: is it possible to define arrays of objects inline without creating a global type? Something like

[...]
application/json:
  type: object[]
  properties:
    name: string
    age: integer
  example: |
    [
      {
        "name": "harry",
        "age": 18
      }
    ]

stevenroose avatar Jul 12 '17 08:07 stevenroose

Hi, you should be able to do this without using type expressions ([]). In your case, the following works:

[...]
application/json:
  type: array
  items:
    type: object
    properties:
      name: string
      age: integer
    example: |
      [
        {
          "name": "harry",
          "age": 18
        }
      ]

sichvoge avatar Jul 12 '17 09:07 sichvoge

@sichvoge I found out, but thanks a lot for the swift response! (The example key in your snippet needs to be indented one level lower, though :)

stevenroose avatar Jul 12 '17 14:07 stevenroose

Ups, you are right :D

sichvoge avatar Jul 12 '17 14:07 sichvoge

In Anypoint Studio Design center, the following seems like it would work; the API console renders nicely with no errors.

  application/json:
    properties: 
      Customer:
        type: object
        properties: 
          firstName:
          lastName:
          titleCode:
          password:
          carrier:
          MId:
            description: ******ID
          email:
      order:
        type: object
        properties: 
          cart:
            type: object
            properties: 
              txnId:
              accountNumber:
              storeFrontId:
              shipMethod:
              sendToFulfillment:
              byodErrorEmail:
              orderCompletionEmail:
              cartItems:
                type: array
                items:
                  type: object
                  properties:
                    coverageZip: string
              teamId:
              referringMDN:
              securityPIN:
              email:
              userName:
              language:
    example: |
      {
        "Customer": {
          "firstName": "Jack",
          "lastName": "Ophaltrades",
          "titleCode": "Mr.",
          "password": "somepassword",
          "carrier": "Verizon",
          "MId": "1234567",
          "email": "[email protected]"
        },
        "order": {
          "cart": {
            "txnId": "3234234",
            "accountNumber": "stri123456ng",
            "storeFrontId": "1234",
            "shipMethod": "UPS Ground",
            "sendToFulfillment": "Yes",
            "byodErrorEmail": "[email protected]",
            "orderCompletionEmail": "true",
            "cartItems": 
              [
                  { 
                    "coverageZip": "90210"
                  },
                  {
                    "coverageZip": "23423"
                  }
              ],
            "teamId": "1234",
            "referringMDN": "16",
            "securityPIN": "1561",
            "email": "[email protected]",
            "userName": "username",
            "language": "ENG"
          }
        }
      }

However, when I "try it", the HTTP response from the mocking service yields this error.

{ "error": "body: order: cart: cartItems: Cannot read property '#<Object>' of undefined" }

Thoughts as to what is wrong?

thanl223 avatar Oct 24 '18 17:10 thanl223