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

WARNING: relational database doesn't support {strict: false} mode. {strict: true} mode will be set for model instead. #4565

Closed
UsmanJavedAttari opened this issue Feb 5, 2020 · 12 comments
Assignees
Labels

Comments

@UsmanJavedAttari
Copy link

UsmanJavedAttari commented Feb 5, 2020

Steps to reproduce

Use {strict: false} in @model(settings : {}) property.

Current Behavior

Getting

WARNING: relational database doesn't support {strict: false} mode. {strict: true} mode will be set for model User instead.

Expected Behavior

The warning should not be here. As I updated the loopback cli and with that I updated loopback dependencies, after updating everything, I am getting this warning. It working fine in previous version. Using MySQL. Also getting these warnings if I get request on any URL.

Additional information

+-- @loopback/[email protected]
+-- @loopback/[email protected]
+-- @loopback/[email protected]
+-- @loopback/[email protected]
+-- @loopback/[email protected]
+-- @loopback/[email protected]
+-- @loopback/[email protected]
+-- @loopback/[email protected]
+-- @loopback/[email protected]
+-- [email protected]
+-- [email protected]
+-- [email protected]

@dougal83
Copy link
Contributor

dougal83 commented Feb 5, 2020

working fine in previous version

I don't think it actual does anything for non-relational dbs. Does anything change when you don't set {strict: false}?

See: loopbackio/loopback-datasource-juggler#1817

@agnes512 Is this correct?

@agnes512
Copy link
Contributor

agnes512 commented Feb 5, 2020

Yes. Because {strict: false} mode is only supported by NoSQL databases. See #4042 and #4042 (comment).

@dougal83 dougal83 removed the bug label Feb 5, 2020
@dougal83
Copy link
Contributor

dougal83 commented Feb 5, 2020

Hey @UsmanJavedAttari

Please remove {strict: false} from @model(settings : {}) property to remove the warning.

@UsmanJavedAttari
Copy link
Author

@dougal83 then I am not able to add extra properties.
Let's say I want to add some extra properties in the response, I have to add those in model and make {strict: false}. Otherwise, it doesn't pick extra properties.

@UsmanJavedAttari
Copy link
Author

And the question is why I didn't get any warnings in the previous version?🤔 Even though I was using {strict: false}.

@agnes512
Copy link
Contributor

agnes512 commented Feb 5, 2020

The warning was added lately. We didn't change anything but add the warning.

@UsmanJavedAttari
Copy link
Author

@dougal83 then I am not able to add extra properties.
Let's say I want to add some extra properties in the response, I have to add those in model and make {strict: false}. Otherwise, it doesn't pick extra properties.

What about this?

@bajtos
Copy link
Member

bajtos commented Feb 6, 2020

@UsmanJavedAttari if I understand your use case correctly, your model contains well-defined property (via @property()) that are stored in your MySQL database, but then you have some custom code that's adding additional properties to be returned in HTTP responses. When a HTTP request to create or modify a model includes those additional properties, they are silently discarded by LoopBack and that's the behavior you are looking for.

Is my description correct?

Where are you adding the extra properties to the response, is it in your controller method?

My recommendation is to convert your model to a plain data object first, and then add the extra properties.

class MyController {
  @get(/*...*/)
  async find(
    @param.query.object('filter', getFilterSchemaFor(TodoList))
    filter?: Filter<TodoList>,
  ): Promise<TodoList[]> {
    const result = this.todoListRepository.find(filter);
    return result.map(it => {
      const data = it.toJSON();
      // add your extra properties here
      return data;
    });
  }
}

There is a catch though: the OpenAPI spec will not describe the additional properties. I believe your original implementation has this problem too. A better solution is to create a new model class for your response data and explicitly describe the properties you are adding on top of the persisted data.

@model()
class CustomerResponse extends Customer {
  // all Product properties are inherited
  // let's add some extra data now
  @property()
  fullName: string;

  // we can fill extra properties in the constructor (for example)
  constructor(data: Partial<Customer>) {
    super(data);
    this.fullName = this.firstName + ' ' + this.lastName;
  }
}

class CustomerController {
  @get(
    // use schema: getModelSchemaRef(CustomerResponse, {includeRelations: true})
  )
  async find(
    // important! the filter object does not accept "extra" properties, 
   // create the filter schema using the base model class
    @param.query.object('filter', getFilterSchemaFor(Customer))
    filter?: Filter<Customer>,
  ): Promise<CustomerResponse[]> {
    const result = this.customerRepository.find(filter);
    return result.map(it => new CustomerResponse(it));
  }
}

@dougal83
Copy link
Contributor

dougal83 commented Feb 6, 2020

@UsmanJavedAttari It is possible to extend a model in the controller as follows:

@model()
export class CustomUserResponse extends User {
  @property({
    type: 'string',
    required: true,
  })
  extendedProp: string;
}

And make the required changes:

@post('/users', {
    responses: {
      '200': {
        description: 'User',
        content: {
          'application/json': {
            schema: {
              'x-ts-type': CustomUserResponse,
            },
          },
        },
      },
    },
  })
  async create(
    // ...
  ): Promise<CustomUserResponse> {
      // ...
      const savedUser = await this.userRepository.create() // ...
      // ...
      return Object.assign({ extendedProp: 'example' }, savedUser);
  }

Lol. Just beaten. :)

@dougal83 dougal83 removed their assignment Feb 14, 2020
@achrinza
Copy link
Member

achrinza commented Apr 5, 2020

Closing as solved, and due to inactivity.

@achrinza achrinza closed this as completed Apr 5, 2020
@mbnoimi
Copy link

mbnoimi commented Dec 24, 2020

I saw the same warning when I generated my models using LB4 CLI for PostgreSQL.

Yes. Because {strict: false} mode is only supported by NoSQL databases. See #4042 and #4042 (comment).

Both of us (@UsmanJavedAttari) use RDBMS not NoSQL!

Please remove {strict: false} from @model(settings : {}) property to remove the warning.

Because I use RDBMS connector I expect from LB4 CLI generating a model without {strict: false}; Why I need to modify it manually?!
Am I right?
If yes; Please reopen this issue.

@achrinza
Copy link
Member

achrinza commented Dec 24, 2020

It's considered a non-issue as RDBMS connectors will ignore it and there's no material problems caused.

The warning was added as a heads up to developers that the setting will be ignored. This was to prevent developers from wasting time debugging why the setting has no effect.

It's not a critical error, it's purely informational and the original behaviour before the warning was added was not changed.

I expect from LB4 CLI generating a model without {strict: false};

I'm guessing this is with regard to lb4 discover? It's added so that the Model definition functions as close as possible to the original database schema, even if it's used on a NoSQL database.

It's intended for workflows where lb4 discover was used and the generated Model was then used with a NoSQL database.

Since lb4 discover is meant to create a Model definition that is "as correct as possible" irregardless of what type of database is used, it's functioning as intended.

Why I need to modify it manually?!

You don't need to remove it. It will be safely ignored by the RDBMS and function identically as if the setting was never there.

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

6 participants