libopenapi-validator

repository·main·Indexed 41 days ago

https://github.com/pb33f/libopenapi-validator

A Go module for validating OpenAPI 3.0, 3.1, and 3.2 specifications. It provides tools to validate HTTP requests, HTTP responses, OpenAPI documents, and individual JSON/YAML schemas. It includes a CLI tool for document validation and supports features such as request default application, strict server matching, and custom regex engines (re2, ecmascript).

Tokens
3.5K
Snippets
15
Records
22
Agent score
49%

What's inside libopenapi-validator

  1. What can libopenapi-validator validate?

    main

    The validator is designed to validate several different entities against an OpenAPI 3+ specification:

    • http.Request: Validates an incoming HTTP request.
    • http.Response: Validates an outgoing HTTP response.
    • libopenapi.Document: Validates the OpenAPI document itself.
    • base.Schema: Validates a specific schema against a JSON or YAML blob or an unmarshalled object.
  2. How request defaults are applied during validation

    main

    The libopenapi-validator can automatically apply default values defined in your OpenAPI specification to an incoming *http.Request. This process, known as 'staging request defaults', ensures that if a client omits a parameter or a request body field that has a default value in the schema, the validator treats the request as if those values were present.

    The staging process follows these steps:

    1. Snapshotting: The original request is cloned to avoid mutating the caller's input prematurely.
    2. Parameter Defaults: The validator checks query, header, and cookie parameters. If a parameter is missing from the request but has a default in the schema, it is injected into the staged request.
    3. Request Body Defaults: If ValidateRequestBody is enabled, the validator decodes the request body, applies schema defaults to the decoded object (recursively through allOf, properties, and items), and then re-encodes the modified object back into the request body.
    4. Mutation: If validation succeeds, the original *http.Request is updated with the staged URL, Headers, and Body to reflect the applied defaults.
  3. Use the validate CLI to validate OpenAPI documents

    main

    The validate command is a CLI tool used to check if an OpenAPI Specification (OAS) document (YAML or JSON) conforms to the OpenAPI specification using libopenapi-validator.

    Usage: validate [OPTIONS] <file>

    Examples:

    Validate a YAML file using the ECMAScript regex engine:

    go run main.go --regexengine=ecmascript ./my-api-spec.yaml

    Validate a YAML file by pre-converting it to JSON (useful for complex mappings):

    go run main.go --yaml2json ./my-api-spec.yaml
    go run main.go --regexengine=ecmascript ./my-api-spec.yaml
  4. Initialize a Validator in Go

    main

    Use validator.NewValidatorFromV3Model to create a validator instance. You can pass several configuration options to customize behavior, such as strict server matching or standard body decoders.

    Available Configuration Options (Examples):

    • config.WithStrictServerMatching(): Enables strict server matching.
    • config.WithStandardBodyDecoders(): Uses standard body decoders.
    • config.WithRejectUnsupportedBodyContent(): Rejects unsupported body content.
    • config.WithRequestDefaults(): Applies request defaults.
    v := validator.NewValidatorFromV3Model(&model.Model,
        config.WithStrictServerMatching(),
        config.WithStandardBodyDecoders(),
        config.WithRejectUnsupportedBodyContent(),
        config.WithRequestDefaults(),
    )
  5. Configure request body default validation

    main

    To enable or disable the application of default values to the request body, you must configure the ValidateRequestBody option within your validator's options.

    Note that for request body defaults to work, your validator must have a valid BodyRegistry configured with appropriate Decoder and Encoder implementations for the Content-Type being used in the request.

  6. Configure CLI validation options

    main

    The validate CLI tool supports the following flags:

    • --regexengine: Specifies a custom regex engine. Defaults to re2. Supported values include: none, ignorecase, multiline, explicitcapture, compiled, singleline, ignorepatternwhitespace, righttoleft, debug, ecmascript, re2, unicode.
    • --yaml2json: Converts YAML files to JSON before validation. This is recommended for OpenAPI specs with deeply nested schema definitions or complex allOf, oneOf, or anyOf structures to avoid ambiguous errors caused by map[interface{}]interface{} structures in libopenapi.
    # Example: Use ecmascript regex engine
    go run github.com/pb33f/libopenapi-validator/cmd/validate@latest --regexengine=ecmascript <file>
    
    # Example: Enable YAML to JSON conversion
    go run github.com/pb33f/libopenapi-validator/cmd/validate@latest --yaml2json <file>
  7. Validate an OpenAPI Document via CLI

    main

    You can validate an OpenAPI specification file directly from the command line using the validate command. This is useful for CI/CD pipelines or manual checks.

    Usage: go run github.com/pb33f/libopenapi-validator/cmd/validate@latest [--regexengine] [--yaml2json] <file>

    go run github.com/pb33f/libopenapi-validator/cmd/validate@latest [--regexengine] [--yaml2json] <file>
  8. Initialize a Validator with NewValidator

    main

    To start validating OpenAPI 3+ documents, use NewValidator. This function takes a libopenapi.Document and optional config.Option arguments. It builds a V3 model from the document and returns a Validator instance. If the document cannot be converted to a V3 model, it returns an error.

    Note: The validator internally builds a radix tree for efficient path lookups and warms schema caches to optimize runtime performance.

    import (
    	"github.com/pb33f/libopenapi"
    	"github.com/pb33f/libopenapi-validator"
    )
    
    // Assuming 'doc' is a valid libopenapi.Document
    validator, errs := validator.NewValidator(doc)
    if len(errs) > 0 {
    	// handle errors
    }
    // Use validator to perform checks
  9. Calculate a compatibility path for a request

    main

    Use compatibilityPath to derive a relative path from an *http.Request based on the base URLs defined in an OpenAPI *v3.Document.

    This is useful when the incoming request URL includes the full server base path (e.g., https://api.example.com/v1/users) and you need to strip the base path (e.g., /v1) to get the path relative to the API root (e.g., /users).

    It iterates through the document.Servers and, if a match is found where the request path starts with the server's URL path, it trims that prefix. It also preserves URL fragments.

    // Returns the path relative to the server base URL
    relPath := router.CompatibilityPath(request, document)
  10. Apply request defaults to an http.Request

    main

    The validator uses an internal mechanism to stage defaults. While the primary entry point for users is typically a high-level validation method, the underlying logic relies on validateWithRequestDefaults.

    When defaults are applied, the following fields of the *http.Request are updated if validation passes:

    • URL (including Query parameters)
    • Header
    • Body
    • GetBody
    • ContentLength