openapi2proto

package module
v0.1.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Mar 27, 2018 License: Apache-2.0 Imports: 18 Imported by: 0

README

openapi2proto Build Status

This tool will accept an OpenAPI/Swagger definition (yaml or JSON) and generate a Protobuf v3 schema and gRPC service definition from it.

Install

To install, have Go installed with $GOPATH/bin on your $PATH and then:

go get -u github.com/NYTimes/openapi2proto/cmd/openapi2proto

Run

There are 3 CLI flags for using the tool:

  • -spec to point to the appropriate OpenAPI spec file
  • -options to include google.api.http options for grpc-gateway users. This is disabled by default.
  • -out to have the output written to a file rather than Stdout. Defaults to Stdout if this is not specified

Protobuf Tags

  • To allow for more control over how your protobuf schema evolves, all parameters and property definitions will accept an optional extension parameter, x-proto-tag, that will overide the generated tag with the value supplied.

External Files

  • Any externally referenced Open API spec will be fetched and inlined.
  • Any externally referenced Protobuf files will be added as imports.
    • Example usage: $ref: "google/protobuf/timestamp.proto#/google.protobuf.Timestamp"

Global Options

Protocol Buffer options such as package names are supported via x-global-options key.

x-global-options:
  go_package: myawesomepackage

Will generate:

option go_package = "myawesomepackage"

Extensions

Global extensions may be generated by specifying x-extensions key.

x-extensions:
- base: google.protobuf.MethodOptions
  fields:
  - name: role
    type: string
    number: 50001
  - name: visibility
    type: string
    number: 50002
  - name: timeout
    type: int32
    number: 50003

Will generate:

extend google.protobuf.MethodOptions {
    string role = 50001;
    string visibility = 50002;
    int32 timeout = 50003;
}

Nested extensions are currently not supported.

Method Options

Method options may be generated by specifying the x-options key within each method.

paths:
  /foo
    post:
      x-options:
        bar: baz

Will generate:

    rpc foo(...) returns (...) {
      option (bar) = "baz";
    }

Caveats

  • Fields with scalar types that can also be "null" will get wrapped with one of the google.protobuf.*Value types.
  • Fields with that have more than 1 type and the second type is not "null" will be replaced with the google.protobuf.Any type.
  • Endpoints that respond with an array will be wrapped with a message type that has a single field, 'items', that contains the array.
  • Only "200" and "201" responses are inspected for determining the expected return value for RPC endpoints.
  • To prevent enum collisions and to match the protobuf style guide, enum values will be CAPITALS_WITH_UNDERSCORES and nested enum values and will have their parent types prepended.

Example

╰─➤  openapi2proto -spec swagger.yaml -options
syntax = "proto3";

import "google/protobuf/empty.proto";

import "google/api/annotations.proto";

package swaggerpetstore;

message GetPetsRequest {
    // maximum number of results to return
    int32 limit = 1;
    // tags to filter by
    repeated string tags = 2;
}

message PostPetsRequest {
    // Pet to add to the store
    Pet pet = 1;
}

message GetPetsIdRequest {
    // ID of pet to fetch
    int64 id = 1;
}

message DeletePetsIdRequest {
    // ID of pet to delete
    int64 id = 1;
}

message Pet {
    int64 id = 1;
    string name = 2;
    string tag = 3;
}

message Pets {
    repeated Pet pets = 1;
}

service SwaggerPetstoreService {
    // Returns all pets from the system that the user has access to
    rpc GetPets(GetPetsRequest) returns (Pets) {
      option (google.api.http) = {
        get: "/api/pets"
      };
    }
    // Creates a new pet in the store.  Duplicates are allowed
    rpc PostPets(PostPetsRequest) returns (Pet) {
      option (google.api.http) = {
        post: "/api/pets"
        body: "pet"
      };
    }
    // Returns a user based on a single ID, if the user does not have access to the pet
    rpc GetPetsId(GetPetsIdRequest) returns (Pet) {
      option (google.api.http) = {
        get: "/api/pets/{id}"
      };
    }
    // deletes a single pet based on the ID supplied
    rpc DeletePetsId(DeletePetsIdRequest) returns (google.protobuf.Empty) {
      option (google.api.http) = {
        delete: "/api/pets/{id}"
      };
    }
}

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func GenerateProto

func GenerateProto(api *APIDefinition, annotate bool) ([]byte, error)

GenerateProto will attempt to generate an protobuf version 3 schema from the given OpenAPI definition.

func OperationIDToName

func OperationIDToName(operationID string) string

func PathMethodToName

func PathMethodToName(path, method, operationID string) string

func ProtoEnum

func ProtoEnum(name string, enums []string, depth int) string

ProtoEnum will generate a protobuf v3 enum declaration from the given info.

Types

type APIDefinition

type APIDefinition struct {
	FileName string // internal use to pass file path
	Swagger  string `yaml:"swagger" json:"swagger"`
	Info     struct {
		Title       string `yaml:"title" json:"title"`
		Description string `yaml:"description" json:"description"`
		Version     string `yaml:"version" json:"version"`
	} `yaml:"info" json:"info"`
	Host          string            `yaml:"host" json:"host"`
	Schemes       []string          `yaml:"schemes" json:"schemes"`
	BasePath      string            `yaml:"basePath" json:"basePath"`
	Produces      []string          `yaml:"produces" json:"produces"`
	Paths         map[string]*Path  `yaml:"paths" json:"paths"`
	Definitions   map[string]*Items `yaml:"definitions" json:"definitions"`
	Parameters    map[string]*Items `yaml:"parameters" json:"parameters"`
	GlobalOptions GRPCOptions       `yaml:"x-global-options" json:"x-global-options"`
	Extensions    []*Extension      `yaml:"x-extensions" json:"x-extensions"`
}

