goa

package module
v0.0.0-...-de4052b Latest Latest
Warning

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

Go to latest
Published: Mar 26, 2016 License: MIT Imports: 22 Imported by: 0

README

goa is a framework for building microservices in Go using a unique design-first approach.

Build Status Windows Build status License Godoc Slack Intro

Why goa?

There are a number of good Go packages for writing modular web services out there so why build another one? Glad you asked! The existing packages tend to focus on providing small and highly modular frameworks that are purposefully narrowly focused. The intent is to keep things simple and to avoid mixing concerns.

This is great when writing simple APIs that tend to change rarely. However there are a number of problems that any non trivial API implementation must address. Things like request validation, response media type definitions or documentation are hard to do in a way that stays consistent and flexible as the API surface evolves.

goa takes a different approach to building these applications: instead of focusing solely on helping with implementation, goa makes it possible to describe the design of an API in an holistic way. goa then uses that description to provide specialized helper code to the implementation and to generate documentation, API clients, tests, even custom artifacts.

The goa design language allows writing self-explanatory code that describes the resources exposed by the API and for each resource the properties and actions. goa comes with the goagen tool which runs the design language and generates various types of artifacts from the resulting metadata.

One of the goagen output is glue code that binds your code with the underlying HTTP server. This code is specific to your API so that for example there is no need to cast or "bind" any handler argument prior to using them. Each generated handler has a signature that is specific to the corresponding resource action. It's not just the parameters though, each handler also has access to specific helper methods that generate the possible responses for that action. The metadata can also include validation rules so that the generated code also takes care of validating the incoming request parameters and payload prior to invoking your code.

The end result is controller code that is terse and clean, the boilerplate is all gone. Another big benefit is the clean separation of concern between design and implementation: on bigger projects it's often the case that API design changes require careful review, being able to generate a new version of the documentation without having to write a single line of implementation is a big boon.

This idea of separating design and implementation is not new, the excellent Praxis framework from RightScale follows the same pattern and was an inspiration to goa.

Other Whys and Hows

If you are new to goa I can't recommend enough that you read the Gopher Academy blog post. goa may look a little bit different at first, the post explains the thinking behind it so that you can better take advantage of the framework.

Installation

Assuming you have a working Go setup:

go get github.com/goadesign/goa/goagen

Teaser

1. Design

Create the file $GOPATH/src/goa-adder/design/design.go with the following content:

package design

import (
        . "github.com/goadesign/goa/design"
        . "github.com/goadesign/goa/design/apidsl"
)

var _ = API("adder", func() {
        Title("The adder API")
        Description("A teaser for goa")
        Host("localhost:8080")
        Scheme("http")
})

var _ = Resource("operands", func() {
        Action("add", func() {
                Routing(GET("add/:left/:right"))
                Description("add returns the sum of the left and right parameters in the response body")
                Params(func() {
                        Param("left", Integer, "Left operand")
                        Param("right", Integer, "Right operand")
                })
                Response(OK, "plain/text")
        })

})

This file contains the design for an adder API which accepts HTTP GET requests to /add/:x/:y where :x and :y are placeholders for integer values. The API returns the sum of x and y in its body.

2. Implement

Now that the design is done, let's run goagen on the design package:

$ cd $GOPATH/src/goa-adder
$ goagen bootstrap -d goa-adder/design

This produces the following outputs:

  • main.go and operands.go contain scaffolding code to help bootstrap the implementation. running goagen again does no recreate them so that it's safe to edit their content.
  • an app package which contains glue code that binds the low level HTTP server to your implementation.
  • a client package with a Client struct that implements a AddOperands function which calls the API with the given arguments and returns the http.Response. The client directory also contains the complete source for a client CLI tool (see below).
  • a swagger package with implements the GET /swagger.json API endpoint. The response contains the full Swagger specificiation of the API.
3. Run

First let's implement the API - edit the file operands.go and replace the content of the Add function with:

// Add runs the add action.
func (c *OperandsController) Add(ctx *app.AddOperandsContext) error {
        sum := ctx.Left + ctx.Right
        return ctx.OK([]byte(strconv.Itoa(sum)))
}

Now let's compile and run the service:

$ cd $GOPATH/src/goa-adder
$ go build
$ ./goa-adder
2016/02/16 16:39:27 [INFO] mount        ctrl: Operands  action: Add     route: GET /add/:left/:right
2016/02/16 16:39:27 [INFO] mount file   filename: swagger/swagger.json  path: GET /swagger.json
2016/02/16 16:39:27 [INFO] listen       address: :8080

Open a new console and compile the generated CLI tool:

cd $GOPATH/src/goa-adder/client/adder-cli
go build

The tool includes contextual help:

$ ./adder-cli --help
CLI client for the adder service

Usage:
  adder-cli [command]

Available Commands:
  add         add returns the sum of the left and right parameters in the response body

Flags:
      --dump[=false]: Dump HTTP request and response.
  -H, --host="localhost:8080": API hostname
      --pp[=false]: Pretty print response body
  -s, --scheme="http": Set the requests scheme
  -t, --timeout=20s: Set the request timeout, defaults to 20s

