Skip to content

lestrrat-go/openapi

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

openapi

[WIP] OpenAPI for Go

Build Status

GoDoc

SYNOPSIS

package openapi_test

import (
  "log"
  "os"

  v2 "github.com/lestrrat-go/openapi/v2"
)

func ExampleV2() {
  const src = `spec/examples/v2.0/petstore-extended.yaml`
  f, err := os.Open(src)
  if err != nil {
    log.Printf(`failed to open file %s: %s`, src, err)
    return
  }

  spec, err := v2.ParseYAML(f)
  if err != nil {
    log.Printf(`failed to parse file %s: %s`, src, err)
    return
  }

  for pathItemIter := spec.Paths().Paths(); pathItemIter.Next(); {
    path, pathItem := pathItemIter.Item()
    for operIter := pathItem.Operations(); operIter.Next(); {
      oper := operIter.Item()
      log.Printf("%s %s", oper.Verb(), path)
    }
  }
}

Status

  • v2/v3 generally works
  • can generate simple gRPC protobuf definition
  • can generate simple Go REST client
  • can generate simple ES6/flow REST client
  • can lint v2/v3 documents (note: validation rules are still not 100% implemented)

Programmatically Build an OpenAPI spec

  • API is geared towards regularity and to be easier for a program to generate this code
  • Use the builder API to build a spec
  • Each builder constructor takes in the required arguments for that component
  • Finalize and build the OpenAPI nodes by calling Build() at the end
  • Properly validate structures

Easier Navigation

OpenAPI by design requires you to remember context as you navigate through the structure. For example, when parsing paths component, when you eventually get to the operation component you need to have remembered

  1. The name of the path you are working on
  2. The HTTP verb that the operation is for

This is because at each level the structure does not contain these information. It's controlled and catalogued by the component one scope above, and that creates really hard-to-work with method signatures like

func processOperation(path, verb string, oper Operation) { ... }

Where you really want to just do

func processOperation(oper Operation) { ... }

This library gives you tools to work with such annoyances by making sure that the structure is immutable once the tree is created, and in doing so we can automatically memoizing some of the information in the components towards the inner scope.

Validation / Lint

oalint command is available to lint your OpenAPI files. Compile using go build ./cmd/oalint/main.go

oalint -file=/path/to/v2spec.yaml -format=yaml
oalint -file=/path/to/v3spec.yaml -format=yaml -openapi-version=3

Code Generation

oagen command is available to generate code. Compile using go build ./cmd/oagen/main.go

Protobuf (gRPC)

Generate a protobuf (gRPC) definition file from OpenAPI spec. This feature has not been extensively tested, but in most simple cases, it should just work. Look into openapi2proto for prior arts.

oagen protobuf \
    -output=/path/to/file.proto \
    -global-option=go_package=myapi \
    spec.yaml

Go/ES6(+Flow) REST Client

Currently oagen restclient command will generate a Go REST client loosely based on Google-ish api (see https://google.golang.org/api)

oagen restclient \
    -target=go \ # or es6flow
    -directory=path/to/dir \
    -package=packageName \
    spec.yaml

CAVEATS

JSON Reference (those pesky $refs) are supported, but only if it's internal to the document itself. I plan on incorporating external references, but in a separate level. I believe external references should be resolved before we do anything with this library.

Releases

No releases published

Packages

No packages published

Languages