APIDefinition is the base struct for containing OpenAPI spec declarations.

func LoadDefinition

func LoadDefinition(pth string) (*APIDefinition, error)

type Endpoint

type Endpoint struct {
	Summary     string               `yaml:"summary" json:"summary"`
	Description string               `yaml:"description" json:"description"`
	Parameters  Parameters           `yaml:"parameters" json:"parameters"`
	Tags        []string             `yaml:"tags" json:"tags"`
	Responses   map[string]*Response `yaml:"responses" json:"responses"`
	OperationID string               `yaml:"operationId" json:"operationId"`
	Options     GRPCOptions          `yaml:"x-options" json:"x-options"`
	// contains filtered or unexported fields
}

Endpoint represents an endpoint for a path in an OpenAPI spec.

type Extension

type Extension struct {
	Base   string            `json:"base" yaml:"base"`
	Fields []*ExtensionField `json:"fields" yaml:"fields"`
}

func (Extension) Protobuf

func (e Extension) Protobuf(indent string) string

type ExtensionField

type ExtensionField struct {
	Name   string `yaml:"name" json:"name"`
	Type   string `yaml:"type" json:"type"`
	Number string `yaml:"number" json:"number"`
}

type GRPCOptions

type GRPCOptions map[string]interface{}

type HTTPAnnotation

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

func NewHTTPAnnotation

func NewHTTPAnnotation(method, path, body string) *HTTPAnnotation

func (HTTPAnnotation) Protobuf

func (a HTTPAnnotation) Protobuf(indent string) string

type Items

type Items struct {
	Description string `yaml:"description,omitempty" json:"description,omitempty"`
	// scalar
	Type   interface{} `yaml:"type" json:"type"`
	Format interface{} `yaml:"format,omitempty" json:"format,omitempty"`
	Enum   []string    `yaml:"enum,omitempty" json:"enum,omitempty"`

	ProtoTag int `yaml:"x-proto-tag" json:"x-proto-tag"`

	// Map type
	AdditionalProperties interface{} `yaml:"additionalProperties" json:"additionalProperties"`

	// ref another Model
	Ref string `yaml:"$ref" json:"$ref"`

	// is an array
	Items *Items `yaml:"items" json:"items"`

	// for request parameters
	In     string `yaml:"in" json:"in"`
	Schema *Items `yaml:"schema" json:"schema"`

	// is an other Model
	Model `yaml:",inline"`

	// required items
	Required interface{} `yaml:"required,omitempty" json:"required,omitempty"`

	// validation (regex pattern, max/min length)
	Pattern   string `yaml:"pattern,omitempty" json:"pattern,omitempty"`
	MaxLength int    `yaml:"maxLength,omitempty" json:"max_length,omitempty"`
	MinLength int    `yaml:"minLength,omitempty" json:"min_length,omitempty"`
}

Items represent Model properties in an OpenAPI spec.

func (Items) Comment

func (i Items) Comment() string

func (Items) HasComment

func (i Items) HasComment() bool

func (*Items) ProtoMessage

func (i *Items) ProtoMessage(dst io.Writer, msgName, name string, defs map[string]*Items, indx *int, depth int)

ProtoMessage will generate a set of fields for a protobuf v3 schema given the current Items and information.

type Model

type Model struct {
	Properties map[string]*Items `yaml:"properties" json:"properties"`
	Name       string
	Depth      int
}

Model represents a model definition from an OpenAPI spec.

func (*Model) ProtoModel

func (m *Model) ProtoModel(dst io.Writer, name string, depth int, defs map[string]*Items)

ProtoModel will return a protobuf v3 message that represents the current Model.

type Parameters

type Parameters []*Items

Parameters is a slice of request parameters for a single endpoint.

func (Parameters) ProtoMessage

func (p Parameters) ProtoMessage(dst io.Writer, parent Parameters, endpointName string, defs map[string]*Items)

ProtoMessage will return a protobuf v3 message that represents the request Parameters.

type Path

type Path struct {
	Get        *Endpoint  `yaml:"get" json:"get"`
	Put        *Endpoint  `yaml:"put" json:"put"`
	Post       *Endpoint  `yaml:"post" json:"post"`
	Delete     *Endpoint  `yaml:"delete" json:"delete"`
	Parameters Parameters `yaml:"parameters" json:"parameters"`
}

Path represents all of the endpoints and parameters available for a single path.

func (*Path) ProtoEndpoints

func (p *Path) ProtoEndpoints(dst io.Writer, annotate bool, base, path string)

ProtoEndpoints will return any protobuf v3 endpoints for gRPC service declarations.

func (*Path) ProtoMessages

func (p *Path) ProtoMessages(dst io.Writer, path string, defs map[string]*Items)

ProtoMessages will return protobuf v3 messages that represents the request Parameters of the endpoints within this path declaration and any custom response messages not listed in the definitions.

type Response

type Response struct {
	Description string `yaml:"description" json:"description"`
	Schema      *Items `yaml:"schema" json:"schema"`
}

Response represents the response object in an OpenAPI spec.

func (*Response) ProtoMessage

func (r *Response) ProtoMessage(dst io.Writer, endpointName string, defs map[string]*Items)

ProtoMessage will return a protobuf message declaration based on the response schema. If the response is an array type, it will get wrapped in a generic message with a single 'items' field to contain the array.

Directories

Path Synopsis
cmd
openapi2proto command

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL