README

OpenAPI initiative analysis

Build Status Build status codecov Slack Status license Go Reference GolangCI Go Report Card

A foundational library to analyze an OAI specification document for easier reasoning about the content.

What's inside?

  • A analyzer providing methods to walk the functional content of a specification
  • A spec flattener producing a self-contained document bundle, while preserving $refs
  • A spec merger ("mixin") to merge several spec documents into a primary spec
  • A spec "fixer" ensuring that response descriptions are non empty

Documentation

FAQ

  • Does this library support OpenAPI 3?

No. This package currently only supports OpenAPI 2.0 (aka Swagger 2.0). There is no plan to make it evolve toward supporting OpenAPI 3.x. This discussion thread relates the full story.

Expand ▾ Collapse ▴

Documentation

Overview

Package analysis provides methods to work with a Swagger specification document from package go-openapi/spec.

Analyzing a specification

An analysed specification object (type Spec) provides methods to work with swagger definition.

Flattening or expanding a specification

Flattening a specification bundles all remote $ref in the main spec document. Depending on flattening options, additional preprocessing may take place:

- full flattening: replacing all inline complex constructs by a named entry in #/definitions
- expand: replace all $ref's in the document by their expanded content

Merging several specifications

Mixin several specifications merges all Swagger constructs, and warns about found conflicts.

Fixing a specification

Unmarshalling a specification with golang json unmarshalling may lead to some unwanted result on present but empty fields.

Analyzing a Swagger schema

Swagger schemas are analyzed to determine their complexity and qualify their content.

Index

Examples

Constants

This section is empty.

Variables

View Source
var (
	// Debug is true when the SWAGGER_DEBUG env var is not empty.
	// It enables a more verbose logging of the spec analyzer.
	Debug = os.Getenv("SWAGGER_DEBUG") != ""
)

Functions

func FixEmptyDesc

