Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

How to define a model @property that allows any scalar value? #4255

Closed
2 tasks
freakpol opened this issue Dec 4, 2019 · 11 comments
Closed
2 tasks

How to define a model @property that allows any scalar value? #4255

freakpol opened this issue Dec 4, 2019 · 11 comments
Assignees
Labels

Comments

@freakpol
Copy link

freakpol commented Dec 4, 2019

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:

@dougal83
Copy link
Contributor

dougal83 commented Dec 4, 2019

Try type: any

Ref: https://loopback.io/doc/en/lb3/LoopBack-types.html

@freakpol
Copy link
Author

freakpol commented Dec 4, 2019

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

@dougal83
Copy link
Contributor

dougal83 commented Dec 4, 2019

Perhaps it needs to be as following:

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

This is what lb4 model produces.

@freakpol
Copy link
Author

freakpol commented Dec 4, 2019

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

@dougal83
Copy link
Contributor

dougal83 commented Dec 4, 2019

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.

@freakpol
Copy link
Author

freakpol commented Dec 4, 2019

Yeah, kinda odd.

@dhmlau dhmlau added bug and removed question labels Dec 9, 2019
@dhmlau
Copy link
Member

dhmlau commented Dec 9, 2019

@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.

@dhmlau dhmlau added the 2020Q1 label Dec 9, 2019
@jannyHou
Copy link
Contributor

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

@luncht1me
Copy link

luncht1me commented Jan 6, 2020

@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.

@dhmlau dhmlau added p3 and removed 2020Q1 labels Feb 13, 2020
@jannyHou jannyHou self-assigned this Mar 18, 2020
@jannyHou jannyHou mentioned this issue Mar 19, 2020
7 tasks
@jannyHou
Copy link
Contributor

Created PR #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: {}
   }
}

@jannyHou
Copy link
Contributor

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

5 participants