swaggering

package module
v0.1.0 Latest Latest
Warning

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

Go to latest
Published: May 14, 2019 License: MIT Imports: 18 Imported by: 13

README

Swaggering

Swagger 1.2 code generator

(For Swagger 2.0, please see https://github.com/go-swagger/go-swagger)

Swaggering is a library for generating code based on Swagger 1.2 JSON description files.

To use this library, you'll probably want to

go get github.com/opentable/swaggering/cmd/swagger-client-maker

Note

My experience has been that Swagger JSON descriptions can be flaky. Swaggering does its best to generate code anyway - when there are references to models that don't exist in the API Swaggering templates in struct fields but comments them out. I've found the best thing is to amend the JSON rather than the resulting code. For that, jq is an invaluable tool.

Building

Note that the default templates live in defaultApi.tmpl and defaultModel.tmpl - if you update those files, you need to run go generate to update templates.go.

Future Work

Maybe it'd be best to do all this with gofmt stuff instead of templates. c.f. https://github.com/sasha-s/go-inline for ideas.

Documentation

Index

Constants

This section is empty.

Variables

View Source
var Templates = mapfs.New(map[string]string{
	`codefile.tmpl`: "package {{.BasePackageName}}\n\nimport \"{{.PackageImportName}}/dtos\"\n\n{{range .Methods}}\n  {{- if .Valid -}}\n    {{template \"method\" .}}\n  {{- else -}}\n    // {{.Name}} is invalid\n  {{ end -}}\n{{end}}\n",
	`method.tmpl`:   "func (client *Client) {{.Name}}(\n{{- range .Params -}}\n{{.Name}} {{.TypeString \"\" -}}\n, {{end -}}\n) ({{ if .HasResult -}}\nresponse {{.ResultTypeString \"\" -}}\n, {{end}} err error) {\n	pathParamMap := map[string]interface{}{\n		{{range .Params -}}\n		{{if eq \"path\" .ParamType -}}\n		  \"{{.Name}}\": {{.Name}},\n	  {{- end }}\n		{{- end }}\n	}\n\n  queryParamMap := map[string]interface{}{\n		{{range .Params -}}\n		{{if eq \"query\" .ParamType -}}\n		  \"{{.Name}}\": {{.Name}},\n	  {{- end }}\n		{{- end }}\n	}\n\n	{{if .DTORequest -}}\n	{{if .MakesResult}}\n    response = make({{.BaseResultTypeString \"\"}}, 0)\n		err = client.DTORequest(\"{{.ResourceName}}\", &response, \"{{.Method}}\", \"{{.Path}}\", pathParamMap, queryParamMap\n		{{- if .HasBody -}}\n		, body\n		{{- end -}})\n	{{else}}\n    response = new({{.BaseResultTypeString \"\"}})\n		err = client.DTORequest(\"{{.ResourceName}}\", response, \"{{.Method}}\", \"{{.Path}}\", pathParamMap, queryParamMap\n		{{- if .HasBody -}}\n		, body\n		{{- end -}})\n	{{end}}\n	{{else if not .HasResult}}\n	_, err = client.Request(\"{{.ResourceName}}\", \"{{.Method}}\", \"{{.Path}}\", pathParamMap, queryParamMap\n	{{- if .HasBody -}}\n	, body\n  {{- end -}})\n	{{else if eq (.ResultTypeString \"\") \"string\"}}\n	resBody, err := client.Request(\"{{.ResourceName}}\", \"{{.Method}}\", \"{{.Path}}\", pathParamMap, queryParamMap\n	{{- if .HasBody -}}\n	, body\n  {{- end -}})\n	readBuf := bytes.Buffer{}\n	readBuf.ReadFrom(resBody)\n	response = string(readBuf.Bytes())\n	{{- end}}\n	return\n}\n",
	`struct.tmpl`:   "package dtos\n\nimport (\n  \"fmt\"\n  \"io\"\n\n  \"github.com/opentable/swaggering\"\n)\n\n{{range $enum := .Enums}}\ntype {{$enum.TypeString \"dtos\"}} string\n\nconst (\n  {{- range $value := $enum.Values}}\n  {{$enum.TypeString \"dtos\"}}{{$value}} {{$enum.TypeString \"dtos\"}} = \"{{$value}}\"\n  {{- end}}\n)\n{{end}}\n\ntype {{.Name}} struct {\n{{range $name, $prop := .Fields}}\n  {{- if not $prop.Valid}}// Invalid field: {{end -}}\n  {{$prop.Name}} {{if $prop.IsConcrete}}*{{end}}{{$prop.TypeString \"dtos\"}} `json:\"{{$prop.SwaggerName}},omitempty\"`\n{{end}}\n}\n\nfunc (self *{{.Name}}) Populate(jsonReader io.ReadCloser) (err error) {\n	return swaggering.ReadPopulate(jsonReader, self)\n}\n\nfunc (self *{{.Name}}) Absorb(other swaggering.DTO) error {\n  if like, ok := other.(*{{.Name}}); ok {\n    *self = *like\n    return nil\n  }\n  return fmt.Errorf(\"A {{.Name}} cannot copy the values from %#v\", other)\n}\n\nfunc (self *{{.Name}}) FormatText() string {\n	return swaggering.FormatText(self)\n}\n\nfunc (self *{{.Name}}) FormatJSON() string {\n	return swaggering.FormatJSON(self)\n}\n\nfunc (self *{{.Name}}) SetField(name string, value interface{}) error {\n  switch name {\n  default:\n    return fmt.Errorf(\"No such field %s on {{.Name}}\", name)\n  {{range $name, $prop := .Fields}}\n    {{ if $prop.Valid }}\n    case \"{{$prop.SwaggerName}}\", \"{{$prop.Name}}\":\n    v, ok := value.(\n      {{- $prop.TypeString \"dtos\" -}}\n      )\n      if ok {\n        self.{{$prop.Name}} = {{if $prop.IsConcrete}}&{{end}}v\n        return nil\n      }\n      return fmt.Errorf(\"Field {{$prop.SwaggerName}}/{{$prop.Name}}: value %v(%T) couldn't be cast to type {{$prop.TypeString \"dtos\"}}\", value, value)\n    {{end}}\n  {{end}}\n  }\n}\n\nfunc (self *{{.Name}}) GetField(name string) (interface{}, error) {\n  switch name {\n  default:\n    return nil, fmt.Errorf(\"No such field %s on {{.Name}}\", name)\n  {{range $name, $prop := .Fields}}\n    {{ if $prop.Valid }}\n    case \"{{$prop.SwaggerName}}\", \"{{$prop.Name}}\":\n    return {{if $prop.IsConcrete}}*{{end}}self.{{$prop.Name}}, nil\n    return nil, fmt.Errorf(\"Field {{$prop.Name}} no set on {{.Name}} %+v\", self)\n    {{end}}\n  {{end}}\n  }\n}\n\nfunc (self *{{.Name}}) ClearField(name string) error {\n  switch name {\n  default:\n    return fmt.Errorf(\"No such field %s on {{.Name}}\", name)\n  {{range $name, $prop := .Fields}}\n    {{ if $prop.Valid }}\n  case \"{{$prop.SwaggerName}}\", \"{{$prop.Name}}\":\n    self.{{$prop.Name}} = nil\n    {{end}}\n  {{end}}\n  }\n\n  return nil\n}\n\nfunc (self *{{.Name}}) LoadMap(from map[string]interface{}) error {\n  return swaggering.LoadMapIntoDTO(from, self)\n}\n\ntype {{.Name}}List []*{{.Name}}\n\nfunc (self *{{.Name}}List) Absorb(other swaggering.DTO) error {\n  if like, ok := other.(*{{.Name}}List); ok {\n    *self = *like\n    return nil\n  }\n  return fmt.Errorf(\"A {{.Name}}List cannot copy the values from %#v\", other)\n}\n\n\nfunc (list *{{.Name}}List) Populate(jsonReader io.ReadCloser) (err error) {\n	return swaggering.ReadPopulate(jsonReader, list)\n}\n\nfunc (list *{{.Name}}List) FormatText() string {\n	text := []byte{}\n	for _, dto := range *list {\n		text = append(text, (*dto).FormatText()...)\n		text = append(text, \"\\n\"...)\n	}\n	return string(text)\n}\n\nfunc (list *{{.Name}}List) FormatJSON() string {\n	return swaggering.FormatJSON(list)\n}\n",
})

Functions

func FormatJSON

func FormatJSON(dto interface{}) string

FormatJSON formats a dto as JSON

func FormatText

func FormatText(dto interface{}) string

FormatText formats a DTO

func InferPackage

func InferPackage(dirName string) (packageName string, err error)

func LoadMapIntoDTO

func LoadMapIntoDTO(from map[string]interface{}, dto Fielder) error

LoadMapIntoDTO loads a map of key/values into a DTO, setting their presence as they're loaded

func NewChannelDummy

func NewChannelDummy() (DummyClient, DummyControl)

NewChannelDummy returns a pair of a DummyClient and a DummyControl. Responses fed to DummyControl will be returned by the DummyClient

func Process

func Process(importName, packageName, serviceSource, renderTarget string)

func ProcessService

func ProcessService(dir string, ingester *Context)

func ReadPopulate

func ReadPopulate(jsonReader io.ReadCloser, target interface{}) error

ReadPopulate reads from jsonReader in order to fill in target

func RenderService

func RenderService(target string, ingester *Context)

RenderService performs the rendering of a service

func ResolveService

func ResolveService(context *Context)

Types

type Api

type Api struct {
	Path, Description string
	Operations        []*Operation
}

Api is the struct that is deserialized from api_*.json files.

type Attribute

type Attribute struct {
	*Field

	SwaggerName string
}

An Attribute is a field in a Swagger Struct, which includes information about JSON serialization.

func (*Attribute) Omittable

func (attr *Attribute) Omittable() bool

type CodeFile

type CodeFile struct {
	Name              string
	BasePackageName   string
	PackageImportName string
	Methods           []*Method
}

CodeFile describes a go code file, which will contain methods

type Collection

type Collection struct {
	SwaggerType
	Items       SwaggerType
	UniqueItems bool
}

Collection represents a list-type from swagger

type Context

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

func NewContext

func NewContext(packageName, importName string) (context *Context)

func (*Context) IngestApi

func (ctx *Context) IngestApi(name, aspath string, data io.Reader)

func (*Context) ProcessServiceDir

func (ingester *Context) ProcessServiceDir(dir string)

func (*Context) Resolve

func (context *Context) Resolve()

type DTO

type DTO interface {
	Populate(io.ReadCloser) error
	Absorb(DTO) error
	FormatText() string
	FormatJSON() string
}

DTO is an interface for a generic data transfer object.

type DummyClient

type DummyClient struct {
	NextDTO    func(method, path string, pathParams, queryParams UrlParams, body ...DTO) (DTO, error)
	NextSimple func(method, path string, pathParams, queryParams UrlParams, body ...DTO) (string, error)
}

DummyClient stands in for the generic part of a swaggering client for testing

func (*DummyClient) DTORequest

func (dc *DummyClient) DTORequest(rn string, pop DTO, m, p string, pp, qp UrlParams, b ...DTO) error

DTORequest performs an HTTP request and populates a DTO based on the response

func (*DummyClient) Request

func (dc *DummyClient) Request(rn, m, p string, pp, qp UrlParams, b ...DTO) (io.ReadCloser, error)

Request performs an HTTP request and returns the body of the response

type DummyControl

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

DummyControl is a tool for controlling a particular kind of DummyClient

func (DummyControl) FeedDTO

func (c DummyControl) FeedDTO(dto DTO, err error)

FeedDTO pushes a DTO (and an error) into the queue for the paired DummyClient to return

func (DummyControl) FeedSimple

func (c DummyControl) FeedSimple(body string, err error)

FeedSimple pushes a body string (and an error) into the queue for the paired DummyClient to return

type Enum

type Enum struct {
	Name   string
	Values []string
}

Enum is a deserialization target for Swagger JSON files.

type EnumType

type EnumType struct {
	Name      string
	Values    []string
	HostModel string
	// contains filtered or unexported fields
}

EnumType is an enum type.

func (EnumType) IsConcrete added in v0.1.0

func (EnumType) IsConcrete() bool

func (*EnumType) TypeString

func (t *EnumType) TypeString(pkg string) string

TypeString implements TypeStringer on PrimitiveType.

func (EnumType) Valid

func (EnumType) Valid() bool

type Field

type Field struct {
	Name string
	TypeStringer
}

Field describes a Go field that will be build from a swagger API.

type Fielder

type Fielder interface {
	GetField(string) (interface{}, error)
	SetField(string, interface{}) error
	ClearField(string) error
	LoadMap(map[string]interface{}) error
}

Fielder is an interface for an object with optional fields This is the most surprising aspect of swaggering, but obvious on reflection. JSON interfaces often treat the _absence_ of a field as very different from its presence, regardless of the value of the field. { name: "Judson" } is semantically different from { name: "Judson", job: undefined }. It's important to distinguish absence from zero, therefore.

func LoadMap

func LoadMap(dto Fielder, from map[string]interface{}) (Fielder, error)

LoadMap loads a map of values into a Fielder

type GenericClient

type GenericClient struct {
	BaseURL string
	Logger  LogSink
	HTTP    http.Client
}

GenericClient is a generic client for Swagger described services

func (*GenericClient) DTORequest

func (gc *GenericClient) DTORequest(resourceName string, pop DTO, method, path string, pathParams, queryParams UrlParams, body ...DTO) (err error)

DTORequest performs an HTTP request and populates a DTO based on the response

func (*GenericClient) Request

func (gc *GenericClient) Request(resourceName, method, path string, pathParams, queryParams UrlParams, body ...DTO) (resBody io.ReadCloser, err error)

Request performs an HTTP request and returns the body of the response

type LogSink added in v0.0.2

type LogSink func(map[string]interface{})

LogSink is a function to integrate the GenericClient with whatever logging platform.

type Logger

type Logger interface {
	Info(msg string, data ...interface{})
	Debug(msg string, data ...interface{})
	Logging() bool
	Debugging() bool
}

Logger is the interface that swaggering's clients expect to log to

type MapType

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

MapType is an map[] type.

func (MapType) IsConcrete added in v0.1.0

func (MapType) IsConcrete() bool

func (*MapType) TypeString

func (t *MapType) TypeString(pkg string) string

TypeString implements TypeStringer on MapType.

func (MapType) Valid

func (MapType) Valid() bool

type Method

type Method struct {
	Name                string
	Params              []*Param
	Results             []*Field
	Method, Path        string
	HasBody, DTORequest bool
	// contains filtered or unexported fields
}

Method describes the Go method that will be build from a swagger API.

func (*Method) BaseResultTypeString

func (method *Method) BaseResultTypeString(pkg string) string

func (*Method) HasResult

func (method *Method) HasResult() bool

HasResult indicates that the Method wraps an API call that produces a result value.

func (*Method) MakesResult

func (method *Method) MakesResult() bool

MakesResult indicates that the result value for this operation should be allocated in Go using make() as opposed to new()

func (Method) ResourceName

func (method Method) ResourceName() string

func (*Method) ResultTypeString

func (method *Method) ResultTypeString(pkg string) string

ResultTypeString is a shortcut for returning the typestring of a result value.

func (Method) Valid

func (v Method) Valid() bool

type Model

type Model struct {
	Id, Description, Discriminator string
	GoPackage, GoName              string
	Required, SubTypes             []string
	Properties                     map[string]*Property
	Enums                          []Enum
	// contains filtered or unexported fields
}

Model represents a Swagger model

type NullLogger

type NullLogger struct{}

NullLogger simply swallows logging

func (NullLogger) Debug

func (nl NullLogger) Debug(m string, d ...interface{})

Debug implements Logger

func (NullLogger) Debugging

func (nl NullLogger) Debugging() bool

Debugging implements Logger

func (NullLogger) Info

func (nl NullLogger) Info(m string, d ...interface{})

Info implements Logger

func (NullLogger) Logging

func (nl NullLogger) Logging() bool

Logging implements Logger

type Operation

type Operation struct {
	Collection

	Nickname, Method, Path, Deprecated string
	HasBody, DTORequest                bool
	Parameters                         []*Parameter
	ResponseMessages                   []*ResponseMessage
}

Operation represents an operation on an API in swagger

type Param

type Param struct {
	*Field

	ParamType string
}

Param describes a parameter to a method.

type Parameter

type Parameter struct {
	Collection
	ParamType, Name         string
	Required, AllowMultiple bool
}

Parameter is a deserialization target for Swagger JSON files.

type Pointer

type Pointer struct {
	TypeStringer
}

Pointer describes a pointer.

func (*Pointer) IsConcrete added in v0.1.0

func (t *Pointer) IsConcrete() bool

IsConcrete implements TypeStringer on Pointer.

func (*Pointer) TypeString

func (t *Pointer) TypeString(pkg string) string

TypeString implements TypeStringer on Pointer.

type PrimitiveType

type PrimitiveType struct {
	Name string
	// contains filtered or unexported fields
}

PrimitiveType is a primitive type.

func (PrimitiveType) IsConcrete added in v0.1.0

func (PrimitiveType) IsConcrete() bool

func (*PrimitiveType) TypeString

func (t *PrimitiveType) TypeString(pkg string) string

TypeString implements TypeStringer on PrimitiveType.

func (PrimitiveType) Valid

func (PrimitiveType) Valid() bool

type Property

type Property struct {
	Collection
}

Property represents a field in a swagger model

type Renderer

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

Renderer is responsible for actually turning the parsed API into go code

func NewRenderer

func NewRenderer(tgt string) *Renderer

NewRenderer creates a new renderer

type ReqError

type ReqError struct {
	Method, Path string
	Message      string
	Status       int
	Body         bytes.Buffer
}

ReqError represents failures from requests

func (*ReqError) Error

func (e *ReqError) Error() string

type Requester

type Requester interface {
	// DTORequest performs an HTTP request and populates a DTO based on the response
	DTORequest(resourceName string, dto DTO, method, path string, pathParams, queryParams UrlParams, body ...DTO) error

	// Request performs an HTTP request and returns the body of the response
	Request(resourceName string, method string, path string, pathParams UrlParams, queryParams UrlParams, body ...DTO) (io.ReadCloser, error)
}

Requester defines the interface that Swaggering uses to make actual HTTP requests of the API server

type ResponseMessage

type ResponseMessage struct {
	Code                   int
	Message, ResponseModel string
	// contains filtered or unexported fields
}

ResponseMessage is a deserialization target for Swagger JSON files.

type ServiceApiJSON

type ServiceApiJSON struct {
	Path, Desc string
}

type ServiceJSON

type ServiceJSON struct {
	Apis []*ServiceApiJSON
}

type SliceType

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

SliceType is a []slice type.

func (SliceType) IsConcrete added in v0.1.0

func (SliceType) IsConcrete() bool

func (*SliceType) TypeString

func (t *SliceType) TypeString(pkg string) string

TypeString implements TypeStringer on SliceType.

func (SliceType) Valid

func (SliceType) Valid() bool

type StarvedChannelError

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

StarvedChannelError means that a channel needed a value but didn't have one

func (*StarvedChannelError) Error

func (e *StarvedChannelError) Error() string

type StdlibDebugLogger

type StdlibDebugLogger struct{}

StdlibDebugLogger just sends its arguments to the global logger

func (StdlibDebugLogger) Debug

func (dl StdlibDebugLogger) Debug(m string, d ...interface{})

Debug implements Logger

func (StdlibDebugLogger) Debugging

func (dl StdlibDebugLogger) Debugging() bool

Debugging implements Logger

func (StdlibDebugLogger) Info

func (dl StdlibDebugLogger) Info(m string, d ...interface{})

Info implements Logger

func (StdlibDebugLogger) Logging

func (dl StdlibDebugLogger) Logging() bool

Logging implements Logger

type StringList

type StringList []string

StringList - it's a list, now with 100% more string This type is used in generated DTOs to encode lists of strings.

func (*StringList) Absorb

func (list *StringList) Absorb(other DTO) error

Absorb implements DTO for StringList

func (*StringList) FormatJSON

func (list *StringList) FormatJSON() string

FormatJSON formats a StringList to JSON

func (*StringList) FormatText

func (list *StringList) FormatText() string

FormatText formats a StringList as text

func (*StringList) Populate

func (list *StringList) Populate(jsonReader io.ReadCloser) (err error)

Populate loads a StringList from json

type Struct

type Struct struct {
	Package, Name string
	Fields        []*Attribute
	Enums         []*EnumType
	// contains filtered or unexported fields
}

Struct describes a Go struct that will be build from a swagger API.

func (Struct) IsConcrete added in v0.1.0

func (Struct) IsConcrete() bool

func (*Struct) TypeString

func (t *Struct) TypeString(pkg string) string

TypeString implements TypeStringer on Struct.

func (Struct) Valid

func (v Struct) Valid() bool

type Swagger

type Swagger struct {
	BasePath, ResourcePath string
	Apis                   []Api
	Models                 map[string]*Model
	// contains filtered or unexported fields
}

Swagger is the top level deserialization target for swagger.

type SwaggerType

type SwaggerType struct {
	Type, Format string
	Ref          string `json:"$ref"`
	Enum         []string
}

SwaggerType represents an abstract datatype as described by swagger.

type TypeStringer

type TypeStringer interface {
	TypeString(pkg string) string
	Valid() bool
	IsConcrete() bool
}

A TypeStringer implements TypeString, which returns the string that describes a go type.

type UrlParams

type UrlParams map[string]interface{}

UrlParams are key-value pairs to URL encoded into the request

Directories

Path Synopsis
cmd

Jump to

Keyboard shortcuts

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