Skip to content

Instantly share code, notes, and snippets.

@jspdown
Created December 20, 2024 16:47
Show Gist options
  • Save jspdown/04e2a88cdb3fe6fafe2a1220f59a26b7 to your computer and use it in GitHub Desktop.
Save jspdown/04e2a88cdb3fe6fafe2a1220f59a26b7 to your computer and use it in GitHub Desktop.
Analyze OpenAPI 3.0.3 path parameters
func main() {
var paths []string
err := filepath.Walk("~/Oss/openapi-directory/APIs", func(path string, info fs.FileInfo, err error) error {
if err != nil {
return fmt.Errorf("error accessing path %q: %v", path, err)
}
if info.IsDir() || !strings.HasSuffix(path, ".yaml") {
return nil
}
paths = append(paths, path)
return nil
})
if err != nil {
panic(err)
}
stats := Stats{
SchemaType: make(map[string]int),
Properties: make(map[string]int),
}
uniqPatterns := make(map[string]struct{})
uniqEnums := make(map[string]struct{})
for _, path := range paths {
loader := openapi3.NewLoader()
doc, err := loader.LoadFromFile(path)
if err != nil {
log.Println("Unable to load specification", path, err)
continue
}
var params []openapi3.Parameter
for _, pathItem := range doc.Paths {
for _, param := range pathItem.Parameters {
if param.Value.In != openapi3.ParameterInPath {
continue
}
params = append(params, *param.Value)
}
for _, operation := range pathItem.Operations() {
for _, param := range operation.Parameters {
if param.Value.In != openapi3.ParameterInPath {
continue
}
params = append(params, *param.Value)
}
}
}
stats.Total += len(params)
for _, param := range params {
if param.Schema == nil {
continue
}
s := param.Schema.Value
stats.WithSchema++
stats.SchemaType[s.Type]++
props := map[string]bool{
// Complex shit.
"oneOf": s.OneOf != nil,
"anyOf": s.AnyOf != nil,
"allOf": s.AllOf != nil,
"not": s.Not != nil,
// Simple.
"enum": s.Enum != nil,
"format": s.Format != "",
// Properties.
"exclusiveMin": s.ExclusiveMin,
"exclusiveMax": s.ExclusiveMax,
"nullable": s.Nullable,
"readInly": s.ReadOnly,
"writeOnly": s.WriteOnly,
"allowEmptyValue": s.AllowEmptyValue,
// Number.
"min": s.Min != nil,
"max": s.Max != nil,
"multipleOf": s.MultipleOf != nil,
// String.
"minLength": s.MinLength != 0,
"maxLength": s.MaxLength != nil,
"pattern": s.Pattern != "",
// Array
"minItems": s.MinItems != 0,
"maxItems": s.MaxItems != nil,
"items": s.Items != nil,
// Object
"required": s.Required != nil,
"properties": s.Properties != nil,
"minProps": s.MinProps != 0,
"maxProps": s.MaxProps != nil,
"additionalProperties": s.AdditionalProperties.Has != nil,
"discriminator": s.Discriminator != nil,
}
for name, isSet := range props {
if isSet {
stats.Properties[name]++
}
}
if s.Pattern != "" {
if _, ok := uniqPatterns[s.Pattern]; !ok {
uniqPatterns[s.Pattern] = struct{}{}
stats.Patterns = append(stats.Patterns, s.Pattern)
}
}
if s.Enum != nil {
key := fmt.Sprintf("%q", s.Enum)
if _, ok := uniqEnums[key]; !ok {
uniqEnums[key] = struct{}{}
stats.Enums = append(stats.Enums, s.Enum)
}
}
}
}
spew.Dump(stats)
}
@jspdown
Copy link
Author

jspdown commented Dec 20, 2024

Total: (int) 188363,
 WithSchema: (int) 124637,
 SchemaType: (map[string]int) (len=7) {
  (string) (len=6) "number": (int) 603,
  (string) (len=7) "boolean": (int) 24,
  (string) "": (int) 166,
  (string) (len=5) "array": (int) 45,
  (string) (len=6) "object": (int) 4,
  (string) (len=6) "string": (int) 112713,
  (string) (len=7) "integer": (int) 11082
 },
 Properties: (map[string]int) (len=17) {
  (string) (len=9) "minLength": (int) 4497,
  (string) (len=4) "enum": (int) 1524,
  (string) (len=5) "oneOf": (int) 144,
  (string) (len=5) "allOf": (int) 2,
  (string) (len=5) "items": (int) 47,
  (string) (len=7) "pattern": (int) 4882,
  (string) (len=9) "maxLength": (int) 4940,
  (string) (len=8) "maxItems": (int) 15,
  (string) (len=5) "anyOf": (int) 20,
  (string) (len=8) "nullable": (int) 232,
  (string) (len=3) "min": (int) 324,
  (string) (len=3) "max": (int) 77,
  (string) (len=10) "properties": (int) 4,
  (string) (len=12) "exclusiveMin": (int) 5,
  (string) (len=20) "additionalProperties": (int) 4,
  (string) (len=6) "format": (int) 6128,
  (string) (len=8) "readInly": (int) 226
 },
 ... 

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment