Loopback-next: How to define a model @property that allows any scalar value?

Created on 4 Dec 2019  路  11Comments  路  Source: strongloop/loopback-next

I'm want to store any type on a property, for example:

@model()
class MyModel extends Entity{
    @property({id: true})
    id: number;

    @property({
        type: 'I DONT KNOW WHT TO PUT HERE TO ALLOW ANY VALUE'
    })
    value: any;
}

The idea, is that, when I POST to that entity I can send the following examples, and all work the same

POST /mymodels 
{
  "id": 1,
  "value": 1
}
---
POST /mymodels 
{
  "id": 2,
  "value": "1"
}
---
POST /mymodels 
{
  "id": 3,
  "value": true
}
---
POST /mymodels 
{
  "id": 4,
  "value": null
}
---
POST /mymodels 
{
  "id": 5,
  "value": {"a":"b" }
}

Note: Database is a mongo db, so it shouldn't be a problem.

Acceptance Criteria

  • [ ] Specify type any in lb4 model cli should not result in "Unsupported type" error.
  • [ ] Add test to make sure the type can be converted to OpenAPI spec correctly

References:

bug

All 11 comments

Nope, if I use any, loopback says that is not a valid type for the openapi spec:

Cannot start the application. Error: Unsupported type: any

Perhaps it needs to be as following:

@property({ type: 'any', required: true, }) test: any;

This is what lb4 model produces.

Yep, thats what I've tried. And get that error.

I see sorry, I had assumed it the lb4 model command would not give unusable results. I'd guess that an option would be to use type string and store as json.

Yeah, kinda odd.

@freakpol @dougal83, thanks for reporting this issue and analyzing it.
The "unsupported type" error is coming from https://github.com/strongloop/loopback-next/blob/master/packages/repository-json-schema/src/build-schema.ts#L167, and it doesn't include type any.

We have AnyType defined in types
So probably handle that type in build schema, convert the AnyType to OpenAPI schema any type

@freakpol You could for now, define the property type as 'object'... ie:

@property({
  type: 'object'
})
data: anyObjectType

} // end of model

// custom type that's just an object with any value.
type anyObjectType = {
  value: any;
};

Ofc this results in your data being modelInstance.data.value but atleast you'd be able to just do anything with it now.

Created PR https://github.com/strongloop/loopback-next/pull/4930

Define the property in model as:

import {AnyType} from '@loopback/repository';
@property({
    // `@loopback/repository-json-schema` recognizes it
    type: 'any'
  })
  // specify `AnyType` for it
  arbitraryProp: AnyType

Generated json schema would be

arbitraryProp: {
    $ref: '#/definitions/AnyType'
}

Generated openapi spec would be

"components": {
    "schemas": {
      "Todo": {
        "title": "Todo",
        "properties": {
          "id": {
            "type": "number"
          },
          // ...other properties
          // The schema will be generated as a reference
          // TODO: to completely support this feature, we can provide schema for 
          // swagger AnyType out-of-the-box
          // see link https://swagger.io/docs/specification/data-models/data-types/#any
          "arbitraryProp": {
            "$ref": "#/components/schemas/AnyType"
          }
        },
        "required": [
          "title"
        ],
        "additionalProperties": false
      },
  },
}

A follow-up PR is coming for adding the openapi shema for any.
The openapi schema spec for any type will be:

components: {
   schemas: {
      AnyValue: {}
   }
}

Update: now you can define the property as

@property({
  // use type name 'any'
  type: 'any'
})
// specify type as `any`
anyProperty: any

Feel free to reopen the issue if you still have questions. Thanks.

Was this page helpful?
0 / 5 - 0 ratings