loopbackio / loopbackio/loopback-next

OpenAPI spec validation error

Open
#7,403 5 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

bug OpenAPI
Dominant language
TypeScript
Stars
5.1k
Forks
1.1k
Avg merge
2d 21h
Merged PRs (30d)
27

Description

Steps to reproduce

  1. Create spec enhancer, which add custom extension to #/components/schemas
@injectable(asSpecEnhancer, { scope: BindingScope.SINGLETON })
export class ComponentsSpecEnhancer implements OASEnhancer {
  name = 'components';

  modifySpec(spec: OpenApiSpec): ValueOrPromise<OpenApiSpec> {
    const components: ComponentsObject = {
      schemas: {
        TupleArray: {
          title: 'TupleArray',
          type: 'array',
          items: {
            type: 'array',
            items: [{ type: 'number' }, { type: 'number' }],
            additionalItems: false,
          },
          example: [[4, 0.2]],
        },
      },
    };
    return mergeOpenAPISpec(spec, { components });
  }
}
  1. Reference this scheme in route or controller description. In request body, for example.
@requestBody({
      required: true,
      content: {
        'application/json': {
          schema: {
            allOf: [
              getModelSchemaRef(Transaction),
              {
                type: 'object',
                properties: {
                  contribution: {
                    $ref: '#/components/schemas/TupleArray',
                  },
                },
                required: ['contribution'],
              },
            ],
          },
        },
      },
    })
  1. Call this endpoint with correct request body

Current Behavior

Got error from AJV during validation at @loopback/rest/src/validation/request-body.validator.ts:157

[MissingRefError: can't resolve reference #/components/schemas/TupleArray from id #] {
  missingRef: '#/components/schemas/TupleArray',
  missingSchema: ''
}

Expected Behavior

Passed validation

Additional information

linux x64 14.15.1

├── @loopback/authentication@7.0.7
├── @loopback/boot@3.3.0
├── @loopback/context@3.15.1
├── @loopback/core@2.15.1
├── @loopback/logging@0.4.7
├── @loopback/openapi-v3@5.2.1
├── @loopback/repository-json-schema@3.3.1
├── @loopback/repository@3.5.1
├── @loopback/rest-explorer@3.2.0
├── @loopback/rest@9.2.1
├── @loopback/security@0.3.7
├── @loopback/service-proxy@3.1.0

The problem is that resolveControllerSpec at @loopback/openapi-v3/src/controller-spec.ts:71 skips extensions, referenced in api description if $ref doesn't have definitions at the same level (@loopback/openapi-v3/src/controller-spec.ts:493), which IMO, shouldn't happen.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with @loopback/rest/src/validation/request-body.validator.ts:157 and trace how the schema reaches AJV. Compare that flow with @loopback/openapi-v3/src/controller-spec.ts, especially resolveControllerSpec at line 71 and the referenced logic near line 493. Done means a request body using the custom components schema validates without a MissingRefError.

Written by the indexing model from the issue text.

Assessment

Tech stack
openapi, typescript
Domain
api
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Clearly specified
Newbie friendliness
42/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.