Loopback4 `HasOneRepository.create()` constraints behaviour

28 Views Asked by At

Lopoback4 HasOneRepository interface implements create function. Suppose I have a User model and a Profile model where User hasOne Profile. In the controller:

@post('/users/{id}/profile', {
    responses: {
      '200': {
        description: 'User model instance',
        content: {'application/json': {schema: getModelSchemaRef(Profile)}},
      },
    },
  })
  async create(
    @param.path.number('id') id: typeof User.prototype.id,
    @requestBody({
      content: {
        'application/json': {
          schema: getModelSchemaRef(Profile, {
            title: 'NewProfileInUser',
            exclude: ['id'],
            optional: ['userId']
          }),
        },
      },
    }) profile: Omit<Profile, 'id'>,
  ): Promise<Profile> {
    return this.userRepository.profile(id).create(profile);
  }

Testing this endpoint, there are a couple of unexpected result:

  1. Providing an id for non-existence User would still create an entry in the Profile table.
  2. Calling this endpoint multiple times would create multiple entries in the Profile table for the same user which means hasOne is no longer true.

Is this the expected behaviour or am I missing something?. I'm using mariaDB and "@loopback/core": "^5.1.1" and "@loopback/repository": "^6.1.3",

  1. Create a new loopback4 application using lb4 cli.
  2. Create a mysql datasource
  3. Create a new User and Profile models and repositories.
  4. Create a HasOne relation between User and Profile.
  5. Create the controllers.
  6. Test POST: /users/{id}/profile with valid id and random id

Expect:

  1. Throw ENTITY_NOT_FOUND error if user with id do not exists
  2. Throw DUPLICATE error id profile for user with id alreadt exists.

Result:

  1. The profile is created regardless if user with id exists or not
  2. Multiple profile for user with the same id are created violating 'hasOne' relation
  3. The this.userRepository.profile(id).get() would only return the first instance found
0

There are 0 best solutions below