package module
Version: v0.0.0-...-7f954c2 Latest Latest

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

Go to latest
Published: Oct 12, 2020 License: MIT Imports: 14 Imported by: 1



Generate Go client code for HTTP APIs described by JSON Hyper-Schemas.


Download and install:

$ go get -u

Warning: schematic requires Go >= 1.7.

Client Generation

Run it against your schema:

$ schematic platform-api.json > heroku/heroku.go

This will generate a Go package named after your schema:

package heroku

Or using go generate:

//go:generate schematic -o heroku/heroku.go platform-api.json

Client Usage

You then would be able to use the package as follow:

package main

import "./heroku"

func main() {
  h := heroku.NewService(nil)
  addons, err := h.AddonServiceList(nil)
  if err != nil {
  for _, addon := range addons {

A Service takes an optional http.Client as argument. This Client will need to handle any HTTP-related details unique to the target API service such as request authorization, request header setup, error handling, response debugging, etc.

As an example, if your service use OAuth2 for authentication:

var config = &oauth.Config{
transport := &oauth.Transport{
  Token:     token,
  Config:    config,
  Transport: http.DefaultTransport,
httpClient := transport.Client()
s := api.NewService(httpClient)

For an example of a service using HTTP Basic Auth, see the generated heroku-go client.

In general, creating a custom http.Transport and creating a client from that is a common way to get an appropriate http.Client for your service.

Client Method Types

Methods on generated clients will follow one of a few common patterns corresponding to reading a single resource, reading a list of resources, and creating or updating a resource.

Reading a single resource looks like this, for example:

app, err := h.AppInfo("my-app")
if err != nil {
fmt.Printf("%+v\n", app)

Where the struct app is of a type e.g. heroku.App defined in the generated client. It will include generated struct members for the various fields included in the API response.

Methods to read a list of resources look similar, for example:

apps, err := h.AppList(nil)
if err != nil {
for _, app := range apps {

The first return value of these methods is a slice of domain structs like heroku.App described above.

List methods take a *ListRange argument that can be used to specify ordering and pagination range options on the underlying list call.

Methods to create or update look like this, for example:

newName := "my-app"
updateOpts := heroku.AppUpdateOpts{
    Name: &newName,
app, err := h.AppUpdate("my-renamed-app", updateOpts)
if err != nil {

Note the availability of generated types of with suffixes UpdateOpts and CreateOpts - these make it easy to generate arguments for update and create calls. These types have pointer members instead of value members so that you can omit some of them without defaulting them to the a zero-value.

See the generated godocs for your package for details on the generated methods and types.


Schematic bundles templated Go code into a Go source file via the templates package. To rebuild the Go source file after changing .tmpl files:

$ templates -s templates/ - templates/templates.go




This section is empty.


This section is empty.


This section is empty.


type HRef

type HRef struct {
	Order   []string
	Schemas map[string]*Schema
	// contains filtered or unexported fields

HRef represents a Link href.

func NewHRef

func NewHRef(href string) *HRef

NewHRef creates a new HRef struct based on a href value.

func (*HRef) MarshalJSON

func (h *HRef) MarshalJSON() ([]byte, error)

MarshalJSON returns *h as the JSON encoding of h.

func (*HRef) Resolve

func (h *HRef) Resolve(r *Schema, rs ResolvedSet)

Resolve resolves a href inside a Schema.

func (*HRef) String

func (h *HRef) String() string

func (*HRef) URL

func (h *HRef) URL() (*url.URL, error)

URL returns a usable URL for the href.

func (*HRef) UnmarshalJSON

func (h *HRef) UnmarshalJSON(data []byte) error

UnmarshalJSON sets *h to a copy of data.

type Link struct {
	Title        string  `json:"title,omitempty"`
	Description  string  `json:"description,omitempty"`
	HRef         *HRef   `json:"href,omitempty"`
	Rel          string  `json:"rel,omitempty"`
	Method       string  `json:"method,omitempty"`
	Schema       *Schema `json:"schema,omitempty"`
	TargetSchema *Schema `json:"targetSchema,omitempty"`
	MediaType    string  `json:"mediaType,omitempty"`
	EncType      string  `json:"encType,omitempty"`

Link represents a Link description.

func (*Link) AcceptsCustomType

func (l *Link) AcceptsCustomType() bool

AcceptsCustomType returns true if the link schema is not a primitive type

func (*Link) GoType

func (l *Link) GoType() (string, bool)

GoType returns Go type for the given schema as string and a bool specifying whether it is required

func (*Link) Parameters

func (l *Link) Parameters(name string) ([]string, map[string]string)

Parameters returns function parameters names and types.

func (*Link) Resolve

func (l *Link) Resolve(r *Schema, rs ResolvedSet)

Resolve resolve link schema and href.

type Reference

type Reference string

Reference represents a JSON Reference.

func NewReference

func NewReference(ref string) *Reference

NewReference creates a new Reference based on a reference value.

func (Reference) Resolve

func (rf Reference) Resolve(r *Schema) *Schema

Resolve resolves reference inside a Schema.

type ResolvedSet

type ResolvedSet map[interface{}]bool

ResolvedSet stores a set of pointers to objects that have already been resolved to prevent infinite loops.

func (ResolvedSet) Has

func (rs ResolvedSet) Has(o interface{}) bool

Has returns if a pointer has already been resolved.

func (ResolvedSet) Insert

func (rs ResolvedSet) Insert(o interface{})

Insert marks a pointer as resolved.

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"`
	Example  interface{} `json:"example,omitempty"`
	Format   string      `json:"format,omitempty"`

	Type interface{} `json:"type,omitempty"`

	Ref    *Reference `json:"$ref,omitempty"`
	Schema *Reference `json:"$schema,omitempty"`

	Definitions map[string]*Schema `json:"definitions,omitempty"`

	// Numbers
	MultipleOf       float64 `json:"multipleOf,omitempty"`
	Maximum          float64 `json:"maximum,omitempty"`
	ExclusiveMaximum bool    `json:"exclusiveMaximum,omitempty"`
	Minimum          float64 `json:"minimum,omitempty"`
	ExclusiveMinimum bool    `json:"exclusiveMinimum,omitempty"`

	// Strings
	MinLength int    `json:"minLength,omitempty"`
	MaxLength int    `json:"maxLength,omitempty"`
	Pattern   string `json:"pattern,omitempty"`

	// Objects
	MinProperties        int                    `json:"minProperties,omitempty"`
	MaxProperties        int                    `json:"maxProperties,omitempty"`
	Required             []string               `json:"required,omitempty"`
	Properties           map[string]*Schema     `json:"properties,omitempty"`
	Dependencies         map[string]interface{} `json:"dependencies,omitempty"`
	AdditionalProperties interface{}            `json:"additionalProperties,omitempty"`
	PatternProperties    map[string]*Schema     `json:"patternProperties,omitempty"`

	// Arrays
	Items           *Schema     `json:"items,omitempty"`
	MinItems        int         `json:"minItems,omitempty"`
	MaxItems        int         `json:"maxItems,omitempty"`
	UniqueItems     bool        `json:"uniqueItems,omitempty"`
	AdditionalItems interface{} `json:"additionalItems,omitempty"`

	// All
	Enum []string `json:"enum,omitempty"`

	// Schemas
	OneOf []Schema `json:"oneOf,omitempty"`
	AnyOf []Schema `json:"anyOf,omitempty"`
	AllOf []Schema `json:"allOf,omitempty"`
	Not   *Schema  `json:"not,omitempty"`

	// Links
	Links []*Link `json:"links,omitempty"`

Schema represents a JSON Schema.

func (*Schema) AreTitleLinksUnique

func (s *Schema) AreTitleLinksUnique() bool

AreTitleLinksUnique ensures that all titles are unique for a schema.

If more than one link in a given schema has the same title, we cannot accurately generate the client from the schema. Although it's not strictly a schema violation, it needs to be fixed before the client can be properly generated.

func (*Schema) EmptyResult

func (s *Schema) EmptyResult(l *Link) bool

EmptyResult retursn true if the link result should be empty.

func (*Schema) Generate

func (s *Schema) Generate() ([]byte, error)

Generate generates code according to the schema.

func (*Schema) GoType

func (s *Schema) GoType() string

GoType returns the Go type for the given schema as string.

func (*Schema) IsCustomType

func (s *Schema) IsCustomType() bool

IsCustomType returns true if the schema declares a custom type.

func (*Schema) Resolve

func (s *Schema) Resolve(r *Schema, rs ResolvedSet) *Schema

Resolve resolves reference inside the schema.

func (*Schema) ReturnedGoType

func (s *Schema) ReturnedGoType(name string, l *Link) string

ReturnedGoType returns Go type returned by the given link as a string.

func (*Schema) ReturnsCustomType

func (s *Schema) ReturnsCustomType(l *Link) bool

ReturnsCustomType returns true if the link returns a custom type.

func (*Schema) Types

func (s *Schema) Types() (types []string, err error)

Types returns the array of types described by this schema.

func (*Schema) URL

func (s *Schema) URL() string

URL returns schema base URL.

func (*Schema) Values

func (s *Schema) Values(name string, l *Link) []string

Values returns function return values types.


Path Synopsis
Schematic Generate Go client code for HTTP APIs described by JSON Hyper-Schemas:
Schematic Generate Go client code for HTTP APIs described by JSON Hyper-Schemas:

Jump to

Keyboard shortcuts

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