Use "adder-cli [command] --help" for more information about a command.
$ ./adder-cli add operands --help
Usage:
  adder-cli add operands [flags]

Global Flags:
      --dump[=false]: Dump HTTP request and response.
  -H, --host="localhost:8080": API hostname
      --pp[=false]: Pretty print response body
  -s, --scheme="http": Set the requests scheme
  -t, --timeout=20s: Set the request timeout, defaults to 20s

Now let's run it:

$ ./adder-cli add operands /add/1/2
2016/02/16 11:04:30 [INFO] started  id: fHAaZ9tx  GET: http://localhost:8080/add/1/2
2016/02/16 11:04:30 [INFO] completed  id: fHAaZ9tx  status: 200 time: 811.575µs
3⏎

The console running the service shows the request that was just handled:

2016/02/16 16:42:01 [INFO] started      app: API        ctrl: operands  action: Add     id: FloJa8uAbm-1        GET: /add/1/2
2016/02/16 16:42:01 [INFO] params       app: API        ctrl: operands  action: Add     id: FloJa8uAbm-1        left: 1 right: 2
2016/02/16 16:42:01 [INFO] completed    app: API        ctrl: operands  action: Add     id: FloJa8uAbm-1        status: 200     bytes: 1        time: 91.858µs

Now let's see how robust our service is and try to use non integer values:

./adder-cli add operands add/1/d
2016/02/24 11:05:15 [INFO] started  id: 3F1FKVRR  GET: http://localhost:8080/add/1/d
2016/02/24 11:05:15 [INFO] completed  id: 3F1FKVRR  status: 400 time: 1.044759ms
error: 400: "[{\"id\":1,\"title\":\"invalid parameter value\",\"msg\":\"invalid value \\\"d\\\" for parameter \\\"right\\\", must be a integer\"}]"

As you can see the generated code validated the incoming request state against the types defined in the design.

4. Document

The swagger directory contains the entire Swagger specification in the swagger.json file. The specification can also be accessed through the service:

$ curl localhost:8080/swagger.json

For open source services hosted on github swagger.goa.design provides a free service that renders the Swagger representation dynamically from goa design packages.

Resources

GoDoc
  • Package goa contains the data structures and algorithms used at runtime.
  • Package apidsl contains the implementation of the goa design language.
  • Package design defines the output data structures of the design language.
  • Package dslengine is a tool to parse and process any arbitrary DSL
Website

http://goa.design contains further information on goa.

Getting Started

Can't wait to give it a try? the easiest way is to follow the short getting started guide.

Middleware

The middleware package provides a number of middlewares covering common needs. It also provides a good source of examples for writing new middlewares.

Examples

The goa-cellar repo contains the implementation for a goa service which demonstrates many aspects of the design language. It is kept up-to-date and provides a reference for testing functionality.

Contributing

Did you fix a bug? write docs or additional tests? or implement some new awesome functionality? You're a rock star!! Just make sure that make succeeds (or that TravisCI is green) and send a PR over.

The issues contain entries tagged with help wanted: beginners which provide a great way to get started!

Documentation

Overview

Package goa provides the runtime support for goa microservices.

Code Generation

goa service development begins with writing the *design* of a service. The design is described using the goa language implemented by the github.com/goadesign/goa/design/apidsl package. The `goagen` tool consumes the metadata produced from executing the design language to generate service specific code that glues the underlying HTTP server with action specific code and data structures.

The goa package contains supporting functionality for the generated code including basic request and response state management through the RequestData and ResponseData structs, error handling via the service and controller ErrorHandler field, middleware support via the Middleware data structure as well as decoding and encoding algorithms.

Request Context

The RequestData and ResponseData structs provides access to the request and response state. goa request handlers also accept a golang.org/x/net/Context interface as first parameter so that deadlines and cancelation signals may easily be implemented.

The request state exposes the underlying http.Request object as well as the deserialized payload (request body) and parameters (both path and querystring parameters). Generated action specific contexts wrap the context.Context, ResponseData and RequestData data structures. They expose properly typed fields that correspond to the request parameters and body data structure descriptions appearing in the design.

The response state exposes the response status and body length as well as the underlying ResponseWriter. Action contexts provide action specific helper methods that write the responses as described in the design optionally taking an instance of the media type for responses that contain a body.

Here is an example showing an "update" action corresponding to following design (extract):

Resource("bottle", func() {
	DefaultMedia(Bottle)
	Action("update", func() {
		Params(func() {
			Param("bottleID", Integer)
		})
		Payload(UpdateBottlePayload)
		Response(OK)
		Response(NotFound)
	})
})

The action signature generated by goagen is:

type BottleController interface {
	goa.Controller
	Update(*UpdateBottleContext) error
}

where UpdateBottleContext is:

	type UpdateBottleContext struct {
        	context.Context   // Timeout and deadline support
		*goa.ResponseData // Response state access
		*goa.RequestData  // Request state access
        	BottleID  int     // Properly typed parameter fields
        	Payload   *UpdateBottlePayload // Properly typed payload
	}

