@apistudio/apim-cli
Version:
CLI for API Management Products
257 lines (185 loc) • 7.5 kB
Markdown
This guide explains how to use the Spectral rules generator in this project to create, update, and test validation rules for OpenAPI schema components.
1. [Overview](
2. [Generating Basic Rulesets](
3. [Generating Enhanced Rulesets](
4. [Generating Recursive Rulesets](
5. [Testing Rulesets](
6. [Using Rulesets with Spectral](
7. [Customizing Rules](
8. [Troubleshooting](
This project includes three ruleset generators:
1. **Basic Generator** (`generate-rulesets.js`): Creates simple validation rules for schema components
2. **Enhanced Generator** (`enhanced-generate-rulesets.js`): Creates detailed validation rules for all properties inside the "spec" field
3. **Recursive Generator** (`recursive-generate-rulesets.js`): Creates comprehensive validation rules for all nested properties at any depth
The generated rulesets are used with Spectral to validate API definitions against the schema components.
To generate basic ruleset files for all schema components:
```bash
cd packages/inventory/src/resources/spectral-rulesets
node generate-rulesets.js
```
This will create ruleset files for all schema components in the OpenAPI specification with basic validation rules.
To generate enhanced ruleset files with detailed validation for spec field properties:
```bash
cd packages/inventory/src/resources/spectral-rulesets
node enhanced-generate-rulesets.js
```
This will create ruleset files with comprehensive validation rules for all properties inside the "spec" field of each schema component.
To generate recursive ruleset files with validation for all nested properties at any depth:
```bash
cd packages/inventory/src/resources/spectral-rulesets
node recursive-generate-rulesets.js
```
This will create ruleset files with the most comprehensive validation rules, including:
- Validation for all properties at any nesting level
- Type checking for deeply nested objects and arrays
- Required field validation at all levels
- Enum value validation at all levels
- Prevention of additional properties at all levels
- Support for oneOf, anyOf, and allOf schemas
| Feature | Basic | Enhanced | Recursive |
|---------|-------|----------|-----------|
| Root field validation | ✅ | ✅ | ✅ |
| Top-level spec properties | ❌ | ✅ | ✅ |
| Nested spec properties | ❌ | ✅ (limited) | ✅ |
| Deep nesting support | ❌ | ❌ | ✅ |
| oneOf/anyOf/allOf support | ❌ | ❌ | ✅ |
| Array item validation | ❌ | ✅ (limited) | ✅ |
| Nested array validation | ❌ | ❌ | ✅ |
| Rule count | Low | Medium | High |
To test the generated rulesets:
```bash
node test-ruleset.js
node test-enhanced-ruleset.js
node test-recursive-ruleset.js
```
These scripts will verify that all ruleset files are loaded correctly and report statistics on the number of rules.
To use the generated rulesets with Spectral in your code:
```javascript
import { Spectral } from '@stoplight/spectral-core';
import { getCombinedRuleset } from './spectral-rulesets/combined-ruleset.js';
async function validateApiDefinition(apiDefinition, componentType) {
// Get the combined ruleset
const combinedRuleset = await getCombinedRuleset();
// Get the ruleset for the specific component type
const ruleset = combinedRuleset[`api.ibm.com_v1_${componentType.toLowerCase()}.ruleset.yaml`];
if (!ruleset) {
throw new Error(`No ruleset found for component type: ${componentType}`);
}
// Create a new Spectral instance
const spectral = new Spectral();
// Set the ruleset
spectral.setRuleset(ruleset);
// Run validation
const results = await spectral.run(apiDefinition);
return results;
}
// Example usage
const apiDefinition = {
kind: "API",
apiVersion: "api.ibm.com/v1",
metadata: {
name: "example-api",
version: "1.0.0"
},
spec: {
"api-spec": {
"$path": "/path/to/api-spec"
},
"policy-sequence": [
{ "$ref": "reference/to/policy" }
]
}
};
validateApiDefinition(apiDefinition, "API")
.then(results => {
if (results.length === 0) {
console.log("API definition is valid!");
} else {
console.log("Validation errors:", results);
}
})
.catch(error => {
console.error("Validation failed:", error);
});
```
You can customize the generated rules by editing the ruleset files directly or by modifying the generator scripts.
Each ruleset file follows this structure:
```javascript
export default {
"rules": {
"rule-name": {
"description": "Rule description",
"severity": "error",
"given": "$",
"then": {
"field": "fieldName",
"function": "truthy"
}
},
// More rules...
}
};
```
You can add, modify, or remove rules as needed.
To customize the rule generation logic:
1. Open the generator script (`generate-rulesets.js`, `enhanced-generate-rulesets.js`, or `recursive-generate-rulesets.js`)
2. Modify the relevant functions to change how rules are generated
3. Run the script to regenerate the ruleset files
#### Customizing the Recursive Generator
The recursive generator uses a powerful recursive function called `processObjectProperties` that can be customized to:
- Change the depth of recursion (default is 10 levels)
- Add special handling for specific property types
- Modify rule severity based on property paths
- Add custom validation logic for specific properties
## Troubleshooting
### Common Issues
1. **Module not found errors**: Make sure you're using the correct import paths and that all dependencies are installed.
2. **Schema component not found**: Check that the component name matches exactly what's in the OpenAPI specification.
3. **Validation not working as expected**: Verify that the ruleset is being loaded correctly and that the API definition matches the expected structure.
### Debugging Tips
- Use `console.log` to debug the ruleset generation process
- Check the structure of the generated ruleset files
- Run the test scripts to verify that rulesets are loaded correctly
## Updating Rulesets After Schema Changes
When the OpenAPI specification changes:
1. Run the appropriate generator to regenerate all ruleset files:
```bash
# For basic rules
node generate-rulesets.js
# For enhanced rules
node enhanced-generate-rulesets.js
# For recursive rules
node recursive-generate-rulesets.js
```
2. Update the combined ruleset file if new components were added:
```bash
# Edit combined-ruleset.js to include new components
```
3. Test the updated rulesets:
```bash
# Test the appropriate ruleset
node test-recursive-ruleset.js
```
4. Commit the changes to version control.
// Made with Bob