Skip to content

Commit

Permalink
parameters schema as type object (#731)
Browse files Browse the repository at this point in the history
* initial draft

* added rule to check if schema in parameters is of type object or not

* added rules.md file

* Highlighted type: object docs/parameters-schema-as-type-object.md

Co-authored-by: Brett DeFoy <[email protected]>

* Update docs/parameters-schema-as-type-object.md

Co-authored-by: Brett DeFoy <[email protected]>

* Update docs/parameters-schema-as-type-object.md

Co-authored-by: Brett DeFoy <[email protected]>

* Update docs/parameters-schema-as-type-object.md

Co-authored-by: Brett DeFoy <[email protected]>

* Update docs/parameters-schema-as-type-object.md

Co-authored-by: Brett DeFoy <[email protected]>

* updated the given condition to check body params from path

* updated doc

---------

Co-authored-by: Brett DeFoy <[email protected]>
  • Loading branch information
tejaswiMinnu and bdefoy authored Aug 19, 2024
1 parent 35f6dea commit f514622
Show file tree
Hide file tree
Showing 5 changed files with 318 additions and 0 deletions.
145 changes: 145 additions & 0 deletions docs/parameters-schema-as-type-object.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,145 @@
# ParametersSchemaAsTypeObject

## Category

ARM Error

## Applies to

ARM OpenAPI(swagger) specs

## Related ARM Guideline Code

- RPC-Arg-V1-01

## Output Message

The schema for body parameters must specify type:object and include a definition for its reference model.

## Description

The schema for body parameters should be defined strictly with the type set as 'object', as ARM does not support other types of definitions. This restriction is in place to ensure a better customer experience.

## How to fix the violation

Please set schema `"type": "object"` in the parameters and define the reference model of the object.

## Good Example 1

```json
...
{
"parameters": {
"ApiVersionParameter": {
"name": "api-version",
// not a body parameter
"in": "query",
"required": true,
// no schema
"type": "string",
"description": "The HDInsight client API Version."
}
}
}
...
```

## Good Example 2

```json
...
{
"parameters": {
"ResourceGroupName": {
"name": "resourceGroupName",
// body parameter
"in": "body",
"required": true,
"schema": {
// refer schema from the definitons
"$ref": "#/definitions/ResourceGroup"
},
"description": "The name of the resource group.",
"x-ms-parameter-location": "method"
}
}
}
...
```

## Good Example 3

```json
...
{
"parameters": {
"ResourceGroupName": {
"name": "resourceGroupName",
// body parameter
"in": "body",
"required": true,
"schema": {
// define schema with type:object
"type": "object",
"Resource": {
"description": "The resource",
"type": "object",
"properties": {
"name": {
"type": "string",
"description": "The name of the Resource"
}
}
}
},
"description": "The name of the resource group.",
"x-ms-parameter-location": "method"
}
}
}
...
```

## Bad Example 1

```json
...
{
"parameters": {
"ResourceGroupName": {
"name": "resourceGroupName",
"in": "body",
"required": true,
"schema": {
// object not defined
"type": "object",
},
"description": "The name of the resource group.",
"x-ms-parameter-location": "method"
}
}
}
...
```

## Bad Example 2

```json
...
{
"parameters": {
"ResourceGroupName": {
"name": "resourceGroupName",
"in": "body",
"required": true,
"schema": {
// type:string is not allowed for body parameters
"type": "string",
},
"description": "The name of the resource group.",
"x-ms-parameter-location": "method"
}
}
}
...
```
6 changes: 6 additions & 0 deletions docs/rules.md
Original file line number Diff line number Diff line change
Expand Up @@ -793,6 +793,12 @@ The rule is to ensure the parameters in the same order as they are ranked in the

Please refer to [parameters-order.md](./parameters-order.md) for details.

### ParametersSchemaAsTypeObject

The schema for body parameters should be defined strictly with the type set as 'object', as ARM does not support other types of definitions. This restriction is in place to ensure a better customer experience.

Please refer to [parameters-schema-as-type-object.md](./parameters-schema-as-type-object.md) for details.

### PatchBodyParametersSchema

A request parameter of the Patch Operation must not have a required/default/'x-ms-mutability:"create"' value.
Expand Down
12 changes: 12 additions & 0 deletions packages/rulesets/generated/spectral/az-arm.js
Original file line number Diff line number Diff line change
Expand Up @@ -3537,6 +3537,18 @@ const ruleset = {
function: parametersInPost,
},
},
ParametersSchemaAsTypeObject: {
rpcGuidelineCode: "RPC-POST-V1-05",
description: "The schema for body parameters must specify type:object and include a definition for its reference model.",
message: "{{description}}",
severity: "error",
resolved: true,
formats: [oas2],
given: "$[paths,'x-ms-paths'].*.*.parameters.*.schema[?(@property === 'type' && @ !=='object')]",
then: {
function: falsy,
},
},
PathContainsSubscriptionId: {
rpcGuidelineCode: "RPC-Uri-V1-01",
description: "Path for resource group scoped CRUD methods MUST contain a subscriptionId parameter.",
Expand Down
18 changes: 18 additions & 0 deletions packages/rulesets/src/spectral/az-arm.ts
Original file line number Diff line number Diff line change
Expand Up @@ -754,6 +754,24 @@ const ruleset: any = {
},
},

