Documentation ¶
Overview ¶
Package dispel implements code generation of server code for REST APIs written in Go. The generated code is based on the JSON Hyper Schema describing the API.
Its primary use is through go:generate, but it's also possible to invoke the dispel command directly, or use this package in your code.
JSON Schema ¶
Usage of this package usually begins with parsing a JSON Schema and the routes it contains:
var schema dispel.Schema err := json.NewDecoder(reader).Decode(&schema) // ... schemaParser := &dispel.SchemaParser{RootSchema: &schema} routes, err := schemaParser.ParseRoutes() // ...
Then you want to generate code using these routes. Dispel provides several builtin templates which provide code generation for registering API routes and API handlers, generating input and output types for the data structures of these routes, and default implementations of API handlers.
Templates ¶
The TemplateBundle type is a bundle of all these templates; all templates for generating this code use the same template context:
tmpl, err := dispel.NewTemplateBundle(schemaParser) // ... ctx := &dispel.TemplateContext{ Prgm: "dispel", PkgName: "main", Routes: routes, HandlerReceiverType: "*App", } err := tmpl.ExecuteTemplate(os.Stdout, dispel.TemplateRoutes, ctx)) // ...
Dispel tries to be as unopiniated as possible for the generated code API. Most of the generated code makes use of interfaces to let the developer implement them as he needs. However, it's possible to generate default implementations of these interfaces to quickly have code that compiles.
This is done with DefaultImplBundle type, which works similarly to the TemplateBundle.
tmpl, err := dispel.NewDefaultImplBundle() // ... pkgName := "main" err := tmpl.ExecuteTemplate(os.Stdout, dispel.DefaultImplMux, pkgName)) // ...
For a more detailed usage of this package, take a look at integration_test.go and cmd/dispel source.
Index ¶
- Constants
- func FindTypes(path string, pkgName string, excludeFiles []string) (map[string]*ast.TypeSpec, error)
- func FindTypesFuncs(path string, pkgName string, typeNames []string, excludeFiles []string) (map[string]*ast.FuncDecl, error)
- type Bundle
- type Context
- type DefaultImplBundle
- type Generator
- type InvalidSchemaError
- type InvalidSchemaRefError
- type JSONArray
- type JSONBoolean
- type JSONDateTime
- type JSONField
- type JSONFieldList
- type JSONInteger
- type JSONNull
- type JSONNumber
- type JSONObject
- type JSONString
- type JSONType
- type JSONTypeNamer
- type Link
- type MethodRouteIOMap
- type Methods
- type NamedGenerator
- type ResourceRoute
- type ResourceRoutes
- type Route
- type RouteAndIOTypeNames
- type RouteIO
- type RouteIOAndLink
- type RouteParam
- type Routes
- type RoutesAndIOTypeNames
- type Schema
- type SchemaParser
- func (sp *SchemaParser) JSONToGoType(jt JSONType, globalScope bool) string
- func (sp *SchemaParser) JSONTypeFromSchema(defaultName string, schema *Schema, ref string) (jt JSONType, err error)
- func (sp *SchemaParser) ParseRoutes() (Routes, error)
- func (sp *SchemaParser) ResolveSchema(schema *Schema) (*Schema, error)
- func (sp *SchemaParser) ResolveSchemaRef(schemaRef string, relSchema *Schema) (*Schema, error)
- func (sp *SchemaParser) ResolveType(jt JSONType) JSONType
- func (sp *SchemaParser) RouteParamsFromLink(link *Link, schema *Schema) ([]RouteParam, error)
- type Template
- func (t *Template) AllHandlerFuncsImplemented() bool
- func (t *Template) Generate(w io.Writer, ctx *Context) error
- func (t *Template) HandlerFuncName(routeMethod string, routeName string) string
- func (t *Template) Name() string
- func (t *Template) PrintSmartDerefType(j JSONType) string
- func (t *Template) PrintTypeDef(j JSONType) string
- func (t *Template) RoutesForType(j JSONType) []RouteAndIOTypeNames
- func (t *Template) TypeImports() []string
- func (t *Template) TypeNeedsAddr(j JSONType) bool
- func (t *Template) Varname(s string) string
- type TypeNamer
- type TypeRedefinitionError
Constants ¶
const ( DefaultImplMethodHandler = "methodhandler" DefaultImplMethodHandlerTest = "methodhandler_test" DefaultImplMux = "defaults_mux" DefaultImplCodec = "defaults_codec" )
The default implementations available in a DefaultImplBundle.
const Version = 6
Version represents the version of the API generated by dispel. Any visible change makes this version bump by 1.
Variables ¶
This section is empty.
Functions ¶
Types ¶
type Bundle ¶
type Bundle struct { Routes NamedGenerator Handlers NamedGenerator Handlerfuncs NamedGenerator Types NamedGenerator }
Bundle represents the group of the 4 dispel generators producing the server code.
func NewBundle ¶
func NewBundle(sp *SchemaParser) (*Bundle, error)
NewBundle returns a Bundle for the SchemaParser.
type Context ¶
type Context struct { Schema *SchemaParser // the SchemaParser which parsed the json schema Prgm string // name of the program generating the source PkgName string // package name for which source code is generated Routes Routes // routes parsed by the SchemaParser HandlerReceiverType string // type which acts as the receiver of the handler funcs. ExistingHandlers []string // list of existing handler funcs in the target package, with HandlerReceiverType as the receiver ExistingTypes []string // list of existing types in the target package. }
Context represents the context passed to a Generator.
type DefaultImplBundle ¶
type DefaultImplBundle struct {
// contains filtered or unexported fields
}
DefaultImplBundle represents a bundle of source files providing default implementations for dispel's interfaces.
func NewDefaultImplBundle ¶
func NewDefaultImplBundle() (*DefaultImplBundle, error)
NewDefaultImplBundle returns a new DefaultImplBundle bundle.
func (*DefaultImplBundle) ExecuteTemplate ¶
func (d *DefaultImplBundle) ExecuteTemplate(wr io.Writer, name string, prgm string, pkgName string) error
ExecuteTemplate writes the source file named by name to the writer wr.
The name must be one of those returned by DefaultImpl.Names(). prgm is printed in the header for warning about editing a generated file. It sets the package of the generated source file to pkgName.
func (*DefaultImplBundle) Names ¶
func (d *DefaultImplBundle) Names() []string
Names returns the list of available default implementations.
type InvalidSchemaError ¶
InvalidSchemaError represents an error which happens when parsing a (sub)schema fails.
func (InvalidSchemaError) Error ¶
func (e InvalidSchemaError) Error() string
type InvalidSchemaRefError ¶
InvalidSchemaRefError represents an error which happens when an invalid $ref is found in a JSON Schema. Typically, it's a $ref which is unsupported or can't be dereferenced.
func (InvalidSchemaRefError) Error ¶
func (e InvalidSchemaRefError) Error() string
type JSONArray ¶
JSONArray represents the array primitive type of the JSON format.
type JSONBoolean ¶
type JSONBoolean struct {
// contains filtered or unexported fields
}
JSONBoolean represents the boolean primitive type of the JSON format.
func (JSONBoolean) Ref ¶
func (b JSONBoolean) Ref() string
Ref implements Ref() of the JSONType interface.
func (JSONBoolean) Type ¶
func (b JSONBoolean) Type() string
Type implements Type() of the JSONType interface.
type JSONDateTime ¶
type JSONDateTime struct {
// contains filtered or unexported fields
}
JSONDateTime represents the string primitive type of the JSON format. Its underlying time is a RFC3339 date time.
func (JSONDateTime) Ref ¶
func (dt JSONDateTime) Ref() string
Ref implements Ref() of the JSONType interface.
func (JSONDateTime) Type ¶
func (dt JSONDateTime) Type() string
Type implements Type() of the JSONType interface.
type JSONFieldList ¶
type JSONFieldList []JSONField
JSONFieldList implements alphabetical sorting of a JSONObject property list.
func (JSONFieldList) Len ¶
func (fl JSONFieldList) Len() int
func (JSONFieldList) Less ¶
func (fl JSONFieldList) Less(i, j int) bool
func (JSONFieldList) Swap ¶
func (fl JSONFieldList) Swap(i, j int)
type JSONInteger ¶
type JSONInteger struct {
// contains filtered or unexported fields
}
JSONInteger represents the integer primitive type of the JSON format.
func (JSONInteger) Ref ¶
func (i JSONInteger) Ref() string
Ref implements Ref() of the JSONType interface.
func (JSONInteger) Type ¶
func (i JSONInteger) Type() string
Type implements Type() of the JSONType interface.
type JSONNull ¶
type JSONNull struct {
// contains filtered or unexported fields
}
JSONNull represents the null primitive type of the JSON format.
type JSONNumber ¶
type JSONNumber struct {
// contains filtered or unexported fields
}
JSONNumber represents the number primitive type of the JSON format.
func (JSONNumber) Ref ¶
func (n JSONNumber) Ref() string
Ref implements Ref() of the JSONType interface.
func (JSONNumber) Type ¶
func (n JSONNumber) Type() string
Type implements Type() of the JSONType interface.
type JSONObject ¶
type JSONObject struct { Name string Fields JSONFieldList // contains filtered or unexported fields }
JSONObject represents the object primitive type of the JSON format.
func (JSONObject) Ref ¶
func (o JSONObject) Ref() string
Ref implements Ref() of the JSONType interface.
func (JSONObject) Type ¶
func (o JSONObject) Type() string
Type implements Type() of the JSONType interface.
func (JSONObject) TypeName ¶
func (o JSONObject) TypeName() string
TypeName implements the TypeNamer interface.
type JSONString ¶
type JSONString struct {
// contains filtered or unexported fields
}
JSONString represents the string primitive type of the JSON format.
func (JSONString) Ref ¶
func (s JSONString) Ref() string
Ref implements Ref() of the JSONType interface.
func (JSONString) Type ¶
func (s JSONString) Type() string
Type implements Type() of the JSONType interface.
type JSONType ¶
type JSONType interface { // Type returns a string representation of this type. Type() string // Ref returns the absolute reference of type as found in the JSON Schema which defined it. Ref() string }
JSONType is the interface implemented by objects that represents a JSON type defined in a JSON Schema.
type JSONTypeNamer ¶
JSONTypeNamer combines the TypeNamer and JSONType interfaces.
type Link ¶
type Link struct { Title string `json:"title,omitempty"` Description string `json:"description,omitempty"` HRef string `json:"href,omitempty"` Rel string `json:"rel,omitempty"` Method string `json:"method,omitempty"` Schema *Schema `json:"schema,omitempty"` TargetSchema *Schema `json:"targetSchema,omitempty"` EncType string `json:"encType,omitempty"` MediaType string `json:"mediaType,omitempty"` }
Link represents a Link description.
func (*Link) ApplyDefaults ¶
func (l *Link) ApplyDefaults()
ApplyDefaults applies default values to the Link's fields.
func (Link) ReceivesJSON ¶
ReceivesJSON returns true if the EncType of the Link is recognized as json.
type MethodRouteIOMap ¶
type MethodRouteIOMap map[string]RouteIOAndLink
MethodRouteIOMap maps a method to a RouteIOAndLink.
type NamedGenerator ¶
NamedGenerator represents a Generator with a name.
type ResourceRoute ¶
type ResourceRoute struct { Path string Name string RouteParams []RouteParam MethodRouteIOMap MethodRouteIOMap }
ResourceRoute represents a set of routes related to a resource, in the scope of a RESTful design.
func (*ResourceRoute) Methods ¶
func (resourceRoutes *ResourceRoute) Methods() Methods
Methods lists the available HTTP methods on the resource.
type ResourceRoutes ¶
type ResourceRoutes []ResourceRoute
ResourceRoutes is a list of resource routes.
func (ResourceRoutes) Len ¶
func (r ResourceRoutes) Len() int
func (ResourceRoutes) Less ¶
func (r ResourceRoutes) Less(i, j int) bool
func (ResourceRoutes) Swap ¶
func (r ResourceRoutes) Swap(i, j int)
type Route ¶
type Route struct { Path string Name string RouteParams []RouteParam Method string Link Link RouteIO }
Route represents an HTTP endpoint for a resource, with JSON on the wire.
type RouteAndIOTypeNames ¶
RouteAndIOTypeNames represents a Route with the names of the types on its input and output.
type RouteIO ¶
type RouteIO struct { InputIsNotJSON bool OutputIsNotJSON bool // InType is the JSON type coming in. InType JSONType // OutType is the JSON type coming out. OutType JSONType }
RouteIO represents JSON types for input and output.
type RouteIOAndLink ¶
RouteIOAndLink combines a RouteIO and a Link.
type RouteParam ¶
RouteParam represents a variable chunk in an HTTP endpoint path.
type Routes ¶
type Routes []Route
Routes represents a list of Routes.
func (Routes) ByResource ¶
func (routes Routes) ByResource() ResourceRoutes
ByResource map-reduces Routes to a ResourceRoutes.
func (Routes) JSONNamedTypes ¶
func (routes Routes) JSONNamedTypes() []JSONTypeNamer
JSONNamedTypes returns a list of all unique types found in the Routes.
type RoutesAndIOTypeNames ¶
type RoutesAndIOTypeNames []RouteAndIOTypeNames
RoutesAndIOTypeNames is defined for sorting RouteIOAndTypeNames by method and path.
func (RoutesAndIOTypeNames) Len ¶
func (routes RoutesAndIOTypeNames) Len() int
func (RoutesAndIOTypeNames) Less ¶
func (routes RoutesAndIOTypeNames) Less(i, j int) bool
func (RoutesAndIOTypeNames) Swap ¶
func (routes RoutesAndIOTypeNames) Swap(i, j int)
type Schema ¶
type Schema struct { ID string `json:"id,omitempty"` Title string `json:"title,omitempty"` Description string `json:"description,omitempty"` Version string `json:"version,omitempty"` Default interface{} `json:"default,omitempty"` ReadOnly bool `json:"readOnly,omitempty"` // unsupported Example interface{} `json:"example,omitempty"` Format string `json:"format,omitempty"` // unsupported Type string `json:"type,omitempty"` Ref string `json:"$ref,omitempty"` Schema string `json:"$schema,omitempty"` // unsupported Definitions map[string]*Schema `json:"definitions,omitempty"` MultipleOf float64 `json:"multipleOf,omitempty"` // unsupported Maximum float64 `json:"maximum,omitempty"` // unsupported ExclusiveMaximum bool `json:"exclusiveMaximum,omitempty"` // unsupported Minimum float64 `json:"minimum,omitempty"` // unsupported ExclusiveMinimum bool `json:"exclusiveMinimum,omitempty"` // unsupported MinLength int `json:"minLength,omitempty"` // unsupported MaxLength int `json:"maxLength,omitempty"` // unsupported Pattern string `json:"pattern,omitempty"` // unsupported MinProperties int `json:"minProperties,omitempty"` // unsupported MaxProperties int `json:"maxProperties,omitempty"` // unsupported Required []string `json:"required,omitempty"` // unsupported Properties map[string]*Schema `json:"properties,omitempty"` Dependencies map[string]interface{} `json:"dependencies,omitempty"` // unsupported AdditionalProperties interface{} `json:"additionalProperties,omitempty"` // unsupported PatternProperties map[string]*Schema `json:"patternProperties,omitempty"` // unsupported Items *Schema `json:"items,omitempty"` MinItems int `json:"minItems,omitempty"` // unsupported MaxItems int `json:"maxItems,omitempty"` // unsupported UniqueItems bool `json:"uniqueItems,omitempty"` // unsupported AdditionalItems interface{} `json:"additionalItems,omitempty"` // unsupported Enum []string `json:"enum,omitempty"` // unsupported OneOf []Schema `json:"oneOf,omitempty"` // unsupported AnyOf []Schema `json:"anyOf,omitempty"` // unsupported AllOf []Schema `json:"allOf,omitempty"` // unsupported Not *Schema `json:"not,omitempty"` // unsupported Links []Link `json:"links,omitempty"` }
Schema represents a JSON Hyper Schema.
type SchemaParser ¶
type SchemaParser struct { RootSchema *Schema Log *log.Logger // contains filtered or unexported fields }
SchemaParser provides a parser for a Schema instance.
It allows to parse its routes and data structures.
func (*SchemaParser) JSONToGoType ¶
func (sp *SchemaParser) JSONToGoType(jt JSONType, globalScope bool) string
JSONToGoType prints Go source code for the JSONType. globalScope tells whether we are in the package scope of the go source file, or inside a type.
func (*SchemaParser) JSONTypeFromSchema ¶
func (sp *SchemaParser) JSONTypeFromSchema(defaultName string, schema *Schema, ref string) (jt JSONType, err error)
JSONTypeFromSchema parses a JSON Schema and returns a value satisfying the jsonType interface. The name parameter, if not empty, is used to give a name to a json object.
func (*SchemaParser) ParseRoutes ¶
func (sp *SchemaParser) ParseRoutes() (Routes, error)
ParseRoutes parses the Schema and returns a list of Route instances.
Various errors may be returned, among them InvalidSchemaError and *TypeRedefinitionError.
func (*SchemaParser) ResolveSchema ¶
func (sp *SchemaParser) ResolveSchema(schema *Schema) (*Schema, error)
ResolveSchema takes a schema and recursively follows its $ref, if any. An error is returned if it fails to resolve a ref along the way.
func (*SchemaParser) ResolveSchemaRef ¶
func (sp *SchemaParser) ResolveSchemaRef(schemaRef string, relSchema *Schema) (*Schema, error)
ResolveSchemaRef takes a $ref string and returns the pointed schema.
The ref, if relative, is resolved against the relSchema schema. The ref is dereferenced only once. An error is returned if the ref or it doesn't point to a schema.
func (*SchemaParser) ResolveType ¶
func (sp *SchemaParser) ResolveType(jt JSONType) JSONType
ResolveType resolves the JSONType by following its Ref backwards.
func (*SchemaParser) RouteParamsFromLink ¶
func (sp *SchemaParser) RouteParamsFromLink(link *Link, schema *Schema) ([]RouteParam, error)
RouteParamsFromLink parses the link to return a slice of RouteParam, dereferenced using the schema from which the link originates.
type Template ¶
type Template struct { T *template.Template Schema *SchemaParser // contains filtered or unexported fields }
Template is a dispel Generator making use of a text/template for producing its output.
func NewTemplate ¶
func NewTemplate(sp *SchemaParser, text string) (*Template, error)
NewTemplate returns a new Template based on the SchemaParser using text.
func (*Template) AllHandlerFuncsImplemented ¶
AllHandlerFuncsImplemented returns true if all dispel's generated handlerfuncs are implemented in the target package.
func (*Template) Generate ¶
Generate implements the Generator interface. It executes the template with the ctx, and writes the output to w. The ctx is forced to use the Template's SchemaParser.
func (*Template) HandlerFuncName ¶
HandlerFuncName returns the name of a handlerfunc for a route method and name.
func (*Template) PrintSmartDerefType ¶
PrintSmartDerefType returns a pointer to j if j is a JSONObject.
func (*Template) PrintTypeDef ¶
PrintTypeDef returns a string representing a valid Go type definition for j.
func (*Template) RoutesForType ¶
func (t *Template) RoutesForType(j JSONType) []RouteAndIOTypeNames
RoutesForType returns the routes in which j is involved, either as itself or as a slice of itself.
func (*Template) TypeImports ¶
TypeImports returns the list of packages to import for the types generated by dispel.
func (*Template) TypeNeedsAddr ¶
TypeNeedsAddr returns true if it's necessary to take the address of a type.
type TypeNamer ¶
type TypeNamer interface {
TypeName() string
}
TypeNamer defines methods for types which are named types.
type TypeRedefinitionError ¶
type TypeRedefinitionError struct { Name string First JSONTypeNamer Redefs []JSONTypeNamer }
TypeRedefinitionError represents a named type which has been redefined one or more times with a different definition.
func (*TypeRedefinitionError) Error ¶
func (e *TypeRedefinitionError) Error() string