and implements:

func (ctx *UpdateBottleContext) OK(resp *Bottle) error
func (ctx *UpdateBottleContext) NotFound() error

The definitions of the Bottle and UpdateBottlePayload data structures are ommitted for brievity.

Controllers

There is one controller interface generated per resource defined via the design language. The interface exposes the controller actions. User code must provide data structures that implement these interfaces when mounting a controller onto a service. The controller data structure should include an anonymous field of type *goa.Controller which takes care of implementing the middleware and error handler handling.

Error Handling

The controller action methods generated by goagen such as the Update method of the BottleController interface shown above all return an error value. The controller or service-wide error handler (if no controller specific error handler) function is invoked whenever the value returned by a controller action is not nil. The handler gets both the request context and the error as argument.

The default handler implementation returns a response with status code 500 containing the error message in the body. A different error handler can be specificied using the SetErrorHandler function on either a controller or service wide. goa comes with an alternative error handler - the TerseErrorHandler - which also returns a response with status 500 but does not write the error message to the body of the response.

Middleware

A goa middleware is a function that takes and returns a Handler. A Handler is a the low level function which handles incoming HTTP requests. goagen generates the handlers code so each handler creates the action specific context and calls the controller action with it.

Middleware can be added to a goa service or a specific controller using the Service type Use method. goa comes with a few stock middleware that handle common needs such as logging, panic recovery or using the RequestID header to trace requests across multiple services.

Validation

The goa design language documented in the dsl package makes it possible to attach validations to data structure definitions. One specific type of validation consists of defining the format that a data structure string field must follow. Example of formats include email, data time, hostnames etc. The ValidateFormat function provides the implementation for the format validation invoked from the code generated by goagen.

Encoding

The goa design language makes it possible to specify the encodings supported by the API both as input (Consumes) and output (Produces). goagen uses that information to registed the corresponding packages with the service encoders and decoders via the Encoder and Decoder methods. The service exposes the Decode, DecodeRequest, Encode and EncodeResponse that implement a simple content type negotiation algorithm for picking the right encoder for the "Accept" request header.

Package goa standardizes on structured error responses: a request that fails because of invalid input or unexpected condition produces a response that contains a structured error. Error objects has four keys: a code, a status, a detail and metadata. The code defines the class of error (e.g. "invalid_parameter_type") and the status is the corresponding HTTP status (e.g. 400). The detail is specific to the error occurrence. The medata provides additional values that provide contextual information (name of parameters etc.).

The basic data structure backing errors is Error. Instances of Error can be created via Error Class functions. See http://goa.design/implement/error_handling.html

The code generated by goagen calls the helper functions exposed in this file when it encounters invalid data (wrong type, validation errors etc.) such as InvalidParamTypeError, InvalidAttributeTypeError etc. These methods return errors that get merged with any previously encountered error via the Error Merge method.

goa includes an error handler middleware that takes care of mapping back any error returned by previously called middleware or action handler into HTTP responses. If the error is an instance of Error then the corresponding content including the HTTP status is used otherwise an internal error is returned. Errors that bubble up all the way to the top (i.e. not handled by the error middleware) also generate an internal error response.

Index

Constants

View Source
const (
	// FormatDateTime defines RFC3339 date time values.
	FormatDateTime Format = "date-time"

	// FormatEmail defines RFC5322 email addresses.
	FormatEmail = "email"

	// FormatHostname defines RFC1035 Internet host names.
	FormatHostname = "hostname"

	// FormatIPv4 defines RFC2373 IPv4 address values.
	FormatIPv4 = "ipv4"

	// FormatIPv6 defines RFC2373 IPv6 address values.
	FormatIPv6 = "ipv6"

	// FormatURI defines RFC3986 URI values.
	FormatURI = "uri"

	// FormatMAC defines IEEE 802 MAC-48, EUI-48 or EUI-64 MAC address values.
	FormatMAC = "mac"

	// FormatCIDR defines RFC4632 and RFC4291 CIDR notation IP address values.
	FormatCIDR = "cidr"

	// FormatRegexp Regexp defines regular expression syntax accepted by RE2.
	FormatRegexp = "regexp"
)
View Source
const ErrMissingLogValue = "MISSING"

ErrMissingLogValue is the value used to log keys with missing values

View Source
const (
	// ErrorMediaIdentifier is the media type identifier used for error responses.
	ErrorMediaIdentifier = "application/vnd.api.error+json"
)

Variables

View Source
var (
	// ErrInvalidRequest is the class of errors produced by the generated code when
	// a request parameter or payload fails to validate.
	ErrInvalidRequest = NewErrorClass("invalid_request", 400)

	// ErrInvalidEncoding is the error produced when a request body fails
	// to be decoded.
	ErrInvalidEncoding = NewErrorClass("invalid_encoding", 400)

	// ErrNoSecurityScheme is the error produced when no security scheme has been
	// registered for a name defined in the design.
	ErrNoSecurityScheme = NewErrorClass("no_security_scheme", 500)

	// ErrBadRequest is a generic bad request error.
	ErrBadRequest = NewErrorClass("bad_request", 400)

	// ErrInternal is the class of error used for non Error.
	ErrInternal = NewErrorClass("internal", 500)
)