///
/// ARM RPC rules for Arg
///

// RPC Code: RPC-Arg-V1-01
ParametersSchemaAsTypeObject: {
rpcGuidelineCode: "RPC-POST-V1-05",
description: "The schema for body parameters must specify type:object and include a definition for its reference model.",
message: "{{description}}",
severity: "error",
resolved: true,
formats: [oas2],
given: "$[paths,'x-ms-paths'].*.*.parameters.*.schema[?(@property === 'type' && @ !=='object')]",
then: {
function: falsy,
},
},

///
/// ARM RPC rules for Uri path patterns
///
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,137 @@
import { Spectral } from "@stoplight/spectral-core"
import linterForRule from "./utils"

let linter: Spectral

const ERROR_MESSAGE = "The schema for body parameters must specify type:object and include a definition for its reference model."

beforeAll(async () => {
linter = await linterForRule("ParametersSchemaAsTypeObject")
return linter
})

test("ParametersSchemaAsTypeObject should find errors", () => {
const myOpenApiDocument = {
swagger: "2.0",
paths: {
"/providers/Microsoft.ConnectedVMwarevSphere/virtualMachine/default": {
get: {
parameters: [
{
$ref: "#/parameters/LoadTestNameParameter",
},
{
$ref: "#/parameters/QuotaBucketNameParameter",
},
],
},
},
},
parameters: {
LoadTestNameParameter: {
in: "body",
name: "loadTestName",
description: "Load Test name.",
required: true,
"x-ms-parameter-location": "method",
schema: {
type: "object",
},
},
QuotaBucketNameParameter: {
in: "body",
name: "quotaBucketName",
description: "Quota Bucket name.",
required: true,
"x-ms-parameter-location": "method",
schema: {
type: "string",
},
},
},
}
return linter.run(myOpenApiDocument).then((results) => {
expect(results.length).toBe(1)
expect(results[0].path.join(".")).toBe(
"paths./providers/Microsoft.ConnectedVMwarevSphere/virtualMachine/default.get.parameters.1.schema.type",
)
expect(results[0].message).toContain(ERROR_MESSAGE)
})
})

test("ParametersSchemaAsTypeObject should find no errors", () => {
const myOpenApiDocument = {
swagger: "2.0",
"/providers/Microsoft.ConnectedVMwarevSphere/virtualMachine/default": {
get: {
parameters: [
{
$ref: "#/parameters/LoadTestNameParameter",
},
{
$ref: "#/parameters/ResourceGroupName",
},
{
$ref: "#/parameters/QuotaBucketNameParameter",
},
],
},
},
definitions: {
ResourceGroup: {
description: "The ResourceGroup model definition.",
properties: {
id: {
readOnly: true,
type: "string",
description: "ResourceGroup Id",
},
},
},
},
parameters: {
LoadTestNameParameter: {
in: "body",
name: "loadTestName",
description: "Load Test name.",
required: true,
"x-ms-parameter-location": "method",
schema: {
$ref: "#/definitions/ResourceGroup",
},
},
QuotaBucketNameParameter: {
in: "body",
name: "quotaBucketName",
description: "Quota Bucket name.",
required: true,
"x-ms-parameter-location": "method",
type: "string",
},
ResourceGroupName: {
name: "resourceGroupName",
in: "body",
required: true,
schema: {
// define schema with type:object
type: "object",
Resource: {
description: "The resource",
type: "object",
properties: {
name: {
type: "string",
description: "The name of the Resource",
},
},
},
},
description: "The name of the resource group.",
"x-ms-parameter-location": "method",
},
},
}
return linter.run(myOpenApiDocument).then((results) => {
expect(results.length).toBe(0)
})
})

0 comments on commit f514622

Please sign in to comment.