OpenAPI 3 Parser

ci workflow

This a Ruby based parser/validator for OpenAPI 3. It is used to convert an OpenAPI file (can be a local file, a URL, a string or even a Ruby hash) into an object graph with a simple API that follows the OpenAPI specification.

Basic example:

require "openapi3_parser"

document = Openapi3Parser.load_url("https://raw.githubusercontent.com/OAI/OpenAPI-Specification/master/examples/v3.0/petstore.yaml")

document.paths["/pets"].get.summary
# => "List all pets"

It aims to support 100% of the OpenAPI 3.0 specification, with key features being:

  • Supports loading a specification by path to a file, URL, Ruby file objects, and strings in YAML and JSON formats, it even supports loading via a Ruby hash;
  • Support for loading references from external files including URLs;
  • Handles recursive references;
  • All of OpenAPI specification mapped to Ruby objects, providing a natural Ruby interface that maps clearly to the specification;
  • OpenAPI files validated with a simple API to quickly and simply see all problems with a file
  • Built-in Markdown to HTML conversion;
  • Documentation for the API to navigate the OpenAPI nodes is available on rubydoc.info.

I've wrote a blog post reflecting on the decisions involved in building this parser in How to write an OpenAPI 3 parser.

Usage

Loading a specification

# by URL
Openapi3Parser.load_url("https://raw.githubusercontent.com/kevindew/openapi3_parser/main/spec/support/examples/petstore-expanded.yaml")

# by path to file
Openapi3Parser.load_file("spec/support/examples/uber.yaml")

# by File
Openapi3Parser.load(File.open("spec/support/examples/uber.yaml"))

# by String
Openapi3Parser.load('{ "openapi": "3.0.0", "info": { "title": "API", "version": "1.0.0" }, "paths": {}  }')

# by Hash
Openapi3Parser.load(openapi: "3.0.0", info: { title: "API", version: "1.0.0" }, paths: {})

Validating

document = Openapi3Parser.load(openapi: "3.0.0", info: {}, paths: {})
document.valid?
# => false
document.errors
# => Openapi3Parser::Validation::ErrorCollection(errors: {"#/info"=>["Missing required fields: title and version"]})

Traversing

document = Openapi3Parser.load_url("https://raw.githubusercontent.com/kevindew/openapi3_parser/main/spec/support/examples/petstore-expanded.yaml")

# by objects

document.info.terms_of_service
# => "http://swagger.io/terms/"

document.paths.keys
# => ["/pets", "/pets/{id}"]

document.paths["/pets"].get.parameters.map(&:name)
# => ["tags", "limit"]

# by hash syntax

document["info"]["termsOfService"]
=> "http://swagger.io/terms/"

document["paths"].keys
# => ["/pets", "/pets/{id}"]

document["paths"]["/pets"]["get"]["parameters"].map(&:name)
# => ["tags", "limit"]

# by a path to a node
document.node_at("#/paths/%2Fpets/get/operationId")
=> "findPets"

document.node_at("#/components/schemas/Pet/allOf/0/required/0")
=> "name"

# or combining

document.components.schemas["Pet"].node_at("#../NewPet")
=> Openapi3Parser::Node::Schema(#/components/schemas/NewPet)

You can learn more about the API on rubydoc.info

Installation

You can install this gem into your bundler application by adding this line to your Gemfile:

gem "openapi3_parser", "~> 0.10.0"

and then running $ bundle install

Or install the gem onto your machine via $ gem install openapi3_parser

Status

This is currently a work in progress and will remain so until it reaches 1.0.

See TODO for details of the features still to implement.

Licence

MIT License