RAML : How to require parameter A OR parameter B
Asked Answered
S

3

8

I'm writing some REST documentation with RAML but I'm stuck.

My problem: - I have a GET request used for search that can take a parameter "id" or (exclusive or) "reference". Having only one of them is required.

I know how to say "this param is required" but I don't know how to say "having one of these params is required". Is it even possible?

Spano answered 3/5, 2016 at 14:25 Comment(0)
L
7

The following example written in RAML 1.0 defines two object types in Url and File then creates another object Item which requires Url OR File in ext. If you change the included examples (which currently validate), you'll see that they fail if the property does not conform to one or the other definition. Hope that helps! LMK if you have any other questions and I'll do my best.

[EDIT: hmm I think I am seeing your problem now, the final example I've just added, named should_fail, (which has one of each type together in the example) still validates and you want a way to make it fail validation.]

[UPDATE: OK I figured a mildly hacky way to do this. Use maxProperties: 1 in the object which should have properties appear alone, see updated code below which fails the final example during validation.]

#%RAML 1.0
types:
    Url:
        properties:
            url:
                type: string
                example: http://www.cats.com/kittens.jpg
                description: |
                    The url to ingest.

    File:
        properties:
            filename:
                type: string
                example: kittens.jpg
                description: |
                    Name of the file that will be uploaded.


    Item:
        description: |
            An example of a allowing multiple types yet requiring 
            one AND ONLY one of two possible types using RAML 1.0
        properties:
            ext: 
                maxProperties: 1
                type: File | Url
        examples:
            file_example:
                content:
                    ext:
                        filename: video.mp4
            url_example:
                content:
                    ext:
                        url: http://heres.a.url.com/asset.jpg
            should_fail:
                content:
                    ext:
                        url: http://heres.a.url.com/asset.jpg
                        filename: video.mp4
Lowercase answered 5/5, 2016 at 14:24 Comment(3)
Thank you for your answer. I'm not familiar with types from RAML 1.0 (I used RAML 0.8 until now). I will read about it to be sure I can interpret your example well.Spano
You're welcome, essentially the schema field is deprecated and type is the field which replaces it. See docs here.Lowercase
If you are using Mulesoft Design Center, to avoid the "maxProperties facet can only be used with object types" error, just enter type: File | Url before you try to add maxProperties: 1.Airlift
V
2

I had the same problem. User can provide either a textual input OR a file input, but not both.

Both have different fields and I detect the request type from the field names. i.e if the request has [files and parameters], it is a FileInput. If the request has [texts and parameters], it is a TextInput. It is not allowed to provide both text and file within the same request.

I used the union property. See CatAndDog example in Raml 200 documentation for a small example. You can define your types as follows.

types:
  FileInput:
    properties:
      parameters:
        type: Parameters
        description: (...)
      files:
        type: ArchiveCollection | FileCollection
        description: (...)


  TextInput:
    properties:
      parameters:
        type: Parameters
        description: (...)

      texts:
        type: TextCollection
        description: (...)

Then in my POST request body:

/your_route:
  post:
    body:
      multipart/form-data:
        type: TextInput | FileInput

The fields in the body are defined with either TextInput or FileInput type.

Vassalize answered 8/12, 2016 at 10:30 Comment(0)
M
1

In RAML 0.8 you can not describe queryParameters with only one parameter.

In RAML 1.0 you can do this. You should use oneOf in jsonschema for describing Type. Your queryParameters should use this type. Example:

api.raml

#%RAML 1.0
title: AUTH microservice
mediaType: application/json
protocols: [HTTPS]
types:
  - example: !include schemas/example.json
/example:
  get:
    queryParameters:
      type: example

schemas/example.json

{
  "$schema": "http://json-schema.org/draft-04/schema#",
  "type": "object",
  "id": "file://schemas/credentials.json",
  "oneOf": [
    {
      "properties": {"key1": {"type": "string"}},
      "additionalProperties": false
    },
    {
      "properties": {"key2": {"type": "string"}},
      "additionalProperties": false
    }
  ]
}

Also you can use uriParameters. Maybe it will help in your case.

#%RAML 0.8
title: API Using media type in the URL
version: v1
/users{mediaTypeExtension}:
  uriParameters:
    mediaTypeExtension:
      enum: [ .json, .xml ]
      description: Use .json to specify application/json or .xml to specify text/xml
Maurist answered 6/5, 2016 at 14:52 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.