func FixEmptyDesc(rs *spec.Response)

    FixEmptyDesc adds "(empty)" as the description to the given Response object if it doesn't already have one and isn't a ref. No-op on nil input.

    func FixEmptyDescs

    func FixEmptyDescs(rs *spec.Responses)

      FixEmptyDescs adds "(empty)" as the description for any Response in the given Responses object that doesn't already have one.

      func FixEmptyResponseDescriptions

      func FixEmptyResponseDescriptions(s *spec.Swagger)

        FixEmptyResponseDescriptions replaces empty ("") response descriptions in the input with "(empty)" to ensure that the resulting Swagger is stays valid. The problem appears to arise from reading in valid specs that have a explicit response description of "" (valid, response.description is required), but due to zero values being omitted upon re-serializing (omitempty) we lose them unless we stick some chars in there.

        func Flatten

        func Flatten(opts FlattenOpts) error

          Flatten an analyzed spec and produce a self-contained spec bundle.

          There is a minimal and a full flattening mode.

          Minimally flattening a spec means:

          - Expanding parameters, responses, path items, parameter items and header items (references to schemas are left
            unscathed)
          - Importing external (http, file) references so they become internal to the document
          - Moving every JSON pointer to a $ref to a named definition (i.e. the reworked spec does not contain pointers
            like "$ref": "#/definitions/myObject/allOfs/1")
          

          A minimally flattened spec thus guarantees the following properties:

          - all $refs point to a local definition (i.e. '#/definitions/...')
          - definitions are unique
          

          NOTE: arbitrary JSON pointers (other than $refs to top level definitions) are rewritten as definitions if they represent a complex schema or express commonality in the spec. Otherwise, they are simply expanded. Self-referencing JSON pointers cannot resolve to a type and trigger an error.

          Minimal flattening is necessary and sufficient for codegen rendering using go-swagger.

          Fully flattening a spec means:

          - Moving every complex inline schema to be a definition with an auto-generated name in a depth-first fashion.
          

          By complex, we mean every JSON object with some properties. Arrays, when they do not define a tuple, or empty objects with or without additionalProperties, are not considered complex and remain inline.

          NOTE: rewritten schemas get a vendor extension x-go-gen-location so we know from which part of the spec definitions have been created.

          Available flattening options:

          - Minimal: stops flattening after minimal $ref processing, leaving schema constructs untouched
          - Expand: expand all $ref's in the document (inoperant if Minimal set to true)
          - Verbose: croaks about name conflicts detected
          - RemoveUnused: removes unused parameters, responses and definitions after expansion/flattening
          

          NOTE: expansion removes all $ref save circular $ref, which remain in place

          TODO: additional options

          - ProgagateNameExtensions: ensure that created entries properly follow naming rules when their parent have set a
            x-go-name extension
          - LiftAllOfs:
             - limit the flattening of allOf members when simple objects
             - merge allOf with validation only
             - merge allOf with extensions only
             - ...
          
          Example

          Code:

          package main
          
          import (
          	"fmt"
          
          	"github.com/go-openapi/analysis"
          	"github.com/go-openapi/loads"
          )
          
          func main() {
          	// Example with spec file in this repo
          	path := "fixtures/flatten.yml"
          	doc, err := loads.Spec(path) // Load spec from file
          	if err == nil {
          		an := analysis.New(doc.Spec()) // Analyze spec
          		// flatten the specification in doc
          		erf := analysis.Flatten(analysis.FlattenOpts{Spec: an, BasePath: path})
          		if erf == nil {
          			fmt.Printf("Specification doc flattened")
          		}
          		// .. the analyzed spec has been updated and may be now used with the reworked spec
          	}
          }
          
          Specification doc flattened
          

          func Mixin

          func Mixin(primary *spec.Swagger, mixins ...*spec.Swagger) []string

            Mixin modifies the primary swagger spec by adding the paths and definitions from the mixin specs. Top level parameters and responses from the mixins are also carried over. Operation id collisions are avoided by appending "Mixin<N>" but only if needed.

            The following parts of primary are subject to merge, filling empty details

            - Info
            - BasePath
            - Host
            - ExternalDocs
            

            Consider calling FixEmptyResponseDescriptions() on the modified primary if you read them from storage and they are valid to start with.

            Entries in "paths", "definitions", "parameters" and "responses" are added to the primary in the order of the given mixins. If the entry already exists in primary it is skipped with a warning message.

            The count of skipped entries (from collisions) is returned so any deviation from the number expected can flag a warning in your build scripts. Carefully review the collisions before accepting them; consider renaming things if possible.

            No key normalization takes place (paths, type defs, etc). Ensure they are canonical if your downstream tools do key normalization of any form.

            Merging schemes (http, https), and consumers/producers do not account for collisions.

            Types

            type AnalyzedSchema

            type AnalyzedSchema struct {
            	IsKnownType      bool
            	IsSimpleSchema   bool
            	IsArray          bool
            	IsSimpleArray    bool
            	IsMap            bool
            	IsSimpleMap      bool
            	IsExtendedObject bool
            	IsTuple          bool
            	IsTupleWithExtra bool
            	IsBaseType       bool
            	IsEnum           bool
            	// contains filtered or unexported fields
            }

              AnalyzedSchema indicates what the schema represents

              func Schema

              func Schema(opts SchemaOpts) (*AnalyzedSchema, error)

                Schema analysis, will classify the schema according to known patterns.

                type ErrorOnParamFunc

                type ErrorOnParamFunc func(spec.Parameter, error) bool

                  ErrorOnParamFunc is a callback function to be invoked whenever an error is encountered while resolving references on parameters.

                  This function takes as input the spec.Parameter which triggered the error and the error itself.

                  If the callback function returns false, the calling function should bail.

                  If it returns true, the calling function should continue evaluating parameters. A nil ErrorOnParamFunc must be evaluated as equivalent to panic().

                  type FlattenOpts

                  type FlattenOpts struct {
                  	Spec *Spec // The analyzed spec to work with
                  
                  	BasePath string // The location of the root document for this spec to resolve relative $ref
                  
                  	// Flattening options
                  	Expand          bool // When true, skip flattening the spec and expand it instead (if Minimal is false)
                  	Minimal         bool // When true, do not decompose complex structures such as allOf
                  	Verbose         bool // enable some reporting on possible name conflicts detected
                  	RemoveUnused    bool // When true, remove unused parameters, responses and definitions after expansion/flattening
                  	ContinueOnError bool // Continue when spec expansion issues are found
                  	// contains filtered or unexported fields
                  }

                    FlattenOpts configuration for flattening a swagger specification.

                    The BasePath parameter is used to locate remote relative $ref found in the specification. This path is a file: it points to the location of the root document and may be either a local file path or a URL.

                    If none specified, relative references (e.g. "$ref": "folder/schema.yaml#/definitions/...") found in the spec are searched from the current working directory.

                    func (*FlattenOpts) ExpandOpts

                    func (f *FlattenOpts) ExpandOpts(skipSchemas bool) *swspec.ExpandOptions

                      ExpandOpts creates a spec.ExpandOptions to configure expanding a specification document.

                      func (*FlattenOpts) Swagger

                      func (f *FlattenOpts) Swagger() *swspec.Swagger

                        Swagger gets the swagger specification for this flatten operation

                        type SchemaOpts

                        type SchemaOpts struct {
                        	Schema   *spec.Schema
                        	Root     interface{}
                        	BasePath string
                        	// contains filtered or unexported fields
                        }

                          SchemaOpts configures the schema analyzer

                          type SchemaRef

                          type SchemaRef struct {
                          	Name     string
                          	Ref      spec.Ref
                          	Schema   *spec.Schema
                          	TopLevel bool
                          }

                            SchemaRef is a reference to a schema

                            type SecurityRequirement

                            type SecurityRequirement struct {
                            	Name   string
                            	Scopes []string
                            }

                              SecurityRequirement is a representation of a security requirement for an operation

                              type Spec

                              type Spec struct {
                              	// contains filtered or unexported fields
                              }

                                Spec is an analyzed specification object. It takes a swagger spec object and turns it into a registry with a bunch of utility methods to act on the information in the spec.

                                Example

                                Code:

                                package main
                                
                                import (
                                	"fmt"
                                
                                	"github.com/go-openapi/analysis"
                                	"github.com/go-openapi/loads"
                                )
                                
                                func main() {
                                	// Example with spec file in this repo
                                	path := "fixtures/flatten.yml"
                                	doc, err := loads.Spec(path) // Load spec from file
                                	if err == nil {
                                		an := analysis.New(doc.Spec()) // Analyze spec
                                
                                		paths := an.AllPaths()
                                		fmt.Printf("This spec contains %d paths", len(paths))
                                	}
                                }
                                
                                This spec contains 2 paths
                                

                                func New

                                func New(doc *spec.Swagger) *Spec

                                  New takes a swagger spec object and returns an analyzed spec document. The analyzed document contains a number of indices that make it easier to reason about semantics of a swagger specification for use in code generation or validation etc.

                                  func (*Spec) AllDefinitionReferences

                                  func (s *Spec) AllDefinitionReferences() (result []string)

                                    AllDefinitionReferences returns json refs for all the discovered schemas

                                    func (*Spec) AllDefinitions

                                    func (s *Spec) AllDefinitions() (result []SchemaRef)

                                      AllDefinitions returns schema references for all the definitions that were discovered

                                      func (*Spec) AllEnums

                                      func (s *Spec) AllEnums() map[string][]interface{}

                                        AllEnums returns all the enums found in the spec the map is cloned to avoid accidental changes

                                        func (*Spec) AllItemsReferences

                                        func (s *Spec) AllItemsReferences() (result []string)

                                          AllItemsReferences returns the references for all the items in simple schemas (parameters or headers).

                                          NOTE: since Swagger 2.0 forbids $ref in simple params, this should always yield an empty slice for a valid Swagger 2.0 spec.

                                          func (*Spec) AllParameterReferences

                                          func (s *Spec) AllParameterReferences() (result []string)

                                            AllParameterReferences returns json refs for all the discovered parameters

                                            func (*Spec) AllPathItemReferences

                                            func (s *Spec) AllPathItemReferences() (result []string)

                                              AllPathItemReferences returns the references for all the items

                                              func (*Spec) AllPaths

                                              func (s *Spec) AllPaths() map[string]spec.PathItem

                                                AllPaths returns all the paths in the swagger spec

                                                func (*Spec) AllPatterns

                                                func (s *Spec) AllPatterns() map[string]string

                                                  AllPatterns returns all the patterns found in the spec the map is cloned to avoid accidental changes

                                                  func (*Spec) AllReferences

                                                  func (s *Spec) AllReferences() (result []string)

                                                    AllReferences returns all the references found in the document, with possible duplicates

                                                    func (*Spec) AllRefs

                                                    func (s *Spec) AllRefs() (result []spec.Ref)

                                                      AllRefs returns all the unique references found in the document

                                                      func (*Spec) AllResponseReferences

                                                      func (s *Spec) AllResponseReferences() (result []string)

                                                        AllResponseReferences returns json refs for all the discovered responses

                                                        func (*Spec) ConsumesFor

                                                        func (s *Spec) ConsumesFor(operation *spec.Operation) []string

                                                          ConsumesFor gets the mediatypes for the operation

                                                          func (*Spec) HeaderEnums

                                                          func (s *Spec) HeaderEnums() map[string][]interface{}

                                                            HeaderEnums returns all the enums found in response headers the map is cloned to avoid accidental changes

                                                            func (*Spec) HeaderPatterns

                                                            func (s *Spec) HeaderPatterns() map[string]string

                                                              HeaderPatterns returns all the patterns found in response headers the map is cloned to avoid accidental changes

                                                              func (*Spec) ItemsEnums

                                                              func (s *Spec) ItemsEnums() map[string][]interface{}

                                                                ItemsEnums returns all the enums found in simple array items the map is cloned to avoid accidental changes

                                                                func (*Spec) ItemsPatterns

                                                                func (s *Spec) ItemsPatterns() map[string]string

                                                                  ItemsPatterns returns all the patterns found in simple array items the map is cloned to avoid accidental changes

                                                                  func (*Spec) OperationFor

                                                                  func (s *Spec) OperationFor(method, path string) (*spec.Operation, bool)

                                                                    OperationFor the given method and path

                                                                    func (*Spec) OperationForName

                                                                    func (s *Spec) OperationForName(operationID string) (string, string, *spec.Operation, bool)

                                                                      OperationForName gets the operation for the given id

                                                                      func (*Spec) OperationIDs

                                                                      func (s *Spec) OperationIDs() []string

                                                                        OperationIDs gets all the operation ids based on method an dpath

                                                                        func (*Spec) OperationMethodPaths

                                                                        func (s *Spec) OperationMethodPaths() []string

                                                                          OperationMethodPaths gets all the operation ids based on method an dpath

                                                                          func (*Spec) Operations

                                                                          func (s *Spec) Operations() map[string]map[string]*spec.Operation

                                                                            Operations gathers all the operations specified in the spec document

                                                                            func (*Spec) ParameterEnums

                                                                            func (s *Spec) ParameterEnums() map[string][]interface{}

                                                                              ParameterEnums returns all the enums found in parameters the map is cloned to avoid accidental changes

                                                                              func (*Spec) ParameterPatterns

                                                                              func (s *Spec) ParameterPatterns() map[string]string

                                                                                ParameterPatterns returns all the patterns found in parameters the map is cloned to avoid accidental changes

                                                                                func (*Spec) ParametersFor

                                                                                func (s *Spec) ParametersFor(operationID string) []spec.Parameter

                                                                                  ParametersFor the specified operation id.

                                                                                  Assumes parameters properly resolve references if any and that such references actually resolve to a parameter object. Otherwise, panics.

                                                                                  func (*Spec) ParamsFor

                                                                                  func (s *Spec) ParamsFor(method, path string) map[string]spec.Parameter

                                                                                    ParamsFor the specified method and path. Aggregates them with the defaults etc, so it's all the params that apply for the method and path.

                                                                                    Assumes parameters properly resolve references if any and that such references actually resolve to a parameter object. Otherwise, panics.

                                                                                    func (*Spec) ProducesFor

                                                                                    func (s *Spec) ProducesFor(operation *spec.Operation) []string

                                                                                      ProducesFor gets the mediatypes for the operation

                                                                                      func (*Spec) RequiredConsumes

                                                                                      func (s *Spec) RequiredConsumes() []string

                                                                                        RequiredConsumes gets all the distinct consumes that are specified in the specification document

                                                                                        func (*Spec) RequiredProduces

                                                                                        func (s *Spec) RequiredProduces() []string

                                                                                          RequiredProduces gets all the distinct produces that are specified in the specification document

                                                                                          func (*Spec) RequiredSecuritySchemes

                                                                                          func (s *Spec) RequiredSecuritySchemes() []string

                                                                                            RequiredSecuritySchemes gets all the distinct security schemes that are specified in the swagger spec

                                                                                            func (*Spec) SafeParametersFor

                                                                                            func (s *Spec) SafeParametersFor(operationID string, callmeOnError ErrorOnParamFunc) []spec.Parameter

                                                                                              SafeParametersFor the specified operation id.

                                                                                              Does not assume parameters properly resolve references or that such references actually resolve to a parameter object.

                                                                                              Upon error, invoke a ErrorOnParamFunc callback with the erroneous parameters. If the callback is set to nil, panics upon errors.

                                                                                              func (*Spec) SafeParamsFor

                                                                                              func (s *Spec) SafeParamsFor(method, path string, callmeOnError ErrorOnParamFunc) map[string]spec.Parameter

                                                                                                SafeParamsFor the specified method and path. Aggregates them with the defaults etc, so it's all the params that apply for the method and path.

                                                                                                Does not assume parameters properly resolve references or that such references actually resolve to a parameter object.

                                                                                                Upon error, invoke a ErrorOnParamFunc callback with the erroneous parameters. If the callback is set to nil, panics upon errors.

                                                                                                func (*Spec) SchemaEnums

                                                                                                func (s *Spec) SchemaEnums() map[string][]interface{}

                                                                                                  SchemaEnums returns all the enums found in schemas the map is cloned to avoid accidental changes

                                                                                                  func (*Spec) SchemaPatterns

                                                                                                  func (s *Spec) SchemaPatterns() map[string]string

                                                                                                    SchemaPatterns returns all the patterns found in schemas the map is cloned to avoid accidental changes

                                                                                                    func (*Spec) SchemasWithAllOf

                                                                                                    func (s *Spec) SchemasWithAllOf() (result []SchemaRef)

                                                                                                      SchemasWithAllOf returns schema references to all schemas that are defined with an allOf key

                                                                                                      func (*Spec) SecurityDefinitionsFor

                                                                                                      func (s *Spec) SecurityDefinitionsFor(operation *spec.Operation) map[string]spec.SecurityScheme

                                                                                                        SecurityDefinitionsFor gets the matching security definitions for a set of requirements

                                                                                                        func (*Spec) SecurityDefinitionsForRequirements

                                                                                                        func (s *Spec) SecurityDefinitionsForRequirements(requirements []SecurityRequirement) map[string]spec.SecurityScheme

                                                                                                          SecurityDefinitionsForRequirements gets the matching security definitions for a set of requirements

                                                                                                          func (*Spec) SecurityRequirementsFor

                                                                                                          func (s *Spec) SecurityRequirementsFor(operation *spec.Operation) [][]SecurityRequirement

                                                                                                            SecurityRequirementsFor gets the security requirements for the operation

                                                                                                            Directories

                                                                                                            Path Synopsis