Available in SwaggerHub SaaS for organizations on the Enterprise plan and in SwaggerHub On-Premise 1.23 and later.
Organizations can add custom rules for API standardization to validate OpenAPI definitions for compliance with API design guidelines. Among other things, these rules can help you verify if:
-
a specific node exists in YAML, regardless of the value,
-
the node name or value matches (or does not match) a regular expression.
-
length of a given field
Each rule consists of a node path (such as $.info.version
) and, optionally, a regular expression that defines valid values for this node. You can customize the rule severity and applicable OpenAPI versions.
Considerations
Custom standardization rules have the same limitations as the built-in rules:
-
They apply only to APIs, not to domains.
-
They check the YAML structure as it is and do not resolve
$refs
.
Create a custom rule
You must be an organization owner to create rules.
-
Go to My Hub and click next to the organization name in the sidebar.
-
Switch to the Standardization tab.
-
Scroll to the bottom and click Add Custom Rule.
-
Configure the rule (see the parameters below) and click Save.
Tip: You can also test the rule directly in the rule editor.
After you create or edit a rule, click Save at the top of the Standardization page to re-scan your organization’s APIs.
Rule parameters
Parameter | Description |
Name | Required. A unique name for this rule, up to 35 characters. The name is also used as a prefix for the rule’s error message. |
Specification | Select if the rule applies to All API definitions. Different API types use a different structure and keywords, so some validations may need separate rules for different OpenAPI versions. |
Rule Severity | Error or Warning. Errors will prevent the API from being published if the Require API to pass Standardization to be publishable option is selected in the Standardization settings. |
Error Message | An optional additional error message displayed in the SwaggerHub editor, up to 130 chars. If omitted, the rule name is used as the error message. If both the name and the error message are specified, the name will prefix the error message. For example, given:
Version -> `info.version` must be major.minor.patch |
Path Required | A JSONPath expression that specifies the target node or nodes to check. For example, $.info.version . Case-sensitive.
We use the jsonpath-plus library that supports some extra selectors in addition to the standard JSONPath syntax. See the jsonpath-plus documentation for the supported syntax.
|
Test For | Specify pattern to search for the regular expression specified in the Pattern field (below). Alternatively, you can choose defined to to check that the node is present, regardless of the value. For example, check that tag objects have a description specified. See also How "defined" rules work below. |
Field | Field to be tested. Set this to @key if you want to test against a field name rather than a value. Also, you can select alphabetical, truthy, or any other available rule. |
Pattern | A regular expression to test against the result of the specified JSONPath. For example, ^\d+\.\d+\.\d+$ .
Note that:
|
Must Match | Regular expression match type: "must match" (check box is selected) or "must not match" (unselected). Appears only if you select Test for patterns. |
Alphabetical | Passing a key enforces alphabetical content for simple arrays or for objects. |
Try It Out | Use this section to test the rule against an existing API. You can either paste the API definition into the Try It Out field or use the IMPORT API button to import an API into the Try It Out field for testing purposes. |
Save | Save the rule. |
Examples
PATTERN custom rule
Version must be major.minor.patch (digits only)
Patterns are case-sensitive by default. For a case-insensitive match, use the format /pattern/i
, for example, /https/i
.
Path Required: $.info.version
Test For: pattern
Pattern: ^\d+\.\d+\.\d+$
Must Match: selected
Paths should not end with a slash
Path Required: $.paths.*~
Test For: pattern
Pattern: ^\/.+\/$
Must Match: unselected
Path names like /pets
and /pets/{id}
are considered valid, but /pets/
and /pets/{id}/
will be flagged.
Response content type must match application/json
Path Required:$.paths.*.*.responses.*.content
Test for: pattern
Field:@key
Pattern:application/json
Must Match: selected
The content field within the responses node can only contain a field that is application/json. Any other field within the content field causes the API definition to fail validation.
DEFINED custom rule
If you specify "defined" in the Test For field, then your custom rule verifies the presence of a specific node or nodes in YAML. The specified JSONPath expression is first split into two components: the last component (the target key name) and everything that precedes it (let's call this "base path"). SwaggerHub then finds all the nodes with the "base path" and checks whether each of them contains the target key. The nodes that do not contain this key fail the validation.
Sample rule: "201 responses to POST requests must include the Location header"
$.paths.*.post.responses.201.headers.Location
\__________________________________/ \______/
find all the nodes at this path and check whether
they have this key
Note that the presence of intermediate nodes is not enforced. For example, the rule above doesn't flag 201 responses without headers
– because these responses aren't found by the "base path" expression ….201.headers
.
# Rule flags this response
responses:
201:
description: Created
headers:
X-RateLimit-Remaining:
type: string
# but not this response
responses:
201:
description: Created
In this example, implement the "Location header exists" rule as two "defined" rules to verify if
- 201 responses have
headers
headers
include theLocation
header:
Defined: $.paths.*.post.responses.201.headers
Defined: $.paths.*.post.responses.201.headers.Location
Example
POST responses must contain 200 response
Path Required:$.paths.*.post.responses
Test For: defined
Field:200
All POST responses in the document must contain the 200
response field.
ALPHABETICAL Custom rule
POST responses must contain 200 response
Examples
Path Required:$.paths.[*]
Test For: alphabetical
Field:tags
All POST responses in the document must contain the 200
response field.
The following alphabetical tags are considered valid:
paths:
/devices:
get:
tags:
- Atag
- Btag
The following non-alphabetical tags are flagged:
paths:
/devices:
get:
tags:
- Btag
- Atag
Path Required: $.paths.[*]
Test For: alphabetical
Field: tags
Alphabetical: greendot
kit:
- object1:
bluedot: 'color'
greendot: 'b'
- object2:
bluedot: 'color'
greendot: 'a'
Object2 is the first because it is sorted by "greendot" keyword.
TRUTHY Custom rule
Path Required:$.paths.[post].parameters.*.
Test For: truthy
Field:required
Required should have value: “”, 0, false, null or undefined.
FALSY custom rule
Path Required:$.paths.[post].parameters.*.
Test For: falsy
Field:required
Required. Should have value different than: “”, 0, false, null, or undefined.
LENGTH custom rule
Choosing this function reveals two additional fields:
- Minimum length
- Maximum length
They are not required but you should provide at least one of them.
Examples
Title must be between 0 and 12 characters.
Path Required:$.info
Test For: length
Field:title
Minimum length: 0
Maximum length: 12
Text must be maximum 12 characters.
Path Required:$.info
Test For: length
Field:title
Minimum length: not specified
Maximum length: 12
The number of elements in an array must be minimum 1.
Path Required:$.
Test For: length
Field:tags
Minimum length: 1
Maximum length: not specified
The number of elements in an array must be between 1 and 6.
Path Required:$.
Test For: length
Field:tags
Minimum length: 1
Maximum length: 6
XOR custom rule
Path $.info
must contain either description or summary.
This shows error if none or both are found at path $.info
.
Path Required:$.
Test For: xor
Field:title
Xor – first value: description.
Xor – second value: summary.
ENUMERATION custom rule
Name of the parameters should be either ‘status’ or ‘tags’.
This shows error if name will not be ‘status’ or ‘tags’.
Path Required:$.paths...parameters.*
Test For: enumeration
Field:name
Enumeration:status, tags
Each entry for enumeration should be followed by Enter or Tab.
OAS 3.1 Pet Store example for many fields:
paths:
/pet/findByStatus:
get:
parameters:
'0':
name: status
/pet/findByTags:
get:
parameters:
'0':
name: tags
/pet/{petId}:
get:
parameters:
'0':
name: petId <---- will show error
post:
parameters:
'0':
name: petId <---- will show error
'1':
name: name <---- will show error
'2':
name: status
delete:
parameters:
'0':
name: api_key <---- will show error
'1':
name: petId <---- will show error
/pet/{petId}/uploadImage:
post:
parameters:
'0':
name: petId <---- will show error
'1':
name: additionalMetadata <---- will show error
/store/order/{orderId}:
get:
parameters:
'0':
name: orderId <---- will show error
delete:
parameters:
'0':
name: orderId <---- will show error
/user/login:
get:
parameters:
'0':
name: username <---- will show error
'1':
name: password <---- will show error
/user/{username}:
get:
parameters:
'0':
name: username <---- will show error
put:
parameters:
'0':
name: username <---- will show error
delete:
parameters:
'0':
name: username <---- will show error
Example for many fields:
The title should be either ‘Very Long Title’ or ‘Long Title’.
Path Required:$.info
Test For: enumeration
Field:title
Enumeration:Very Long Title, Long Title
Each entry for enumeration should be followed by Enter or Tab.
CASING custom rule
Text must be of flat/camel/pascal/kebab/cobol/snake/macro style casing.
This shows error if none or both are found at path $.info
.
Path Required:$.info
Test For: casing
Field:title
Disallow digits: unchecked
Casing: flat/camel/pascal/kebab/cobol/snake/macro
Separator character: none
Allow leading separator: unchecked
flat | verylongtitle |
camel | veryLongTitle |
pascal | VeryLongTitle |
kebab | very-long-title |
cobol | VERY-LONG-TITLE |
snake | very_long_title |
macro | VERY_LONG_TITLE |
Text must be separated by '-' character while enforcing pascal casing.
Very-Long-Title
Path Required:$.info
Test For: casing
Field:title
Disallow digits: unchecked
Casing: pascal
Separator character: '-'
Allow leading separator: unchecked
-Very-Long-Title
Text can start with chosen separator.
Path Required:$.info
Test For: casing
Field:title
Disallow digits: unchecked
Casing: pascal
Separator character: '-'
Allow leading separator: unchecked
verylongtitle
Text can't contain numbers.
Path Required:$.info
Test For: casing
Field:title
Disallow digits: checked
Casing: flat
Separator character: none
Allow leading separator: unchecked
+flat+title123
Text can:
- contain numbers
- be separated by '+' character
- start with '+' character
Path Required:$.info
Test For: casing
Field:title
Disallow digits: unchecked
Casing: flat
Separator character: '+'
Allow leading separator: checked
+very-long+kebab-title
You can separate a text with a kebab-style casing by '+' character and start it with this character.
Path Required:$.info
Test For: casing
Field:title
Disallow digits: unchecked
Casing: kebab
Separator character: '+'
Allow leading separator: checked
Test a rule
You can quickly test custom rules against existing APIs directly in the rule editor. To do that:
-
Edit a rule or start to create a new one.
-
Paste the YAML to test against, or click Import API and load an existing API.
Note: Pasting works only if the path is not yet specified. -
Enter the JSONPath and, optionally, a regular expression to test the value.
-
The validation results appears in the Try It Out section.
The Try It Out section displays YAML nodes found by the specified JSONPath. Leading dashes (-
) indicate individual matches.
Note that a match can be:
- a standalone value
- a simple key: value node
- an array
- multi-property object (including nested objects)
The error and warning icons in the gutter indicate the nodes that failed the validation.
The results may look different. That depends on whether you test a "defined" rule or a pattern-based rule. For example, when you test the existence of tag descriptions ($.tags[*].description
), the results show all the tag objects ("base" nodes) and indicate those without the description
property. However, when you test the values of tag descriptions against a regular expression, the results show the descriptions themselves.
Delete a custom rule
Note: In SwaggerHub On-Premise, this is supported since v. 1.27.
-
In the Custom Rules list, click next to the rule you want to delete and confirm the deletion.
-
Click Save at the top of the Standardization page to save the changes.
Enable or disable a rule
-
Select or clear the check box next to the rule.
-
Click Save at the top of the page to save the changes.