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

Type/Interface used with request body validation is ignored #2641

Closed
frodoe7 opened this issue Mar 24, 2019 · 4 comments
Closed

Type/Interface used with request body validation is ignored #2641

frodoe7 opened this issue Mar 24, 2019 · 4 comments
Labels
OpenAPI REST Issues related to @loopback/rest package and REST transport in general

Comments

@frodoe7
Copy link

frodoe7 commented Mar 24, 2019

Description / Steps to reproduce / Feature proposal

Given the following interface defined inside a controller:

interface idAndAge {
 id : string,
 age : number
}

and here is the endpoint definition:

@put('/tests')
  async replaceById(
    @requestBody() test: idAndAge,// <--to validate the input
  ): Promise<void> {
    await this.testRepository.updateAll(test,{id : test.id});
  }

When this endpoint receives the following input for example (which has properties not defined in the interface):

{ anyKey: anyValue }

it accept it and ignore the validation

it should not allow the below values - because they are not included/against our interface idAndAge

{ anyKey: anyValue }

please check this repo , if you'd like to test the issue

@shadyanwar
Copy link

I am guessing this could be related to #1179 and #2082

@bajtos
Copy link
Member

bajtos commented Mar 26, 2019

I am afraid TypeScript does not capture information about interfaces at runtime. Interfaces exist at compile time only.

You have two options:

  • Describe your data type as a class, use @model and @property decorators.

    @model()
    class idAndAge {
      @property()
       id : string,
      
      @property()
      age : number
    }
  • Provide an explicit schema for your request body argument.

    class MyController {
      // ...
      @put('/tests')
      async replaceById(
        @requestBody({
          content: {
            'application/json': {
              schema: {
                 // your OpenAPI schema goes here
              }
            },
          },
        })
        test: idAndAge,// <--to validate the input
      ): Promise<void> {
        await this.testRepository.updateAll(test,{id : test.id});
      }
    }

@bajtos bajtos added question OpenAPI REST Issues related to @loopback/rest package and REST transport in general labels Mar 26, 2019
@bajtos bajtos closed this as completed Mar 26, 2019
@frodoe7
Copy link
Author

frodoe7 commented Mar 26, 2019

@bajtos

Thank you for the quick response.

I have tried the first option. Unfortunately, it gives the following error:
Unhandled error in PUT /tests: 500 Error: The key 'repositories.TestRepository' is not bound to any value in context 0c7f5a30-4fd2-11e9-8580- 2faabf6cb00d at AyApplication.getBinding (../LB4RequestbodyValidation/node_modules/@loopback/context/dist/context.js:503:15) at RestServer.getBinding (../LB4RequestbodyValidation/node_modules/@loopback/context/dist/context.js:499:33) at RequestContext.getBinding (../LB4RequestbodyValidation/node_modules/@loopback/context/dist/context.js:499:33) at RequestContext.getValueOrPromise (../LB4RequestbodyValidation/node_modules/@loopback/context/dist/context.js:5 38:30) at resolution_session_1.ResolutionSession.runWithInjection.s (../LB4RequestbodyValidation/node_modules/@loopback/ context/dist/resolver.js:103:24) at value_promise_1.tryWithFinally (../LB4RequestbodyValidation/node_modules/@loopback/context/dist/resolution-session.js:89:53) at Object.tryWithFinally (../LB4RequestbodyValidation/node_modules/@loopback/context/dist/value-promise.js:158:18) at Function.runWithInjection (../LB4RequestbodyValidation/node_modules/@loopback/context/dist/resolution-session.js:89:32) at resolve (../LB4RequestbodyValidation/node_modules/@loopback/context/dist/resolver.js:94:59) at value_promise_1.resolveList (../LB4RequestbodyValidation/node_modules/@loopback/context/dist/resolver.js:175:16) at Object.resolveList (../LB4RequestbodyValidation/node_modules/@loopback/context/dist/value-promise.js:131:32) at resolveInjectedArguments (../LB4RequestbodyValidation/node_modules/@loopback/context/dist/resolver.js:158:28) at Object.instantiateClass (../LB4RequestbodyValidation/node_modules/@loopback/context/dist/resolver.js:39:27) at Binding._getValue (../LB4RequestbodyValidation/node_modules/@loopback/context/dist/binding.js:388:55) at resolution_session_1.ResolutionSession.runWithBinding.s (../LB4RequestbodyValidation/node_modules/@loopback/context/dist/binding.js:206:90) at value_promise_1.tryWithFinally (../LB4RequestbodyValidation/node_modules/@loopback/context/dist/resolution-session.js:69:53)

You can find it in this repo

However, the second option (which I have been already using) is working without a problem:

      content: {
        'application/json': {
          schema: {
            type: 'object',
            additionalProperties: false,
            properties: {
              id: {type: 'string'},
              age: {type: 'number'}
            },
            required: ['id', 'age'],
          },
        },

But of course, it will be better in my view to have a model used for validation instead of manually adding the properties. So it would be great if we get option 1 to work.

@bajtos
Copy link
Member

bajtos commented Mar 28, 2019

I have tried the first option. Unfortunately, it gives the following error:

Unhandled error in PUT /tests: 500 Error: The key 'repositories.TestRepository' 
is not bound to any value in context 0c7f5a30-4fd2-11e9-8580- 2faabf6cb00d

That problem looks unrelated to model validation, at least I don't see any obvious reason how using class idAndAge { can trigger it. Is it possible that your application is misconfigured in the sense that the repository class is either not bound at all, or is bound under a different key?

I am afraid I don't have bandwidth to look into this in more details right now. If you manage to find any new information, then feel free to open a new issue. Just make sure to create a sandbox app per our bug reporting instructions.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
OpenAPI REST Issues related to @loopback/rest package and REST transport in general
Projects
None yet
Development

No branches or pull requests

3 participants