diff --git a/docs/spectral-rules.md b/docs/spectral-rules.md index c64b67784..82e34a42e 100644 --- a/docs/spectral-rules.md +++ b/docs/spectral-rules.md @@ -145,6 +145,35 @@ parameters: **Default Severity**: error +## request-body-object + +Request bodies should be objects. + +**Bad Example** + +```yaml +requestBody: + content: + application/json: + schema: + type: string +``` + +**Good Example** + +```yaml +requestBody: + content: + application/json: + schema: + type: object + properties: + prop1: + type: string +``` + +**Default Severity**: warn + ## response-example-provided Response examples are used to generate documentation. To improve the generated documentation, response examples should be provided in the schema object or "next to" the schema object. diff --git a/src/spectral/rulesets/.defaultsForSpectral.yaml b/src/spectral/rulesets/.defaultsForSpectral.yaml index 39f453ed1..1e2539447 100644 --- a/src/spectral/rulesets/.defaultsForSpectral.yaml +++ b/src/spectral/rulesets/.defaultsForSpectral.yaml @@ -163,6 +163,17 @@ rules: resolved: true then: function: error-response-schema + # ensure requestBody is an object + request-body-object: + description: "All request bodies MUST be structured as an object at the top level" + given: $.paths[*][*].requestBody.content[*].schema + severity: error + then: + field: type + function: enumeration + functionOptions: + values: + - object # ensure major version is in path major-version-in-path: description: 'All paths must contain the API major version as a distinct path segment' diff --git a/test/spectral/tests/custom-rules/request-body-object.test.js b/test/spectral/tests/custom-rules/request-body-object.test.js new file mode 100644 index 000000000..073894082 --- /dev/null +++ b/test/spectral/tests/custom-rules/request-body-object.test.js @@ -0,0 +1,55 @@ +const inCodeValidator = require('../../../../src/lib'); + +describe('spectral - test that request body schema is an object', function() { + it('should error only when request body is not an object', async () => { + const spec = { + openapi: '3.0.0', + paths: { + '/path1': { + post: { + operationId: 'addPet', + requestBody: { + content: { + 'application/json': { + schema: { + // no error + type: 'object', + properties: { + prop1: { + type: 'string' + } + } + } + } + } + } + }, + put: { + operationId: 'updatePet', + requestBody: { + content: { + 'application/json': { + schema: { + // error 1 + type: 'array', + items: { + type: 'string' + } + } + } + } + } + } + } + } + }; + + const res = await inCodeValidator(spec, true); + const expectedErrors = res.errors.filter( + err => + err.message === + 'All request bodies MUST be structured as an object at the top level' + ); + expect(expectedErrors.length).toBe(1); + }); +});