Functions

func AddSample

func AddSample(key []string, val float32)

AddSample adds a sample to an aggregated metric reporting count, min, max, mean, and std deviation Usage:

AddSample([]string{"my","namespace","key"}, 15.0)

func EmitKey

func EmitKey(key []string, val float32)

EmitKey emits a key/value pair Usage:

EmitKey([]string{"my","namespace","key"}, 15.0)

func IncrCounter

func IncrCounter(key []string, val float32)

IncrCounter increments the counter named by `key` Usage:

IncrCounter([]key{"my","namespace","counter"}, 1.0)

func LastResortErrorHandler

func LastResortErrorHandler(ctx context.Context, rw http.ResponseWriter, req *http.Request, e error)

LastResortErrorHandler is the last thing that can handle an error propagating up the middleware chain and turns all errors into a response indicating an internal error. Ideally all errors are handled at a lower level in the middleware chain so they can be logged properly.

func LogContext

func LogContext(ctx context.Context) []interface{}

LogContext returns the logging context initialized via LogWith.

func LogError

func LogError(ctx context.Context, msg string, keyvals ...interface{})

LogError extracts the logger from the given context and calls Error on it. In general this shouldn't be needed (the client code should already have a handle on the logger) This is mainly useful for "out-of-band" code like middleware.

func LogInfo

func LogInfo(ctx context.Context, msg string, keyvals ...interface{})

LogInfo extracts the logger from the given context and calls Info on it. In general this shouldn't be needed (the client code should already have a handle on the logger) This is mainly useful for "out-of-band" code like middleware.

func LogWith

func LogWith(ctx context.Context, keyvals ...interface{}) context.Context

LogWith stores logging context to be used by all Log invocations using the returned context.

func MeasureSince

func MeasureSince(key []string, start time.Time)

MeasureSince creates a timing metric that records the duration of elapsed time since `start` Usage:

