Skip to content
This repository has been archived by the owner on Feb 17, 2024. It is now read-only.

How do inline definitions look like especially for securedBy or traits, or others? #302

Closed
sichvoge opened this issue Mar 14, 2016 · 7 comments

Comments

@sichvoge
Copy link
Contributor

Reading through the default behaviour of an !include and how these applies to different levels; I wonder how inline definitions (that is an outcome of the !include behaviour) actually looks like?

Let's take traits as an example. Currently 0.8 and 1.0 defines the is node as either a sequence with names that references to a global trait definition or inline definitions (explicitly or implicitly through !include).

As the former is very clear, the latter about inline definitions isn't.

How would you define, for example, multiple !include definitions since RAML 1.0 will remove composition?

Perhaps:

/resource:
  get:
    is:
      trait1:
        queryParameters:
          query1:
      trait2:
        queryParameters:
          query2:

And the equivalent using !include:

/resource:
  get:
    is:
      trait1: !include trait1.raml # trait fragment
      trait2: !include trait2.raml # trait fragment

Would you also be able to do the following?

/resource:
  get:
    is: !include traits.raml

And the content of traits.raml is simple a map (so no library or fragment used here)?

If they get included with a key or complete (is: !include traits.raml); how do you define values for additional properties?

Currently, you are able to do the following:

#%RAML 0.8
title: Example API
version: v1
resourceTypes:
  - searchableCollection:
      get:
        queryParameters:
          <<queryParamName>>:
            description: Return <<resourcePathName>> that have their <<queryParamName>> matching the given value
          <<fallbackParamName>>:
            description: If no values match the value given for <<queryParamName>>, use <<fallbackParamName>> instead
traits:
  - secured:
      queryParameters:
        <<tokenName>>:
          description: A valid <<tokenName>> is required
    paged:
      queryParameters:
        numPages:
          description: The number of pages to return, not to exceed <<maxPages>>
/books:
  type: { searchableCollection: { queryParamName: title, fallbackParamName: digest_all_fields } }
  get:
    is: [ secured: { tokenName: access_token }, paged: { maxPages: 10 } ]

How would that look with inline or includes?


Where the default behaviour of !include is clear, all these different cases are not. It would be good if we can clarify them since the spec is not describing them well.

I have to admit that these very corner cases are not, and shouldn't be, best practices and avoided at all costs, but still these cases are there if we stick with the !include behaviour.

Using references to a global definition (either library or traits) should be recommended of course.

@usarid
Copy link
Contributor

usarid commented Mar 16, 2016

First, let's recall that the value of is is a sequence of traits, not a map. That's not related to whether the traits global declaration takes a map or a sequence. Also, each item in the sequence in is must be either the name of a global trait or an anonymous trait definition, not a key-value pair where the key is a name of a trait. So your first two examples are invalid in any case. But you could make your third example valid

/resource:
  get:
    is: !include traits.raml

if traits.raml were a sequence of anonymous trait definitions:

- queryParameters:
    query1:
- queryParameters:
    query2:

If you do choose to use anonymous trait definitions (whether through an !include or directly in the same file), you won't be able to pass them any parameters, because parameter passing is via a key-value map where the key is the name of the trait (or resource type) and the value is the map of parameters, but these traits have no names.

@sichvoge
Copy link
Contributor Author

So something like that should also be allowed right?

/resource:
  get:
    is:
      - !include trait1.raml
      - !include trait2.raml

And for example the content of trait1.raml could be

queryParameters:
  query1:

@svacas
Copy link
Contributor

svacas commented Mar 16, 2016

I think we shouldn't support inlining traits nor resource types. It's 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.

@sichvoge
Copy link
Contributor Author

I am with @svacas on this. Inline (anonymous) declaration plus includes does not bring too many advantages against the complexity that it creates for the spec and its implementation.

@usarid
Copy link
Contributor

usarid commented Mar 17, 2016

So you would like to disallow

/users:
  type: !include types/collectionBase.raml

which was allowed in RAML 0.8, and instead force the explicit declaration of resource types and traits, e.g.

resourceTypes:
  baseCollection: !include types/collectionBase.raml
/users:
  type: baseCollection

but still allow data types to be defined inline (which is hard to see why we would forbid it):

/users:
  get:
    responses:
      200:
        body:
          type: !include users.json

?

@sichvoge
Copy link
Contributor Author

Indeed, removing the behaviour for traits and resource types would be the correct step forward to simplify the spec significantly, and we are being very clear in our messaging about what @svacas mentioned.

@usarid
Copy link
Contributor

usarid commented Mar 17, 2016

Ok, agreed, let's remove the allowance of inline trait and resource type declarations within the type and is key-value pairs where they're applied. Please assign the appropriate issue to me.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Development

No branches or pull requests

3 participants