MeasureSince([]string{"my","namespace","action}, time.Now())

Frequently used in a defer:

defer MeasureSince([]string{"my","namespace","action}, time.Now())

func MergeErrors

func MergeErrors(err, other error) error

MergeErrors updates an error by merging another into it. It first converts other into an Error if not already one - producing an internal error in that case. The merge algorithm is then:

* If any of e or other is an internal error then the result is an internal error

* If the status or code of e and other don't match then the result is a 400 "bad_request"

The Detail field is updated by concatenating the Detail fields of e and other separated by a newline. The MetaValues field of is updated by merging the map of other MetaValues into e's where values in e with identical keys to values in other get overwritten.

Merge returns the updated error. This is useful in case the error was initially nil in which case other is returned.

func NewContext

func NewContext(ctx context.Context, rw http.ResponseWriter, req *http.Request, params url.Values) context.Context

NewContext builds a new goa request context. The parent context may include log context data. If parent is nil then RootContext is used.

func NewMetrics

func NewMetrics(conf *metrics.Config, sink metrics.MetricSink) (err error)

NewMetrics initializes goa's metrics instance with the supplied configuration and metrics sink

func SetGauge

func SetGauge(key []string, val float32)

SetGauge sets the named gauge to the specified value Usage:

SetGauge([]string{"my","namespace"}, 2.0)

func UseLogger

func UseLogger(ctx context.Context, logger Logger) context.Context

UseLogger sets the request context logger and returns the resulting new context.

func ValidateFormat

func ValidateFormat(f Format, val string) error

ValidateFormat validates a string against a standard format. It returns nil if the string conforms to the format, an error otherwise. The format specification follows the json schema draft 4 validation extension. see http://json-schema.org/latest/json-schema-validation.html#anchor105 Supported formats are: - "date-time": RFC3339 date time value - "email": RFC5322 email address - "hostname": RFC1035 Internet host name - "ipv4" and "ipv6": RFC2673 and RFC2373 IP address values - "uri": RFC3986 URI value - "mac": IEEE 802 MAC-48, EUI-48 or EUI-64 MAC address value - "cidr": RFC4632 and RFC4291 CIDR notation IP address value - "regexp": Regular expression syntax accepted by RE2

func ValidatePattern

func ValidatePattern(p string, val string) bool

ValidatePattern returns an error if val does not match the regular expression p. It makes an effort to minimize the number of times the regular expression needs to be compiled.

Types

type APIKeySecurity

type APIKeySecurity struct {
	// Description of the security scheme
	Description string
	// In represents where to check for some data, `query` or `header`
	In string
	// Name is the name of the `header` or `query` parameter to check for data.
	Name string
}

APIKeySecurity represents the `apiKey` security scheme. It handles a key that can be in the headers or in the query parameters, and does authentication based on that. The Name field represents the key of either the query string parameter or the header, depending on the In field.

type APIKeySecurityConfigFunc

type APIKeySecurityConfigFunc func(scheme *APIKeySecurity) Middleware

APIKeySecurityConfigFunc is what you need to pass to the generated `ConfigureYourAPIKeySecurity` functions in your `app`.

type BasicAuthSecurity

type BasicAuthSecurity struct {
	// Description of the security scheme
	Description string
}

BasicAuthSecurity represents the `Basic` security scheme, which consists of a simple login/pass, accessible through Request.BasicAuth().

type BasicAuthSecurityConfigFunc

type BasicAuthSecurityConfigFunc func(scheme *BasicAuthSecurity) Middleware

BasicAuthSecurityConfigFunc is what you need to pass to the generated `ConfigureYourBasicAuthSecurity` functions in your `app`.

type Controller

type Controller struct {
	Name       string          // Controller resource name
	Context    context.Context // Controller root context
	Middleware []Middleware    // Controller specific middleware if any
}

Controller provides the common state and behavior for generated controllers.

func (*Controller) MuxHandler

func (ctrl *Controller) MuxHandler(name string, hdlr Handler, unm Unmarshaler) MuxHandler

MuxHandler wraps a request handler into a MuxHandler. The MuxHandler initializes the request context by loading the request state, invokes the handler and in case of error invokes the controller (if there is one) or Service error handler. This function is intended for the controller generated code. User code should not need to call it directly.

func (*Controller) Use

func (ctrl *Controller) Use(m Middleware)

Use adds a middleware to the controller. See NewMiddleware for wrapping goa and http handlers into goa middleware. goa comes with a set of commonly used middleware, see middleware.go.

type DecodeFunc

type DecodeFunc func(context.Context, io.ReadCloser, interface{}) error

DecodeFunc is the function that initialize the unmarshaled payload from the request body.

type Decoder

type Decoder interface {
	Decode(v interface{}) error
}

A Decoder unmarshals an io.Reader into an interface

func NewGobDecoder

func NewGobDecoder(r io.Reader) Decoder

NewGobDecoder is an adapter for the encoding package gob decoder.

func NewJSONDecoder

func NewJSONDecoder(r io.Reader) Decoder

NewJSONDecoder is an adapter for the encoding package JSON decoder.

func NewXMLDecoder

func NewXMLDecoder(r io.Reader) Decoder

NewXMLDecoder is an adapter for the encoding package XML decoder.

type DecoderFunc

type DecoderFunc func(r io.Reader) Decoder

DecoderFunc instantiates a decoder that decodes data read from the given io reader.

type Encoder

type Encoder interface {
	Encode(v interface{}) error
}

An Encoder marshals from an interface into an io.Writer

func NewGobEncoder

func NewGobEncoder(w io.Writer) Encoder

NewGobEncoder is an adapter for the encoding package gob encoder.

func NewJSONEncoder

func NewJSONEncoder(w io.Writer) Encoder

NewJSONEncoder is an adapter for the encoding package JSON encoder.

func NewXMLEncoder

func NewXMLEncoder(w io.Writer) Encoder

NewXMLEncoder is an adapter for the encoding package XML encoder.

type EncoderFunc

type EncoderFunc func(w io.Writer) Encoder

EncoderFunc instantiates an encoder that encodes data into the given writer.

type Error

type Error struct {
	// Code identifies the class of errors for client programs.
	Code string `json:"code" xml:"code"`
	// Status is the HTTP status code used by responses that cary the error.
	Status int `json:"status" xml:"status"`
	// Detail describes the specific error occurrence.
	Detail string `json:"detail" xml:"detail"`
	// MetaValues contains additional key/value pairs useful to clients.
	MetaValues map[string]interface{} `json:"meta,omitempty" xml:"meta,omitempty"`
}

Error contains the details of a error response.

func InvalidAttributeTypeError

func InvalidAttributeTypeError(ctx string, val interface{}, expected string) *Error

InvalidAttributeTypeError creates a Error with class ID ErrInvalidAttributeType

func InvalidEnumValueError

func InvalidEnumValueError(ctx string, val interface{}, allowed []interface{}) *Error

InvalidEnumValueError creates a Error with class ID ErrInvalidEnumValue

func InvalidFormatError

func InvalidFormatError(ctx, target string, format Format, formatError error) *Error

InvalidFormatError creates a Error with class ID ErrInvalidFormat

func InvalidLengthError

func InvalidLengthError(ctx string, target interface{}, ln, value int, min bool) *Error

InvalidLengthError creates a Error with class ID ErrInvalidLength

func InvalidParamTypeError

func InvalidParamTypeError(name string, val interface{}, expected string) *Error

InvalidParamTypeError creates a Error with class ID ErrInvalidParamType

func InvalidPatternError

func InvalidPatternError(ctx, target string, pattern string) *Error

InvalidPatternError creates a Error with class ID ErrInvalidPattern

func InvalidRangeError

func InvalidRangeError(ctx string, target interface{}, value int, min bool) *Error

InvalidRangeError creates a Error with class ID ErrInvalidRange

func MissingAttributeError

func MissingAttributeError(ctx, name string) *Error

MissingAttributeError creates a Error with class ID ErrMissingAttribute

func MissingHeaderError

func MissingHeaderError(name string) *Error

MissingHeaderError creates a Error with class ID ErrMissingHeader

func MissingParamError

func MissingParamError(name string) *Error

MissingParamError creates a Error with class ID ErrMissingParam

func NoSecurityScheme

func NoSecurityScheme(schemeName string) *Error

NoSecurityScheme creates a Error with class ID ErrNoSecurityScheme

func (*Error) Error

func (e *Error) Error() string

Error returns the error occurrence details.

func (*Error) Meta

func (e *Error) Meta(keyvals ...interface{}) *Error

Meta adds to the error metadata.

type ErrorClass

type ErrorClass func(fm interface{}, v ...interface{}) *Error

ErrorClass is an error generating function. It accepts a format and values and produces errors with the resulting string. If the format is a string or a Stringer then the string value is used. If the format is an error then the string returned by Error() is used. Otherwise the string produced using fmt.Sprintf("%v") is used.

func NewErrorClass

func NewErrorClass(code string, status int) ErrorClass

NewErrorClass creates a new error class. It is the responsability of the client to guarantee uniqueness of code.

type ErrorHandler

type ErrorHandler func(context.Context, http.ResponseWriter, *http.Request, error)

ErrorHandler defines the service error handler signature.

type Format

type Format string

Format defines a validation format.

type Handler

Handler defines the controller handler signatures. If a controller handler returns an error then the service error handler is invoked with the request context and the error. The error handler is responsible for writing the HTTP response. See DefaultErrorHandler and TerseErrorHandler.

type JWTSecurity

type JWTSecurity struct {
	// Description of the security scheme
	Description string
	// In represents where to check for the JWT, `query` or `header`
	In string
	// Name is the name of the `header` or `query` parameter to check for data.
	Name string
	// TokenURL defines the URL where you'd get the JWT tokens.
	TokenURL string
	// Scopes defines a list of scopes for the security scheme, along with their description.
	Scopes map[string]string
}

JWTSecurity represents an api key based scheme, with support for scopes and a token URL.

type JWTSecurityConfigFunc

type JWTSecurityConfigFunc func(scheme *JWTSecurity, getScopes func(context.Context) []string) Middleware

JWTSecurityConfigFunc is what you need to pass to the generated `ConfigureYourOwnJWTSecurity` functions in your `app`.

The `goa/middleware/security` middlewares implement this for you.

type Logger

type Logger interface {
	// Info logs an informational message.
	Info(msg string, keyvals ...interface{})
	// Error logs an error.
	Error(msg string, keyvals ...interface{})
}

Logger is the logger interface used by goa to log informational and error messages. Adapters to different logging backends are provided in the logging package.

func ContextLogger

func ContextLogger(ctx context.Context) Logger

ContextLogger returns the logger used by the request context.

func NewStdLogger

func NewStdLogger(logger *log.Logger) Logger

NewStdLogger returns an implementation of Logger backed by a stdlib Logger.

type Middleware

type Middleware func(Handler) Handler

Middleware represents the canonical goa middleware signature.

func NewMiddleware

func NewMiddleware(m interface{}) (mw Middleware, err error)

NewMiddleware creates a middleware from the given argument. The allowed types for the argument are:

- a goa middleware: goa.Middleware or func(goa.Handler) goa.Handler

- a goa handler: goa.Handler or func(*goa.Context) error

- an http middleware: func(http.Handler) http.Handler

- or an http handler: http.Handler or func(http.ResponseWriter, *http.Request)

An error is returned if the given argument is not one of the types above.

type MuxHandler

type MuxHandler func(http.ResponseWriter, *http.Request, url.Values)

MuxHandler provides the low level implementation for an API endpoint. The values argument includes both the querystring and path parameter values.

type Muxer

type Muxer interface {
	MuxHandler(string, Handler, Unmarshaler) MuxHandler
}

Muxer implements an adapter that given a request handler can produce a mux handler.

type OAuth2Security

type OAuth2Security struct {
	// Description of the security scheme
	Description string
	// Flow defines the OAuth2 flow type. See http://swagger.io/specification/#securitySchemeObject
	Flow string
	// TokenURL defines the OAuth2 tokenUrl.  See http://swagger.io/specification/#securitySchemeObject
	TokenURL string
	// AuthorizationURL defines the OAuth2 authorizationUrl.  See http://swagger.io/specification/#securitySchemeObject
	AuthorizationURL string
	// Scopes defines a list of scopes for the security scheme, along with their description.
	Scopes map[string]string
}

OAuth2Security represents the `oauth2` security scheme. It is automatically instantiated in your generated code when you use the different `*Security()` DSL functions and `Security()` in your design.

type OAuth2SecurityConfigFunc

type OAuth2SecurityConfigFunc func(scheme *OAuth2Security, getScopes func(context.Context) []string) Middleware

OAuth2SecurityConfigFunc is what you need to pass to the generated `ConfigureYourOwnOAuth2Security` functions in your `app`.

The `goa/middleware/security` middlewares implement this for you.

type RequestData

type RequestData struct {
	*http.Request

	// Payload returns the decoded request body.
	Payload interface{}
	// Params is the path and querystring request parameters.
	Params url.Values
}

RequestData provides access to the underlying HTTP request.

func ContextRequest

func ContextRequest(ctx context.Context) *RequestData

ContextRequest gives access to the underlying HTTP request.

type ResettableDecoder

type ResettableDecoder interface {
	Decoder
	Reset(r io.Reader)
}

The ResettableDecoder is used to determine whether or not a Decoder can be reset and thus safely reused in a sync.Pool

type ResettableEncoder

type ResettableEncoder interface {
	Encoder
	Reset(w io.Writer)
}

The ResettableEncoder is used to determine whether or not a Encoder can be reset and thus safely reused in a sync.Pool

type ResponseData

type ResponseData struct {
	http.ResponseWriter

	// Status is the response HTTP status code
	Status int
	// Length is the response body length
	Length int
}

ResponseData provides access to the underlying HTTP response.

func ContextResponse

func ContextResponse(ctx context.Context) *ResponseData

ContextResponse gives access to the underlying HTTP response.

func (*ResponseData) BadRequest

func (r *ResponseData) BadRequest(ctx context.Context, err *Error) error

BadRequest sends a HTTP response with status code 400 and the given error as body.

func (*ResponseData) Bug

func (r *ResponseData) Bug(ctx context.Context, format string, a ...interface{}) error

Bug sends a HTTP response with status code 500 and the given body. The body can be set using a format and substituted values a la fmt.Printf.

func (*ResponseData) Send

func (r *ResponseData) Send(ctx context.Context, code int, body interface{}) error

Send serializes the given body matching the request Accept header against the service encoders. It uses the default service encoder if no match is found.

func (*ResponseData) SwitchWriter

func (r *ResponseData) SwitchWriter(rw http.ResponseWriter) http.ResponseWriter

SwitchWriter overrides the underlying response writer. It returns the response writer that was previously set.

func (*ResponseData) Write

func (r *ResponseData) Write(b []byte) (int, error)

Write records the amount of data written and calls the underlying writer.

func (*ResponseData) WriteHeader

func (r *ResponseData) WriteHeader(status int)

WriteHeader records the response status code and calls the underlying writer.

func (*ResponseData) Written

func (r *ResponseData) Written() bool

Written returns true if the response was written.

type ServeMux

type ServeMux interface {
	http.Handler
	// Handle sets the MuxHandler for a given HTTP method and path.
	Handle(method, path string, handle MuxHandler)
	// Lookup returns the MuxHandler associated with the given HTTP method and path.
	Lookup(method, path string) MuxHandler
}

ServeMux is the interface implemented by the service request muxes. It implements http.Handler and makes it possible to register request handlers for specific HTTP methods and request path via the Handle method.

func NewMux

func NewMux() ServeMux

NewMux returns a Mux.

type Service

type Service struct {
	// Name of service used for logging, tracing etc.
	Name string
	// Mux is the service request mux
	Mux ServeMux
	// Context is the root context from which all request contexts are derived.
	// Set values in the root context prior to starting the server to make these values
	// available to all request handlers:
	//
	//	service.Context = context.WithValue(service.Context, key, value)
	//
	Context context.Context
	// Middleware chain
	Middleware []Middleware
	// contains filtered or unexported fields
}

Service is the data structure supporting goa services. It provides methods for configuring a service and running it. At the basic level a service consists of a set of controllers, each implementing a given resource actions. goagen generates global functions - one per resource - that make it possible to mount the corresponding controller onto a service. A service contains the middleware, error handler, encoders and muxes shared by all its controllers. Setting up a service might look like:

service := goa.New("my api")
service.Use(SomeMiddleware())
rc := NewResourceController()
rc.Use(SomeOtherMiddleware())
service.MountResourceController(service, rc)
service.ListenAndServe(":80")

where NewResourceController returns an object that implements the resource actions as defined by the corresponding interface generated by goagen.

func ContextService

func ContextService(ctx context.Context) *Service

ContextService returns the service tageted by the request with the given context.

func New

func New(name string) *Service

New instantiates an service with the given name and default decoders/encoders.

func (*Service) CancelAll

func (service *Service) CancelAll()

CancelAll sends a cancel signals to all request handlers via the context. See https://godoc.org/golang.org/x/net/context for details on how to handle the signal.

func (*Service) Decode

func (service *Service) Decode(v interface{}, body io.Reader, contentType string) error

Decode uses registered Decoders to unmarshal a body based on the contentType

func (*Service) DecodeRequest

func (service *Service) DecodeRequest(req *http.Request, v interface{}) error

DecodeRequest retrives the request body and `Content-Type` header and uses Decode to unmarshal into the provided `interface{}`

func (*Service) Decoder

func (service *Service) Decoder(f DecoderFunc, contentTypes ...string)

Decoder sets a specific decoder to be used for the specified content types. If a decoder is already registered, it will be overwritten.

func (*Service) EncodeResponse

func (service *Service) EncodeResponse(ctx context.Context, v interface{}) error

EncodeResponse uses registered Encoders to marshal the response body based on the request `Accept` header and writes it to the http.ResponseWriter

func (*Service) Encoder

func (service *Service) Encoder(f EncoderFunc, contentTypes ...string)

Encoder sets a specific encoder to be used for the specified content types. If an encoder is already registered, it will be overwritten.

func (*Service) ListenAndServe

func (service *Service) ListenAndServe(addr string) error

ListenAndServe starts a HTTP server and sets up a listener on the given host/port.

func (*Service) ListenAndServeTLS

func (service *Service) ListenAndServeTLS(addr, certFile, keyFile string) error

ListenAndServeTLS starts a HTTPS server and sets up a listener on the given host/port.

func (*Service) LogError

func (service *Service) LogError(msg string, keyvals ...interface{})

LogError logs the error and values at odd indeces using the keys at even indeces of the keyvals slice.

func (*Service) LogInfo

func (service *Service) LogInfo(msg string, keyvals ...interface{})

LogInfo logs the message and values at odd indeces using the keys at even indeces of the keyvals slice.

func (*Service) NewController

func (service *Service) NewController(resName string) *Controller

NewController returns a controller for the given resource. This method is mainly intended for use by the generated code. User code shouldn't have to call it directly.

func (*Service) ServeFiles

func (service *Service) ServeFiles(path, filename string) error

ServeFiles replies to the request with the contents of the named file or directory. The logic for what to do when the filename points to a file vs. a directory is the same as the standard http package ServeFile function. The path may end with a wildcard that matches the rest of the URL (e.g. *filepath). If it does the matching path is appended to filename to form the full file path, so:

ServeFiles("/index.html", "/www/data/index.html")

Returns the content of the file "/www/data/index.html" when requests are sent to "/index.html" and:

ServeFiles("/assets/*filepath", "/www/data/assets")

returns the content of the file "/www/data/assets/x/y/z" when requests are sent to "/assets/x/y/z".

func (*Service) Use

func (service *Service) Use(m Middleware)

Use adds a middleware to the service wide middleware chain. See NewMiddleware for wrapping goa and http handlers into goa middleware. goa comes with a set of commonly used middleware, see middleware.go. Controller specific middleware should be mounted using the Controller type Use method instead.

func (*Service) UseLogger

func (service *Service) UseLogger(logger Logger)

UseLogger sets the logger used internally by the service and by Log.

type Unmarshaler

type Unmarshaler func(context.Context, *http.Request) error

Unmarshaler defines the request payload unmarshaler signatures.

Directories

Path Synopsis
_integration_tests
Package cors provides the means for implementing the server side of CORS, see https://developer.mozilla.org/en-US/docs/Web/HTTP/Access_control_CORS.
Package cors provides the means for implementing the server side of CORS, see https://developer.mozilla.org/en-US/docs/Web/HTTP/Access_control_CORS.
Package design defines types which describe the data types used by action controllers.
Package design defines types which describe the data types used by action controllers.
apidsl
Package apidsl implements the goa design language.
Package apidsl implements the goa design language.
apidsl/test
Package test contains a self-contained DSL test.
Package test contains a self-contained DSL test.
Package encoding provide goa adapters to many different encoders.
Package encoding provide goa adapters to many different encoders.
codegen
Package codegen contains common code used by all code generators.
Package codegen contains common code used by all code generators.
gen_client
Package genclient provides a generator for the client tool and package of a goa application.
Package genclient provides a generator for the client tool and package of a goa application.
gen_gen
Package gengen provides goagen with the ability to run user provided generators (*plugins*).
Package gengen provides goagen with the ability to run user provided generators (*plugins*).
gen_js
Package genjs provides a goa generator for a javascript client module.
Package genjs provides a goa generator for a javascript client module.
gen_main
Package genmain provides a generator for a skeleton goa application.
Package genmain provides a generator for a skeleton goa application.
gen_schema
Package genschema provides a generator for the JSON schema controller.
Package genschema provides a generator for the JSON schema controller.
gen_swagger
Package genswagger provides a generator for the JSON swagger controller.
Package genswagger provides a generator for the JSON swagger controller.
meta
Package meta is used to bootstrap the code generator.
Package meta is used to bootstrap the code generator.
Package logging contains logger adapters that make it possible for goa to log messages to various logger backends.
Package logging contains logger adapters that make it possible for goa to log messages to various logger backends.
kit
Package goakit contains an adapter that makes it possible to configure goa so it uses the go-kit log package as logger backend.
Package goakit contains an adapter that makes it possible to configure goa so it uses the go-kit log package as logger backend.
log15
Package goalog15 contains an adapter that makes it possible to configure goa so it uses log15 as logger backend.
Package goalog15 contains an adapter that makes it possible to configure goa so it uses log15 as logger backend.
logrus
Package goalogrus contains an adapter that makes it possible to configure goa so it uses logrus as logger backend.
Package goalogrus contains an adapter that makes it possible to configure goa so it uses logrus as logger backend.

Jump to

Keyboard shortcuts

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