dsl

package
v2.2.5+incompatible Latest Latest
Warning

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

Go to latest
Published: Nov 1, 2020 License: MIT Imports: 8 Imported by: 88

Documentation

Overview

Package dsl implements the Goa DSL.

The Goa DSL consists of Go functions that can be composed to describe a remote service API. The functions are composed using anonymous function arguments, for example:

var Person = Type("Person", func() {
    Attribute("name", String)
})

The package defines a set of "top level" DSL functions - functions that do not appear within other functions such as Type above and a number of functions that are meant to be used within others such as Attribute above.

The comments for each function describe the intent, parameters and usage of the function. A number of DSL functions leverage variadic arguments to emulate optional arguments, for example these are all valid use of Attribute:

Attribute("name", String)
Attribute("name", String, "The name of the person")
Attribute("name", String, "The name of the person", func() {
    Meta("struct:field:type", "json.RawMessage")
})

It is recommended to use "dot" import when importing the DSL package to improve the readability of designs:

import . "goa.design/goa/dsl"

Importing the DSL package this way makes it possible to write the designs as shown in the examples above instead of having to prefix each DSL function call with "dsl." (note: the authors are aware that using "dot" imports is bad practice in general when writing standard Go code and Goa in particular makes no use of them outside of writing DSLs. However they DO make designs much easier to read and maintain).

The general structure of the DSL is shown below (partial list):

API                 Service          Type            ResultType
├── Title           ├── Description  ├── Extend      ├── TypeName
├── Description     ├── Docs         ├── Reference   ├── ContentType
├── Version         ├── Security     ├── ConvertTo   ├── Extend
├── Docs            ├── Error        ├── CreateFrom  ├── Reference
├── License         ├── GRPC         ├── Attribute   ├── ConvertTo
├── TermsOfService  ├── HTTP         ├── Field       ├── CreateFrom
├── Contact         ├── Method       └── Required    ├── Attributes
├── Server          │   ├── Payload                  └── View
└── HTTP            │   ├── Result
                    │   ├── Error
                    │   ├── GRPC
                    │   └── HTTP
                    └── Files

Index

Constants

View Source
const (
	// CodeOK represents the gRPC response code "OK".
	CodeOK = 0
	// CodeCanceled represents the gRPC response code "Canceled".
	CodeCanceled = 1
	// CodeUnknown represents the gRPC response code "Unknown".
	CodeUnknown = 2
	// CodeInvalidArgument represents the gRPC response code "InvalidArgument".
	CodeInvalidArgument = 3
	// CodeDeadlineExceeded represents the gRPC response code "DeadlineExceeded".
	CodeDeadlineExceeded = 4
	// CodeNotFound represents the gRPC response code "NotFound".
	CodeNotFound = 5
	// CodeAlreadyExists represents the gRPC response code "AlreadyExists".
	CodeAlreadyExists = 6
	// CodePermissionDenied represents the gRPC response code "PermissionDenied".
	CodePermissionDenied = 7
	// CodeResourceExhausted represents the gRPC response code "ResourceExhausted".
	CodeResourceExhausted = 8
	// CodeFailedPrecondition represents the gRPC response code "FailedPrecondition".
	CodeFailedPrecondition = 9
	// CodeAborted represents the gRPC response code "Aborted".
	CodeAborted = 10
	// CodeOutOfRange represents the gRPC response code "OutOfRange".
	CodeOutOfRange = 11
	// CodeUnimplemented represents the gRPC response code "Unimplemented".
	CodeUnimplemented = 12
	// CodeInternal represents the gRPC response code "Internal".
	CodeInternal = 13
	// CodeUnavailable represents the gRPC response code "Unavailable".
	CodeUnavailable = 14
	// CodeDataLoss represents the gRPC response code "DataLoss".
	CodeDataLoss = 15
	// CodeUnauthenticated represents the gRPC response code "Unauthenticated".
	CodeUnauthenticated = 16
)
View Source
const (
	StatusContinue           = expr.StatusContinue
	StatusSwitchingProtocols = expr.StatusSwitchingProtocols
	StatusProcessing         = expr.StatusProcessing

	StatusOK                   = expr.StatusOK
	StatusCreated              = expr.StatusCreated
	StatusAccepted             = expr.StatusAccepted
	StatusNonAuthoritativeInfo = expr.StatusNonAuthoritativeInfo
	StatusNoContent            = expr.StatusNoContent
	StatusResetContent         = expr.StatusResetContent
	StatusPartialContent       = expr.StatusPartialContent
	StatusMultiStatus          = expr.StatusMultiStatus
	StatusAlreadyReported      = expr.StatusAlreadyReported
	StatusIMUsed               = expr.StatusIMUsed

	StatusMultipleChoices  = expr.StatusMultipleChoices
	StatusMovedPermanently = expr.StatusMovedPermanently
	StatusFound            = expr.StatusFound
	StatusSeeOther         = expr.StatusSeeOther
	StatusNotModified      = expr.StatusNotModified
	StatusUseProxy         = expr.StatusUseProxy

	StatusTemporaryRedirect = expr.StatusTemporaryRedirect
	StatusPermanentRedirect = expr.StatusPermanentRedirect

	StatusBadRequest                   = expr.StatusBadRequest
	StatusUnauthorized                 = expr.StatusUnauthorized
	StatusPaymentRequired              = expr.StatusPaymentRequired
	StatusForbidden                    = expr.StatusForbidden
	StatusNotFound                     = expr.StatusNotFound
	StatusMethodNotAllowed             = expr.StatusMethodNotAllowed
	StatusNotAcceptable                = expr.StatusNotAcceptable
	StatusProxyAuthRequired            = expr.StatusProxyAuthRequired
	StatusRequestTimeout               = expr.StatusRequestTimeout
	StatusConflict                     = expr.StatusConflict
	StatusGone                         = expr.StatusGone
	StatusLengthRequired               = expr.StatusLengthRequired
	StatusPreconditionFailed           = expr.StatusPreconditionFailed
	StatusRequestEntityTooLarge        = expr.StatusRequestEntityTooLarge
	StatusRequestURITooLong            = expr.StatusRequestURITooLong
	StatusUnsupportedMediaType         = expr.StatusUnsupportedMediaType
	StatusRequestedRangeNotSatisfiable = expr.StatusRequestedRangeNotSatisfiable
	StatusExpectationFailed            = expr.StatusExpectationFailed
	StatusTeapot                       = expr.StatusTeapot
	StatusUnprocessableEntity          = expr.StatusUnprocessableEntity
	StatusLocked                       = expr.StatusLocked
	StatusFailedDependency             = expr.StatusFailedDependency
	StatusUpgradeRequired              = expr.StatusUpgradeRequired
	StatusPreconditionRequired         = expr.StatusPreconditionRequired
	StatusTooManyRequests              = expr.StatusTooManyRequests
	StatusRequestHeaderFieldsTooLarge  = expr.StatusRequestHeaderFieldsTooLarge
	StatusUnavailableForLegalReasons   = expr.StatusUnavailableForLegalReasons

	StatusInternalServerError           = expr.StatusInternalServerError
	StatusNotImplemented                = expr.StatusNotImplemented
	StatusBadGateway                    = expr.StatusBadGateway
	StatusServiceUnavailable            = expr.StatusServiceUnavailable
	StatusGatewayTimeout                = expr.StatusGatewayTimeout
	StatusHTTPVersionNotSupported       = expr.StatusHTTPVersionNotSupported
	StatusVariantAlsoNegotiates         = expr.StatusVariantAlsoNegotiates
	StatusInsufficientStorage           = expr.StatusInsufficientStorage
	StatusLoopDetected                  = expr.StatusLoopDetected
	StatusNotExtended                   = expr.StatusNotExtended
	StatusNetworkAuthenticationRequired = expr.StatusNetworkAuthenticationRequired
)
View Source
const (
	// Boolean is the type for a JSON boolean.
	Boolean = expr.Boolean

	// Int is the type for a signed integer.
	Int = expr.Int

	// Int32 is the type for a signed 32-bit integer.
	Int32 = expr.Int32

	// Int64 is the type for a signed 64-bit integer.
	Int64 = expr.Int64

	// UInt is the type for an unsigned integer.
	UInt = expr.UInt

	// UInt32 is the type for an unsigned 32-bit integer.
	UInt32 = expr.UInt32

	// UInt64 is the type for an unsigned 64-bit integer.
	UInt64 = expr.UInt64

	// Float32 is the type for a 32-bit floating number.
	Float32 = expr.Float32

	// Float64 is the type for a 64-bit floating number.
	Float64 = expr.Float64

	// String is the type for a JSON string.
	String = expr.String

	// Bytes is the type for binary data.
	Bytes = expr.Bytes

	// Any is the type for an arbitrary JSON value (interface{} in Go).
	Any = expr.Any
)
View Source
const (
	// FormatDate describes RFC3339 date values.
	FormatDate = expr.FormatDate

	// FormatDateTime describes RFC3339 date time values.
	FormatDateTime = expr.FormatDateTime

	// FormatUUID describes RFC4122 UUID values.
	FormatUUID = expr.FormatUUID

	// FormatEmail describes RFC5322 email addresses.
	FormatEmail = expr.FormatEmail

	// FormatHostname describes RFC1035 Internet hostnames.
	FormatHostname = expr.FormatHostname

	// FormatIPv4 describes RFC2373 IPv4 address values.
	FormatIPv4 = expr.FormatIPv4

	// FormatIPv6 describes RFC2373 IPv6 address values.
	FormatIPv6 = expr.FormatIPv6

	// FormatIP describes RFC2373 IPv4 or IPv6 address values.
	FormatIP = expr.FormatIP

	// FormatURI describes RFC3986 URI values.
	FormatURI = expr.FormatURI

	// FormatMAC describes IEEE 802 MAC-48, EUI-48 or EUI-64 MAC address values.
	FormatMAC = expr.FormatMAC

	// FormatCIDR describes RFC4632 and RFC4291 CIDR notation IP address values.
	FormatCIDR = expr.FormatCIDR

	// FormatRegexp describes regular expression syntax accepted by RE2.
	FormatRegexp = expr.FormatRegexp

	// FormatJSON describes JSON text.
	FormatJSON = expr.FormatJSON

	// FormatRFC1123 describes RFC1123 date time values.
	FormatRFC1123 = expr.FormatRFC1123
)

Variables

View Source
var (
	// ErrorResultIdentifier is the result type identifier used for error
	// responses.
	ErrorResultIdentifier = expr.ErrorResultIdentifier

	// ErrorResult is the built-in result type for error responses.
	ErrorResult = expr.ErrorResult
)
View Source
var Empty = expr.Empty

Empty represents empty values.

Functions

func API

func API(name string, fn func()) *expr.APIExpr

API defines a network service API. It provides the API name, description and other global properties. There may only be one API declaration in a given design package.

API is a top level DSL. API takes two arguments: the name of the API and the defining DSL.

The API properties are leveraged by the OpenAPI specification. The server expressions are also used by the server and the client tool code generators.

Example:

var _ = API("adder", func() {
    Title("title")                // Title used in documentation
    Description("description")    // Description used in documentation
    Version("2.0")                // Version of API
    TermsOfService("terms")       // Terms of use
    Contact(func() {              // Contact info
        Name("contact name")
        Email("contact email")
        URL("contact URL")
    })
    License(func() {              // License
        Name("license name")
        URL("license URL")
    })
    Docs(func() {                 // Documentation links
        Description("doc description")
        URL("doc URL")
    })
    Server("addersvr", func() {
        Host("development", func() {
            URI("http://localhost:80")
            URI("grpc://localhost:8080")
        })
    })
}

func APIKey

func APIKey(scheme, name string, args ...interface{})

APIKey defines the attribute used to provide the API key to an endpoint secured with API keys. The parameters and usage of APIKey are the same as the Attribute function except that it accepts an extra first argument corresponding to the name of the API key security scheme.

The generated code produced by goa uses the value of the corresponding payload field to set the API key value.

APIKey must appear in Payload or Type.

Example:

Method("secured_read", func() {
    Security(APIKeyAuth)
    Payload(func() {
        APIKey("api_key", "key", String, "API key used to perform authorization")
        Required("key")
    })
    Result(String)
    HTTP(func() {
        GET("/")
        Param("key:k") // Provide the key as a query string param "k"
    })
})

Method("secured_write", func() {
    Security(APIKeyAuth)
    Payload(func() {
        APIKey("api_key", "key", String, "API key used to perform authorization")
        Attribute("data", String, "Data to be written")
        Required("key", "data")
    })
    HTTP(func() {
        POST("/")
        Header("key:Authorization") // Provide the key in Authorization header (default)
    })
})

func APIKeyField

func APIKeyField(tag interface{}, scheme, name string, args ...interface{})

APIKeyField is syntactic sugar to define an API key attribute with the "rpc:tag" meta set with the value of the first argument.

APIKeyField takes the same arguments as APIKey with the addition of the tag value as the first argument.

func APIKeySecurity

func APIKeySecurity(name string, fn ...func()) *expr.SchemeExpr

APIKeySecurity defines an API key security scheme where a key must be provided by the client to perform authorization.

APIKeySecurity is a top level DSL.

APIKeySecurity takes a name as first argument and an optional DSL as second argument.

Example:

var APIKey = APIKeySecurity("key", func() {
      Description("Shared secret")
})

func AccessToken

func AccessToken(name string, args ...interface{})

AccessToken defines the attribute used to provide the access token to an endpoint secured with OAuth2. The parameters and usage of AccessToken are the same as the goa DSL Attribute function.

The generated code produced by goa uses the value of the corresponding payload field to initialize the Authorization header.

AccessToken must appear in Payload or Type.

Example:

Method("secured", func() {
    Security(OAuth2)
    Payload(func() {
        AccessToken("token", String, "OAuth2 access token used to perform authorization")
        Required("token")
    })
    Result(String)
    HTTP(func() {
        // The "Authorization" header is defined implicitly.
        GET("/")
    })
})

func AccessTokenField

func AccessTokenField(tag interface{}, name string, args ...interface{})

AccessTokenField is syntactic sugar to define an access token attribute with the "rpc:tag" meta set with the value of the first argument.

AccessTokenField takes the same arguments as AccessToken with the addition of the tag value as the first argument.

func ArrayOf

func ArrayOf(v interface{}, fn ...func()) *expr.Array

ArrayOf creates an array type from its element type.

ArrayOf may be used wherever types can. The first argument of ArrayOf is the type of the array elements specified by name or by reference. The second argument of ArrayOf is an optional function that defines validations for the array elements.

Examples:

var Names = ArrayOf(String, func() {
    Pattern("[a-zA-Z]+") // Validates elements of the array
})

var Account = Type("Account", func() {
    Attribute("bottles", ArrayOf(Bottle), "Account bottles", func() {
        MinLength(1) // Validates array as a whole
    })
})

Note: CollectionOf and ArrayOf both return array types. CollectionOf returns a result type where ArrayOf returns a user type. In general you want to use CollectionOf if the argument is a result type and ArrayOf if it is a user type.

func Attribute

func Attribute(name string, args ...interface{})

Attribute describes a field of an object.

An attribute has a name, a type and optionally a default value, an example value and validation rules.

The type of an attribute can be one of:

* The primitive types Boolean, Float32, Float64, Int, Int32, Int64, UInt, UInt32, UInt64, String or Bytes.

* A user type defined via the Type function.

* An array defined using the ArrayOf function.

* An map defined using the MapOf function.

* An object defined inline using Attribute to define the type fields recursively.

* The special type Any to indicate that the attribute may take any of the types listed above.

Attribute must appear in ResultType, Type, Attribute or Attributes.

Attribute accepts one to four arguments, the valid usages of the function are:

Attribute(name)       // Attribute of type String with no description, no
                      // validation, default or example value

Attribute(name, fn)   // Attribute of type object with inline field
                      // definitions, description, validations, default
                      // and/or example value

Attribute(name, type) // Attribute with no description, no validation,
                      // no default or example value

Attribute(name, type, fn) // Attribute with description, validations,
                          // default and/or example value

Attribute(name, type, description)     // Attribute with no validation,
                                       // default or example value

Attribute(name, type, description, fn) // Attribute with description,
                                       // validations, default and/or
                                       // example value

Where name is a string indicating the name of the attribute, type specifies the attribute type (see above for the possible values), description a string providing a human description of the attribute and fn the defining DSL if any.

When defining the type inline using Attribute recursively the function takes the second form (name and DSL defining the type). The description can be provided using the Description function in this case.

Examples:

Attribute("name")

Attribute("driver", Person)         // Use type defined with Type function

Attribute("driver", "Person")       // May also use the type name

Attribute("name", String, func() {
    Pattern("^foo")                 // Adds a validation rule
})

Attribute("driver", Person, func() {
    Required("name")                // Add required field to list of
})                                  // fields already required in Person

Attribute("name", String, func() {
    Default("bob")                  // Sets a default value
})

Attribute("name", String, "name of driver") // Sets a description

Attribute("age", Int32, "description", func() {
    Minimum(2)                       // Sets both a description and
                                     // validations
})

The definition below defines an attribute inline. The resulting type is an object with three attributes "name", "age" and "child". The "child" attribute is itself defined inline and has one child attribute "name".

Attribute("driver", func() {           // Define type inline
    Description("Composite attribute") // Set description

    Attribute("name", String)          // Child attribute
    Attribute("age", Int32, func() {   // Another child attribute
        Description("Age of driver")
        Default(42)
        Minimum(2)
    })
    Attribute("child", func() {        // Defines a child attribute
        Attribute("name", String)      // Grand-child attribute
        Required("name")
    })

    Required("name", "age")            // List required attributes
})

func Attributes

func Attributes(fn func())

Attributes implements the result type Attributes DSL. See ResultType.

func AuthorizationCodeFlow

func AuthorizationCodeFlow(authorizationURL, tokenURL, refreshURL string)

AuthorizationCodeFlow defines an authorizationCode OAuth2 flow as described in section 1.3.1 of RFC 6749.

AuthorizationCodeFlow must be used in OAuth2Security.

AuthorizationCodeFlow accepts three arguments: the authorization, token and refresh URLs.

func BasicAuthSecurity

func BasicAuthSecurity(name string, fn ...func()) *expr.SchemeExpr

BasicAuthSecurity defines a basic authentication security scheme.

BasicAuthSecurity is a top level DSL.

BasicAuthSecurity takes a name as first argument and an optional DSL as second argument.

Example:

var Basic = BasicAuthSecurity("basicauth", func() {
    Description("Use your own password!")
})

func Body

func Body(args ...interface{})

Body describes a HTTP request or response body.

Body must appear in a Method HTTP expression to define the request body or in an Error or Result HTTP expression to define the response body. If Body is absent then the body is built using the HTTP endpoint request or response type attributes not used to describe parameters (request only) or headers.

Body accepts one argument which describes the shape of the body, it can be:

  • The name of an attribute of the request or response type. In this case the attribute type describes the shape of the body.

  • A function listing the body attributes. The attributes inherit the properties (description, type, validations etc.) of the request or response type attributes with identical names.

Assuming the type:

var CreatePayload = Type("CreatePayload", func() {
    Attribute("name", String, "Name of account")
})

The following:

Method("create", func() {
    Payload(CreatePayload)
})

is equivalent to:

Method("create", func() {
    Payload(CreatePayload)
    HTTP(func() {
        Body(func() {
            Attribute("name")
        })
    })
})

func CONNECT

func CONNECT(path string) *expr.RouteExpr

CONNECT creates a route using the CONNECT HTTP method. See GET.

func CanonicalMethod

func CanonicalMethod(name string)

CanonicalMethod sets the name of the service canonical method. The canonical method endpoint HTTP path is used to prefix the paths to child service endpoints (a child service is a service that uses the Parent function). The default value is "show".

CanonicalMethod must appear in the HTTP expresssion of a Service.

CanonicalMethod accepts one argument: the name of the canonical service method.

func ClientCredentialsFlow

func ClientCredentialsFlow(tokenURL, refreshURL string)

ClientCredentialsFlow defines an clientCredentials OAuth2 flow as described in section 1.3.4 of RFC 6749.

ClientCredentialsFlow must be used in OAuth2Security.

ClientCredentialsFlow accepts two arguments: the token and refresh URLs.

func Code

func Code(code int)

Code sets the Response status code.

Code must appear in a Response expression.

Code accepts one argument: the HTTP or gRPC status code.

func CollectionOf

func CollectionOf(v interface{}, adsl ...func()) *expr.ResultTypeExpr

CollectionOf creates a collection result type from its element result type. A collection result type represents the content of responses that return a collection of values such as listings. The expression accepts an optional DSL as second argument that allows specifying which view(s) of the original result type apply.

The resulting result type identifier is built from the element result type by appending the result type parameter "type" with value "collection".

CollectionOf must appear wherever ResultType can.

CollectionOf takes the element result type as first argument and an optional DSL as second argument.

Example:

var DivisionResult = ResultType("application/vnd.goa.divresult", func() {
    Attributes(func() {
        Attribute("value", Float64)
        Attribute("remainder", Int)
    })
    View("default", func() {
        Attribute("value")
        Attribute("remainder")
    })
    View("tiny", func() {
        Attribute("value")
    })
})

var MultiResults = CollectionOf(DivisionResult)

var TinyMultiResults = CollectionOf(DivisionResult, func() {
    View("tiny")  // use "tiny" view to render the collection elements
})

func Consumes

func Consumes(args ...string)

Consumes adds a MIME type to the list of MIME types the APIs supports when accepting requests. While the DSL supports any MIME type, the code generator only knows to generate the code for "application/json", "application/xml" and "application/gob". The service code must provide the decoders for other MIME types.

Consumes must appear in the HTTP expression of API.

Consumes accepts one or more strings corresponding to the MIME types.

Example:

API("cellar", func() {
    // ...
    HTTP(func() {
        Consumes("application/json", "application/xml")
        // ...
    })
})

func Contact

func Contact(fn func())

Contact sets the API contact information.

Contact must appear in a API expression.

Contact takes a single argument which is the defining DSL.

Example:

var _ = API("divider", func() {
    Contact(func() {
        Name("support")
        Email("support@goa.design")
        URL("https://goa.design")
    })
})

func ContentType

func ContentType(typ string)

ContentType sets the value of the Content-Type response header.

ContentType must appear in a Response expression. ContentType accepts one argument: the mime type as defined by RFC 6838.

   var _ = Method("add", func() {
	      HTTP(func() {
           Response(StatusOK, func() {
               ContentType("application/json")
           })
       })
   })

func ConvertTo

func ConvertTo(obj interface{})

ConvertTo specifies an external type that instances of the generated struct are converted into. The generated struct is equipped with a method that makes it possible to instantiate the external type. The default algorithm used to match the external type fields to the design attributes is as follows:

  1. Look for an attribute with the same name as the field
  2. Look for an attribute with the same name as the field but with the first letter being lowercase
  3. Look for an attribute with a name corresponding to the snake_case version of the field name

This algorithm does not apply if the attribute is equipped with the "struct.field.external" meta. In this case the matching is done by looking up the field with a name corresponding to the value of the meta. If the value of the meta is "-" the attribute isn't matched and no conversion code is generated for it. In all other cases it is an error if no match is found or if the matching field type does not correspond to the attribute type.

The following limitations apply on the external Go struct field types recursively:

  • struct fields must use pointers
  • pointers on slices or on maps are not supported

ConvertTo must appear in Type or ResutType.

ConvertTo accepts one arguments: an instance of the external type.

Example:

Service design:

var Bottle = Type("bottle", func() {
    Description("A bottle")
    ConvertTo(models.Bottle{})
    // The "rating" attribute is matched to the external
    // typ "Rating" field.
    Attribute("rating", Int)
    Attribute("name", String, func() {
        // The "name" attribute is matched to the external
        // type "MyName" field.
        Meta("struct.field.external", "MyName")
    })
    Attribute("vineyard", String, func() {
        // The "vineyard" attribute is not converted.
        Meta("struct.field.external", "-")
    })
})

External (i.e. non design) package:

package model

type Bottle struct {
    Rating int
    // Mapped field
    MyName string
    // Additional fields are OK
    Description string
}
func Cookie(name string, args ...interface{})

Cookie identifies a HTTP cookie. When used within a Response the Cookie DSL also makes it possible to define the cookie attributes.

Cookie must appear in the API HTTP expression (to define request cookies common to all the API endpoints), a service HTTP expression (to define request cookies common to all the service endpoints) a specific method HTTP expression (to define request cookies) or a Response expression (to define the response cookies).

Cookie accepts the same arguments as the Attribute function. The cookie name may define a mapping between the attribute name and the cookie name. The mapping syntax is "name of attribute:name of cookie".

Example:

var _ = Service("account", func() {
    Method("create", func() {
        Payload(func() {
            Attribute("session", String, "ID of current session")
        })
        Result(Account)
        HTTP(func() {
            // Initialize payload's "session" attribute with the value of
            // the SID cookie after validating that's it's a valid GUID.
            Cookie("session:SID", String, func() {
                Format(FormatGUID)
            })
            Response(StatusCreated, func() {
                // Write the value of the result "session" attribute to
                // the cookie named "SID" and initialize the cookie
                // "max-age", "domain", "path", "secure" and "http-only"
                // attributes. When reading the cookie value client
                // side validate that's it is a GUID.
                Cookie("session:SID", String, func() {
                    Format(FormatGUID)      // Cookie value validations
                })
                CookieMaxAge(3600)          // Cookie attributes
                CookieDomain("goa.design")
                CookiePath("/session")
                CookieSecure()
                CookieHTTPOnly()
            })
        })
    })
})

func CookieDomain

func CookieDomain(d string)

CookieDomain defines the "domain" attribute of a HTTP response cookie.

CookieDomain must appear in a Cookie expression.

CookieDomain accepts one argument which is the path value.

Example:

var _ = Service("account", func() {
    Method("create", func() {
        Result(Account)
        HTTP(func() {
            Response(StatusCreated, func() {
                Cookie("session:SID", String)
                CookieDomain("goa.design")
            })
        })
    })
})

func CookieHTTPOnly

func CookieHTTPOnly()

CookieHTTPOnly initializes the "http-only" attribute of a HTTP response cookie with "HttpOnly".

CookieHTTPOnly must appear in a Cookie expression.

Example:

var _ = Service("account", func() {
    Method("create", func() {
        Result(Account)
        HTTP(func() {
            Response(StatusCreated, func() {
                Cookie("session:SID", String)
                CookieHTTPOnly()
            })
        })
    })
})

func CookieMaxAge

func CookieMaxAge(n int)

CookieMaxAge defines the "max-age" attribute of a HTTP response cookie.

CookieMaxAge must appear in a Cookie expression.

CookieMaxAge accepts one argument which is the max-age value.

Example:

var _ = Service("account", func() {
    Method("create", func() {
        Result(Account)
        HTTP(func() {
            Response(StatusCreated, func() {
                Cookie("session:SID", String)
                CookieMaxAge(3600)
            })
        })
    })
})

func CookiePath

func CookiePath(p string)

CookiePath defines the "path" attribute of a HTTP response cookie.

CookiePath must appear in a Cookie expression.

CookiePath accepts one argument which is the path value.

Example:

var _ = Service("account", func() {
    Method("create", func() {
        Result(Account)
        HTTP(func() {
            Response(StatusCreated, func() {
                Cookie("session:SID", String)
                CookiePath("/session")
            })
        })
    })
})

func CookieSecure

func CookieSecure()

CookieSecure initializes the "secute" attribute of a HTTP response cookie with "Secure".

CookieSecure must appear in a Cookie expression.

Example:

var _ = Service("account", func() {
    Method("create", func() {
        Result(Account)
        HTTP(func() {
            Response(StatusCreated, func() {
                Cookie("session:SID", String)
                CookieSecure()
            })
        })
    })
})

func CreateFrom

func CreateFrom(obj interface{})

CreateFrom specifies an external type that instances of the generated struct can be initialized from. The generated struct is equipped with a method that initializes its fields from an instance of the external type. The default algorithm used to match the external type fields to the design attributes is as follows:

  1. Look for an attribute with the same name as the field
  2. Look for an attribute with the same name as the field but with the first letter being lowercase
  3. Look for an attribute with a name corresponding to the snake_case version of the field name

This algorithm does not apply if the attribute is equipped with the "struct.field.external" meta. In this case the matching is done by looking up the field with a name corresponding to the value of the meta. If the value of the meta is "-" the attribute isn't matched and no conversion code is generated for it. In all other cases it is an error if no match is found or if the matching field type does not correspond to the attribute type.

The following limitations apply on the external Go struct field types recursively:

  • struct fields must use pointers
  • pointers on slices or on maps are not supported

CreateFrom must appear in Type or ResultType.

CreateFrom accepts one arguments: an instance of the external type.

Example:

Service design:

var Bottle = Type("bottle", func() {
    Description("A bottle")
    CreateFrom(models.Bottle{})
    Attribute("rating", Int)
    Attribute("name", String, func() {
        // The "name" attribute is matched to the external
        // type "MyName" field.
        Meta("struct.field.external", "MyName")
    })
    Attribute("vineyard", String, func() {
        // The "vineyard" attribute is not initialized by the
        // generated constructor method.
        Meta("struct.field.external", "-")
    })
})

External (i.e. non design) package:

package model

type Bottle struct {
    Rating int
    // Mapped field
    MyName string
    // Additional fields are OK
    Description string
}

func DELETE

func DELETE(path string) *expr.RouteExpr

DELETE creates a route using the DELETE HTTP method. See GET.

func Default

func Default(def interface{})

Default sets the default value for an attribute.

Default must appear in an Attribute DSL.

Default takes one parameter: the default value.

func Description

func Description(d string)

Description sets the expression description.

Description may appear in API, Docs, Type or Attribute. Description may also appear in Response and Files.

Description accepts one arguments: the description string.

Example:

API("adder", func() {
    Description("Adder API")
})

func Docs

func Docs(fn func())

Docs provides external documentation URLs. It is used by the generated OpenAPI specification.

Docs must appear in an API, Service, Method or Attribute expr.

Docs takes a single argument which is the defining DSL.

Example:

var _ = API("cellar", func() {
    Docs(func() {
        Description("Additional documentation")
        URL("https://goa.design")
    })
})

func Elem

func Elem(fn func())

Elem makes it possible to specify validations for array and map values.

Example:

Attribute("array", ArrayOf(Int), func() {
    Elem(func() {
        Enum(1, 2, 3, 4, 5) // list possible values for array elements
    })
})

Attribute("map", MapOf(String, Int), func() {
    Elem(func() {
        Minimum(1)
        Maximum(100)
    })
})

func Email

func Email(email string)

Email sets the contact email.

Email must appear in a Contact expression.

Email takes a single argument which is the email address.

Example:

var _ = API("divider", func() {
    Contact(func() {
        Email("support@goa.design")
    })
})

func Enum

func Enum(vals ...interface{})

Enum adds a "enum" validation to the attribute. See http://json-schema.org/latest/json-schema-validation.html#anchor76.

Example:

Attribute("string", String, func() {
    Enum("this", "that", "and this")
})

Attribute("array", ArrayOf(Int), func() {
    Elem(func() {
        Enum(1, 2, 3, 4, 5)  // Sets possible values for array elements
    })
})

func Error

func Error(name string, args ...interface{})

Error describes a method error return value. The description includes a unique name (in the scope of the method), an optional type, description and DSL that further describes the type. If no type is specified then the built-in ErrorResult type is used. The DSL syntax is identical to the Attribute DSL.

Error must appear in the Service (to define error responses that apply to all the service methods) or Method expressions.

See Attribute for details on the Error arguments.

Example:

var _ = Service("divider", func() {
    Error("invalid_arguments") // Uses type ErrorResult

    // Method which uses the default type for its response.
    Method("divide", func() {
        Payload(DivideRequest)
        Error("div_by_zero", DivByZero, "Division by zero")
    })
})

func Example

func Example(args ...interface{})

Example provides an example value for a type, a parameter, a header or any attribute. Example supports two syntaxes: one syntax accepts two arguments where the first argument is a summary describing the example and the second a value provided directly or via a DSL which may also specify a long description. The second syntax accepts a single argument and is equivalent to using the first syntax where the summary is the string "default". When using a DSL the Value function can be used to provide the example value.

If no example is explicitly provided in an attribute expression then a random example is generated unless the "swagger:example" meta is set to "false". See Meta.

Example must appear in a Attributes, Attribute, Params, Param, Headers or Header DSL.

Example takes one or two arguments: an optional summary and the example value or defining DSL.

Examples:

Params(func() {
    Param("ZipCode:zip-code", String, "Zip code filter", func() {
        Example("Santa Barbara", "93111")
        Example("93117") // same as Example("default", "93117")
    })
})

Attributes(func() {
    Attribute("ID", Int64, "ID is the unique bottle identifier")
    Example("The first bottle", func() {
        Description("This bottle has an ID set to 1")
        Value(Val{"ID": 1})
    })
    Example("Another bottle", func() {
        Description("This bottle has an ID set to 5")
        Value(Val{"ID": 5})
    })
})

func Extend

func Extend(t expr.DataType)

Extend adds the parameter type attributes to the type using Extend. The parameter type must be an object.

Extend may be used in Type or ResultType. Extend accepts a single argument: the type or result type containing the attributes to be copied.

Example:

var CreateBottlePayload = Type("CreateBottlePayload", func() {
   Attribute("name", String, func() {
      MinLength(3)
   })
   Attribute("vintage", Int32, func() {
      Minimum(1970)
   })
})

var UpdateBottlePayload = Type("UpatePayload", func() {
    Attribute("id", String, "ID of bottle to update")
    Extend(CreateBottlePayload) // Adds attributes "name" and "vintage"
})

func Fault

func Fault()

Fault qualifies an error type as describing errors due to a server-side fault.

Fault must appear in a Error expression.

Fault takes no argument.

Example:

var _ = Service("divider", func() {
     Error("internal_error", func() {
             Fault()
     })
})

func Field

func Field(tag interface{}, name string, args ...interface{})

Field is syntactic sugar to define an attribute with the "rpc:tag" meta set with the value of the first argument.

Field must appear wherever Attribute can.

Field takes the same arguments as Attribute with the addition of the tag value as first argument.

Example:

Field(1, "ID", String, func() {
    Pattern("[0-9]+")
})

func Files

func Files(path, filename string, fns ...func())

Files defines a endpoint that serves static assets via HTTP. 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:

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

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

Files("/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".

Files must appear in Service.

Files accepts 2 arguments and an optional DSL. The first argument is the request path which may use a wildcard starting with {* and ending with }. The second argument is the path on disk to the files being served. The file path may be absolute or relative to the current path of the process. The DSL allows specifying a description and documentation as well.

Example:

var _ = Service("bottle", func() {
    Files("/index.html", "/www/data/index.html", func() {
        Description("Serve home page.")
        Docs(func() {
            Description("Additional documentation")
            URL("https://goa.design")
        })
    })
    Files("/static/{*path}", "/www/data/static", func() {
        Description("Serve static content.")
    })
})

func Format

func Format(f expr.ValidationFormat)

Format adds a "format" validation to the attribute. See http://json-schema.org/latest/json-schema-validation.html#anchor104. The formats supported by goa are:

FormatDate: RFC3339 date

FormatDateTime: RFC3339 date time

FormatUUID: RFC4122 uuid

FormatEmail: RFC5322 email address

FormatHostname: RFC1035 internet host name

FormatIPv4, FormatIPv6, FormatIP: RFC2373 IPv4, IPv6 address or either

FormatURI: RFC3986 URI

FormatMAC: IEEE 802 MAC-48, EUI-48 or EUI-64 MAC address

FormatCIDR: RFC4632 or RFC4291 CIDR notation IP address

FormatRegexp: RE2 regular expression

FormatJSON: JSON text

FormatRFC1123: RFC1123 date time

Example:

Attribute("created_at", String, func() {
    Format(FormatDateTime)
})

func GET

func GET(path string) *expr.RouteExpr

GET defines a route using the GET HTTP method. The route may use wildcards to define path parameters. Wildcards start with '{' or with '{*' and end with '}'. They must appear after a '/'.

A wildcard that starts with '{' matches a section of the path (the value in between two slashes).

A wildcard that starts with '{*' matches the rest of the path. Such wildcards must terminate the path.

GET must appear in a method HTTP function.

GET accepts one argument which is the request path.

Example:

var _ = Service("Manager", func() {
    Method("GetAccount", func() {
        Payload(GetAccount)
        Result(Account)
        HTTP(func() {
            GET("/{accountID}/details")
            GET("/{*accountPath}")
        })
    })
})

func GRPC

func GRPC(fn func())

GRPC defines gRPC transport specific properties on an API, a service, or a single method. The function maps the request and response types to gRPC properties such as request and response messages.

As a special case GRPC may be used to define the response generated for invalid requests and internal errors (errors returned by the service methods that don't match any of the error responses defined in the design). This is the only use of GRPC allowed in the API expression.

The functions that appear in GRPC such as Message or Response may take advantage of the request or response types (depending on whether they appear when describing the gRPC request or response). The properties of the message attributes inherit the properties of the attributes with the same names that appear in the request or response types. The functions may also define new attributes or override the existing request or response type attributes.

GRPC must appear in an API, a Service, or a Method expression.

GRPC accepts a single argument which is the defining DSL function.

Example:

var CreatePayload = Type("CreatePayload", func() {
    Field(1, "name", String, "Name of account")
    TokenField(2, "token", String, "JWT token for authentication")
})

var CreateResult = ResultType("application/vnd.create", func() {
    Attributes(func() {
        Field(1, "name", String, "Name of the created resource")
        Field(2, "href", String, "Href of the created resource")
    })
})

Method("create", func() {
    Payload(CreatePayload)
    Result(CreateResult)
    Error("unauthenticated")

    GRPC(func() {              // gRPC endpoint to define gRPC service
        Message(func() {       // gRPC request message
            Attribute("token")
        })
        Response(CodeOK)     // gRPC success response
        Response("unauthenticated", CodeUnauthenticated) // gRPC error
    })
})
func HEAD(path string) *expr.RouteExpr

HEAD creates a route using the HEAD HTTP method. See GET.

func HTTP

func HTTP(fns ...func())

HTTP defines the HTTP transport specific properties of an API, a service or a single method. The function maps the method payload and result types to HTTP properties such as parameters (via path wildcards or query strings), request or response headers, request or response bodies as well as response status code. HTTP also defines HTTP specific properties such as the method endpoint URLs and HTTP methods.

The functions that appear in HTTP such as Header, Param or Body may take advantage of the method payload or result types (depending on whether they appear when describing the HTTP request or response). The properties of the header, parameter or body attributes inherit the properties of the attributes with the same names that appear in the method payload or result types.

HTTP must appear in an API, a Service, or a Method expression.

HTTP accepts an optional argument which is the defining DSL function.

Example:

var _ = API("calc", func() {
    HTTP(func() {
        Path("/api") // Prefix to HTTP path of all requests.
    })
})

Example:

var _ = Service("calculator", func() {
    Error("unauthorized")

    HTTP(func() {
        Path("/calc")      // Prefix to all request paths
        Error("unauthorized", StatusUnauthorized) // Define "unauthorized"
                           // error HTTP response status code.
        Parent("account")  // Parent service, used to prefix request
                           // paths.
        CanonicalMethod("show") // Method whose path is used to prefix
                                // the paths of child service.
    })

    Method("div", func() {
        Description("Divide two operands.")
        Payload(Operands)
        Error("div_by_zero")

        HTTP(func() {
            GET("/div/{left}/{right}") // Define HTTP route. The "left"
                                       // and "right" parameter properties
                                       // are inherited from the
                                       // corresponding Operands attributes.
            Param("integer:int")       // Load "integer" attribute of
                                       // Operands from "int" query string.
            Header("requestID:X-RequestId")  // Load "requestID" attribute
                                             // of Operands from
                                             // X-RequestId header
            Response(StatusOK)               // Use status 200 on success
            Error("div_by_zero", BadRequest) // Use status code 400 for
                                             // "div_by_zero" responses
        })
    })
})
func Header(name string, args ...interface{})

Header describes a single HTTP header or gRPC metadata header. The properties (description, type, validation etc.) of a header are inherited from the request or response type attribute with the same name by default.

Header must appear in the API HTTP expression (to define request headers common to all the API endpoints), a service HTTP expression (to define request headers common to all the service endpoints) a specific method HTTP expression (to define request headers) or a Response expression (to define the response headers). Header may also appear in a method GRPC expression (to define headers sent in message metadata), or in a Response expression (to define headers sent in result metadata). Finally Header may also appear in a Headers expression.

Header accepts the same arguments as the Attribute function. The header name may define a mapping between the attribute name and the HTTP header name when they differ. The mapping syntax is "name of attribute:name of header".

Example:

var _ = Service("account", func() {
    Method("create", func() {
        Payload(CreatePayload)
        Result(Account)
        HTTP(func() {
            Header("auth:Authorization", String, "Auth token", func() {
                Pattern("^Bearer [^ ]+$")
            })
            Response(StatusCreated, func() {
                Header("href") // Inherits description, type, validations
                               // etc. from Account href attribute
            })
        })
    })
})

func Headers

func Headers(args interface{})

Headers describes HTTP request/response or gRPC response headers. When used in a HTTP expression, it groups a set of Header expressions and makes it possible to list required headers using the Required function. When used in a GRPC response expression, it defines the headers to be sent in the response metadata.

To define HTTP headers, Headers must appear in an Service HTTP expression to define request headers common to all the service methods. Headers may also appear in a method, response or error HTTP expression to define the HTTP endpoint request and response headers.

To define gRPC response header metadata, Headers must appear in a GRPC response expression.

Headers accepts one argument which is a function listing the headers.

Example:

// HTTP headers

var _ = Service("cellar", func() {
    HTTP(func() {
        Headers(func() {
            Header("version:Api-Version", String, "API version", func() {
                Enum("1.0", "2.0")
            })
            Required("version")
        })
    })
})

// gRPC response header metadata

var CreateResult = ResultType("application/vnd.create", func() {
    Attributes(func() {
        Field(1, "name", String, "Name of the created resource")
        Field(2, "href", String, "Href of the created resource")
    })
})

Method("create", func() {
    Payload(CreatePayload)
    Result(CreateResult)
    GRPC(func() {
        Response(func() {
            Code(CodeOK)
            Headers(func() {
                Attribute("name") // "name" sent in the header metadata
            })
        })
    })
})

func Host

func Host(name string, fn func())

Host defines a server host. A single server may define multiple hosts. Each host lists the set of URIs that identify it.

The Host expression is leveraged by the example generator to produce the service and client commands. It is also consumed by the OpenAPI specification generator to initialize the server objects.

Host must appear in a Server expression.

Host takes two arguments: a name and a DSL function.

Example:

Server("calcsvc", func() {
    Host("development", func() {
        URI("http://localhost:80/calc")
        URI("grpc://localhost:8080")
    })
})

func ImplicitFlow

func ImplicitFlow(authorizationURL, refreshURL string)

ImplicitFlow defines an implicit OAuth2 flow as described in section 1.3.2 of RFC 6749.

ImplicitFlow must be used in OAuth2Security.

ImplicitFlow accepts two arguments: the authorization and refresh URLs.

func JWTSecurity

func JWTSecurity(name string, fn ...func()) *expr.SchemeExpr

JWTSecurity defines an HTTP security scheme where a JWT is passed in the request Authorization header as a bearer token to perform auth. This scheme supports defining scopes that endpoint may require to authorize the request. The scheme also supports specifying a token URL used to retrieve token values.

Since scopes are not compatible with the Swagger specification, the swagger generator inserts comments in the description of the different elements on which they are defined.

JWTSecurity is a top level DSL.

JWTSecurity takes a name as first argument and an optional DSL as second argument.

Example:

var JWT = JWTSecurity("jwt", func() {
    Scope("system:write", "Write to the system")
    Scope("system:read", "Read anything in there")
})

func Key

func Key(fn func())

Key makes it possible to specify validations for map keys.

Example:

Attribute("map", MapOf(String, Int), func() {
    Key(func() {
        Format(FormatDateTime) // map keys are timestamps
    })
})

func License

func License(fn func())

License sets the API license information.

License must appear in a API expression.

License takes a single argument which is the defining DSL.

Example:

var _ = API("divider", func() {
    License(func() {
        Name("MIT")
        URL("https://github.com/goadesign/goa/blob/master/LICENSE")
    })
})

func MapOf

func MapOf(k, v interface{}, fn ...func()) *expr.Map

MapOf creates a map from its key and element types.

MapOf may be used wherever types can. MapOf takes two arguments: the key and value types either by name of by reference.

Example:

var ReviewByID = MapOf(Int64, String, func() {
    Key(func() {
        Minimum(1)           // Validates keys of the map
    })
    Elem(func() {
        Pattern("[a-zA-Z]+") // Validates values of the map
    })
})

var Review = Type("Review", func() {
    Attribute("ratings", MapOf(Bottle, Int32), "Bottle ratings")
})

func MapParams

func MapParams(args ...interface{})

MapParams describes the query string parameters in a HTTP request.

MapParams must appear in a Method HTTP expression to map the query string parameters with the Method's Payload.

MapParams accepts one optional argument which specifes the Payload attribute to which the query string parameters must be mapped. This Payload attribute must be a map. If no argument is specified, the query string parameters are mapped with the entire Payload (the Payload must be a map).

Example:

 var _ = Service("account", func() {
     Method("index", func() {
         Payload(MapOf(String, Int))
         HTTP(func() {
             GET("/")
             MapParams()
         })
     })
})

var _ = Service("account", func() {
    Method("show", func() {
        Payload(func() {
            Attribute("p", MapOf(String, String))
            Attribute("id", String)
        })
        HTTP(func() {
            GET("/{id}")
            MapParams("p")
        })
    })
})

func MaxLength

func MaxLength(val int)

MaxLength adds a "maxItems" validation to the attribute. See http://json-schema.org/latest/json-schema-validation.html#anchor42.

Example:

Attribute("array", ArrayOf(String), func() {
    MaxLength(200)    // max array length
    Elem(func() {
        MaxLength(5)  // max length of each array element
    })
})

func Maximum

func Maximum(val interface{})

Maximum adds a "maximum" validation to the attribute. See http://json-schema.org/latest/json-schema-validation.html#anchor17.

Example:

Attribute("integer", Int, func() {
    Maximum(100)
})

func Message

func Message(fn func())

Message describes a gRPC request or response message.

Message must appear in a gRPC method expression to define the attributes that must appear in a request message or in a gRPC response expression to define the attributes that must appear in a response message. If Message is absent then the request message is built using the method payload expression and the response message is built using the method result expression.

Message accepts one argument of function type which lists the attributes that must be present in the message. For example, the Message function can be defined on the gRPC method expression listing the security attributes to appear in the request message instead of sending them in the gRPC metadata by default. The attributes listed in the function inherit the properties (description, type, meta, validations etc.) of the request or response type attributes with identical names.

Example:

var CreatePayload = Type("CreatePayload", func() {
    Field(1, "name", String, "Name of account")
    TokenField(2, "token", String, "JWT token for authentication")
})

var CreateResult = ResultType("application/vnd.create", func() {
    Attributes(func() {
        Field(1, "name", String, "Name of the created resource")
        Field(2, "href", String, "Href of the created resource")
    })
})

Method("create", func() {
    Payload(CreatePayload)
    Result(CreateResult)
    GRPC(func() {
        Message(func() {
            Attribute("token") // "token" sent in the request message
                               // along with "name"
        })
        Response(func() {
            Code(CodeOK)
            Message(func() {
                Attribute("name") // "name" sent in the response
                                  // message along with "href"
                Required("name")  // "name" is set to required
            })
        })
    })
})

If the method payload/result type is a primitive, array, or a map the request/response message by default contains one attribute with name "field", "rpc:tag" set to 1, and the type set to the type of the method payload/result. The function argument can also be used to set the message field name to something other than "field".

Example:

Method("add", func() {
    Payload(Operands)
    Result(Int)      // method Result is a primitive
    GRPC(func() {
        Response(CodeOK, func()
            Message(func() {
                Attribute("sum") // Response message has one field with
                                 // name "sum" instead of the default
                                 // "field"
            })
        })
    })
})

func Meta

func Meta(name string, value ...string)

Meta defines a set of key/value pairs that can be assigned to an object. Each value consists of a slice of strings so that multiple invocation of the Meta function on the same target using the same key builds up the slice.

Meta may appear in attributes, result types, endpoints, responses, services and API definitions.

While keys can have any value the following names have special meanings:

- "type:generate:force" forces the code generation for the type it is defined on. By default goa only generates types that are used explicitly by the service methods. The value is a slice of strings that lists the names of the services for which to generate the struct. The struct is generated for all services if left empty.

package design

var _ = Service("service1", func() { ... })
var _ = Service("service2", func() { ... })

var Unused = Type("Unused", func() {
    Attribute("name", String)
    Meta("type:generate:force", service1, service2)
})

- "struct:error:name" identifies the attribute of a result type used to select the returned error when multiple errors are defined on the same method. The value of the field corresponding to the attribute with the struct:error:name metadata is matched against the names of the method errors as defined in the design. This makes it possible to define distinct transport mappings for the various errors (for example to return different HTTP status codes). There must be one and exactly one attribute with the struct:error:name metadata defined on result types used to define error results.

var CustomErrorType = ResultType("application/vnd.goa.error", func() {
    Attributes(func() {
        Attribute("message", String, "Error returned.", func() {
            Meta("struct:error:name")
        })
        Attribute("occurred_at", String, "Time error occurred.", func() {
            Format(FormatDateTime)
        })
    })
})

var _ = Service("MyService", func() {
    Error("internal_error", CustomErrorType)
    Error("bad_request", CustomErrorType)
})

- "struct:field:name" overrides the Go struct field name generated by default by goa. Applicable to attributes only.

var MyType = Type("MyType", func() {
    Attribute("ssn", String, "User SSN", func() {
        Meta("struct:field:name", "SSN")
    })
})

- "struct:field:type" overrides the Go struct field type specified in the design, with one caveat; if the type would have been a pointer (such as its not Required) the new type will also be a pointer. Applicable to attributes only. The import path of the type should be passed in as the second parameter, if needed. If the default imported package name conflicts with another, you can override that as well with the third parameter.

var MyType = Type("BigOleMessage", func() {
    Attribute("type", String, "Type of big payload")
    Attribute("bigPayload", String, "Don't parse it if you don't have to",func() {
        Meta("struct:field:type","json.RawMessage","encoding/json")
     })
     Attribute("id", String, func() {
         Meta("struct:field:type","bison.ObjectId", "github.com/globalsign/mgo/bson", "bison")
     })
})

- "struct:tag:xxx" sets a generated Go struct field tag and overrides tags that goa would otherwise set. If the metadata value is a slice then the strings are joined with the space character as separator. Applicable to attributes only.

var MyType = Type("MyType", func() {
    Attribute("ssn", String, "User SSN", func() {
        Meta("struct:tag:json", "SSN,omitempty")
        Meta("struct:tag:xml", "SSN,omitempty")
    })
})

- "swagger:generate" specifies whether Swagger specification should be generated. Defaults to true. Applicable to services, methods and file servers.

var _ = Service("MyService", func() {
    Meta("swagger:generate", "false")
})

- "swagger:summary" sets the Swagger operation summary field. Applicable to methods.

var _ = Service("MyService", func() {
    Method("MyMethod", func() {
           Meta("swagger:summary", "Summary of MyMethod")
    })
})

- "swagger:example" specifies whether to generate random example. Defaults to true. Applicable to API (applies to all attributes) or individual attributes.

var _ = API("MyAPI", func() {
    Meta("swagger:example", "false")
})

- "swagger:tag:xxx" sets the Swagger object field tag xxx. Applicable to services and methods.

var _ = Service("MyService", func() {
    Method("MyMethod", func() {
        Meta("swagger:tag:Backend")
        Meta("swagger:tag:Backend:desc", "Description of Backend")
        Meta("swagger:tag:Backend:url", "http://example.com")
        Meta("swagger:tag:Backend:url:desc", "See more docs here")
        Meta("swagger:tag:Backend:extension:x-data", `{"foo":"bar"}`)
    })
})

- "swagger:extension:xxx" sets the Swagger extensions xxx. The value can be any valid JSON. Applicable to API (Swagger info and tag objects), Service (Swagger paths object), Method (Swagger path-item object), Route (Swagger operation object), Param (Swagger parameter object), Response (Swagger response object) and Security (Swagger security-scheme object). See https://github.com/OAI/OpenAPI-Specification/blob/master/guidelines/EXTENSIONS.md.

var _ = API("MyAPI", func() {
    Meta("swagger:extension:x-api", `{"foo":"bar"}`)
})

func Metadata

func Metadata(fn func())

Metadata defines a gRPC request metadata.

Metadata must appear in a gRPC endpoint expression to describe gRPC request metadata.

Security attributes in the method payload are automatically added to the request metadata unless specified explicitly in request message using Message function. All other attributes in method payload are added to the request message unless specified explicitly using Metadata (in which case will be added to the metadata).

Metadata takes one argument of function type which lists the attributes that must be set in the request metadata instead of the message. If Metadata is set in the gRPC endpoint expression, it inherits the attribute properties (description, type, meta, validations etc.) from the method payload.

Example:

var CreatePayload = Type("CreatePayload", func() {
    Field(1, "name", String, "Name of account")
    TokenField(2, "token", String, "JWT token for authentication")
})

var CreateResult = ResultType("application/vnd.create", func() {
    Attributes(func() {
        Field(1, "name", String, "Name of the created resource")
        Field(2, "href", String, "Href of the created resource")
    })
})

Method("create", func() {
    Payload(CreatePayload)
    Result(CreateResult)
    GRPC(func() {
        Metadata(func() {
            Attribute("name") // "name" sent in the request metadata
                              // along with "token"
        })
        Response(func() {
            Code(CodeOK)
        })
    })
})

func Method

func Method(name string, fn func())

Method defines a single service method.

Method must appear in a Service expression.

Method takes two arguments: the name of the method and the defining DSL.

Example:

Method("add", func() {
    Description("The add method returns the sum of A and B")
    Docs(func() {
        Description("Add docs")
        URL("http//adder.goa.design/docs/endpoints/add")
    })
    Payload(Operands)
    Result(Sum)
    Error(ErrInvalidOperands)
})

func MinLength

func MinLength(val int)

MinLength adds a "minItems" validation to the attribute. See http://json-schema.org/latest/json-schema-validation.html#anchor45.

Example:

Attribute("map", MapOf(String, String), func() {
    MinLength(10)      // min key-values in map
    Key(func() {
        MinLength(1)   // min length of map key
    })
    Elem(func() {
        MinLength(5)   // min length of map elements
    })
})

func Minimum

func Minimum(val interface{})

Minimum adds a "minimum" validation to the attribute. See http://json-schema.org/latest/json-schema-validation.html#anchor21.

Example:

Attribute("integer", Int, func() {
    Minimum(100)
})

func MultipartRequest

func MultipartRequest()

MultipartRequest indicates that HTTP requests made to the method use MIME multipart encoding as defined in RFC 2046.

MultipartRequest must appear in a HTTP endpoint expression.

goa generates a custom encoder that writes the payload for requests made to HTTP endpoints that use MultipartRequest. The generated encoder accept a user provided function that does the actual mapping of the payload to the multipart content. The user provided function accepts a multipart writer and a reference to the payload and is responsible for encoding the payload. goa also generates a custom decoder that reads back the multipart content into the payload struct. The generated decoder also accepts a user provided function that takes a multipart reader and a reference to the payload struct as parameter. The user provided decoder is responsible for decoding the multipart content into the payload. The example command generates a default implementation for the user decoder and encoder.

func Name

func Name(name string)

Name sets the contact or license name.

Name must appear in a Contact or License expression.

Name takes a single argument which is the contact or license name.

Example:

var _ = API("divider", func() {
    License(func() {
        Name("MIT")
        URL("https://github.com/goadesign/goa/blob/master/LICENSE")
    })
})

func NoSecurity

func NoSecurity()

NoSecurity removes the need for an endpoint to perform authorization.

NoSecurity must appear in Method.

func OAuth2Security

func OAuth2Security(name string, fn ...func()) *expr.SchemeExpr

OAuth2Security defines an OAuth2 security scheme. The DSL provided as second argument defines the specific flows supported by the scheme. The supported flow types are ImplicitFlow, PasswordFlow, ClientCredentialsFlow, and AuthorizationCodeFlow. The DSL also defines the scopes that may be associated with the incoming request tokens.

OAuth2Security is a top level DSL.

OAuth2Security takes a name as first argument and a DSL as second argument.

Example:

var OAuth2 = OAuth2Security("googauth", func() {
    ImplicitFlow("/authorization")

    Scope("api:write", "Write acess")
    Scope("api:read", "Read access")
})

func OPTIONS

func OPTIONS(path string) *expr.RouteExpr

OPTIONS creates a route using the OPTIONS HTTP method. See GET.

func PATCH

func PATCH(path string) *expr.RouteExpr

PATCH creates a route using the PATCH HTTP method. See GET.

func POST

func POST(path string) *expr.RouteExpr

POST creates a route using the POST HTTP method. See GET.

func PUT

func PUT(path string) *expr.RouteExpr

PUT creates a route using the PUT HTTP method. See GET.

func Param

func Param(name string, args ...interface{})

Param describes a single HTTP request path or query string parameter.

Param must appear in the API HTTP expression (to define request parameters common to all the API endpoints), a service HTTP expression to define common parameters to all the service methods or a specific method HTTP expression. Param may also appear in a Params expression.

Param accepts the same arguments as the Function Attribute.

The name may be of the form "name of attribute:name of parameter" to define a mapping between the attribute and parameter names when they differ.

Example:

var ShowPayload = Type("ShowPayload", func() {
    Attribute("id", UInt64, "Account ID")
    Attribute("version", String, "Version", func() {
        Enum("1.0", "2.0")
    })
})

var _ = Service("account", func() {
    HTTP(func() {
        Path("/{parentID}")
        Param("parentID", UInt64, "ID of parent account")
    })
    Method("show", func() {  // default response type.
        Payload(ShowPayload)
        Result(AccountResult)
        HTTP(func() {
            GET("/{id}")           // HTTP request uses ShowPayload "id"
                                   // attribute to define "id" parameter.
            Params(func() {        // Params makes it possible to group
                                   // Param expressions.
                Param("version:v") // "version" of ShowPayload to define
                                   // path and query string parameters.
                                   // Query string "v" maps to attribute
                                   // "version" of ShowPayload.
            })
        })
    })
})

func Params

func Params(args interface{})

Params groups a set of Param expressions. It makes it possible to list required parameters using the Required function.

Params must appear in an API or Service HTTP expression to define the API or service base path and query string parameters. Params may also appear in an method HTTP expression to define the HTTP endpoint path and query string parameters.

Params accepts one argument which is a function listing the parameters.

Example:

var _ = API("cellar", func() {
    HTTP(func() {
        Params(func() {
            Param("version", String, "API version", func() {
                Enum("1.0", "2.0")
            })
            Required("version")
        })
    })
})

func Parent

func Parent(name string)

Parent sets the name of the parent service. The parent service canonical method path is used as prefix for all the service HTTP endpoint paths.

Attributes of the parent method payload that map to parent path parameters are automatically merged into the child method payload type if not already defined.

Parent must appear in the HTTP expresssion of a Service.

Parent accepts one argument: the name of the parent service.

func Password

func Password(name string, args ...interface{})

Password defines the attribute used to provide the password to an endpoint secured with basic authentication. The parameters and usage of Password are the same as the goa DSL Attribute function.

The generated code produced by goa uses the value of the corresponding payload field to compute the basic authentication Authorization header value.

Password must appear in Payload or Type.

Example:

Method("login", func() {
    Security(Basic)
    Payload(func() {
        Username("user", String)
        Password("pass", String)
    })
    HTTP(func() {
        // The "Authorization" header is defined implicitly.
        POST("/login")
    })
})

func PasswordField

func PasswordField(tag interface{}, name string, args ...interface{})

PasswordField is syntactic sugar to define a password attribute with the "rpc:tag" meta set with the value of the first argument.

PasswordField takes the same arguments as Password with the addition of the tag value as the first argument.

func PasswordFlow

func PasswordFlow(tokenURL, refreshURL string)

PasswordFlow defines an Resource Owner Password Credentials OAuth2 flow as described in section 1.3.3 of RFC 6749.

PasswordFlow must be used in OAuth2Security.

PasswordFlow accepts two arguments: the token and refresh URLs.

func Path

func Path(val string)

Path defines an API or service base path, i.e. a common HTTP path prefix to all the API or service methods. The path may define wildcards (see GET for a description of the wildcard syntax). The corresponding parameters must be described using Params. Multiple base paths may be defined for services.

GET("/") does not add a trailing slash when the base path is defined by Path. For example, when Path('foo') is defined, the path generated by GET("/") will be '/foo'. As a special case, if you want to generate a path with a trailing slash, you can use GET("/./") to generate a path such as '/foo/'.

Path must appear in a API HTTP expression or a Service HTTP expression.

Path accepts one argument: the HTTP path prefix.

func Pattern

func Pattern(p string)

Pattern adds a "pattern" validation to the attribute. See http://json-schema.org/latest/json-schema-validation.html#anchor33.

Example:

Attribute("pattern", String, func() {
    Pattern("^[A-Z].*[0-9]$")
})

func Payload

func Payload(val interface{}, args ...interface{})

Payload defines the data type of an method input. Payload also makes the input required.

Payload must appear in a Method expression.

Payload takes one to three arguments. The first argument is either a type or a DSL function. If the first argument is a type then an optional description may be passed as second argument. Finally a DSL may be passed as last argument that further specializes the type by providing additional validations (e.g. list of required attributes)

The valid usage for Payload are thus:

Payload(Type)

Payload(func())

Payload(Type, "description")

Payload(Type, func())

Payload(Type, "description", func())

Examples:

Method("upper"), func() {
    // Use primitive type.
    Payload(String)
}

Method("upper"), func() {
    // Use primitive type.and description
    Payload(String, "string to convert to uppercase")
}

Method("upper"), func() {
    // Use primitive type, description and validations
    Payload(String, "string to convert to uppercase", func() {
        Pattern("^[a-z]")
    })
}

Method("add", func() {
    // Define payload data structure inline
    Payload(func() {
        Description("Left and right operands to add")
        Attribute("left", Int32, "Left operand")
        Attribute("right", Int32, "Left operand")
        Required("left", "right")
    })
})

Method("add", func() {
    // Define payload type by reference to user type
    Payload(Operands)
})

Method("divide", func() {
    // Specify additional required attributes on user type.
    Payload(Operands, func() {
        Required("left", "right")
    })
})

func Produces

func Produces(args ...string)

Produces adds a MIME type to the list of MIME types the APIs supports when writing responses. While the DSL supports any MIME type, the code generator only knows to generate the code for "application/json", "application/xml" and "application/gob". The service code must provide the encoders for other MIME types.

Produces must appear in the HTTP expression of API.

Produces accepts one or more strings corresponding to the MIME types.

Example:

API("cellar", func() {
    // ...
    HTTP(func() {
        Produces("application/json", "application/xml")
        // ...
    })
})

func Reference

func Reference(t expr.DataType)

Reference sets a type or result type reference. The value itself can be a type or a result type. The reference type attributes define the default properties for attributes with the same name in the type using the reference.

Reference may be used in Type or ResultType, it may appear multiple times in which case attributes are looked up in each reference in order of appearance in the DSL.

Reference accepts a single argument: the type or result type containing the attributes that define the default properties of the attributes of the type or result type that uses Reference.

Example:

var Bottle = Type("bottle", func() {
	Attribute("name", String, func() {
		MinLength(3)
	})
	Attribute("vintage", Int32, func() {
		Minimum(1970)
	})
	Attribute("somethingelse", String)
})

var BottleResult = ResultType("vnd.goa.bottle", func() {
	Reference(Bottle)
	Attributes(func() {
		Attribute("id", UInt64, "ID is the bottle identifier")

		// The type and validation of "name" and "vintage" are
		// inherited from the Bottle type "name" and "vintage"
		// attributes.
		Attribute("name")
		Attribute("vintage")
	})
})

func Required

func Required(names ...string)

Required adds a "required" validation to the attribute. See http://json-schema.org/latest/json-schema-validation.html#anchor61.

Example:

var _ = Type("MyType", func() {
    Attribute("string", String)
    Attribute("int", Integer)
    Required("string", "int")
})

func Response

func Response(val interface{}, args ...interface{})

Response describes a HTTP or a gRPC response. Response describes both success and error responses. When describing an error response the first argument is the name of the error.

While a service method may only define a single result type, Response may appear multiple times to define multiple success HTTP responses. In this case the Tag expression makes it possible to identify a result type attribute and a corresponding string value used to select the proper success response (each success response is associated with a different tag value). gRPC responses may only define one success response.

Response may appear in a service expression to define error responses common to all the service methods. Response may also appear in a method expression to define both success and error responses specific to the method. In both cases Response must appear in the transport specific DSL (i.e. in a HTTP or gRPC subexpression).

Response accepts one to three arguments. Success response accepts a status code as first argument. If the first argument is a status code then a function may be given as the second argument. This function may provide a description and describes how to map the result type attributes to transport specific constructs (e.g. HTTP headers and body, gRPC metadata and message).

The valid invocations for successful response are thus:

* Response(status)

* Response(func)

* Response(status, func)

Error responses additionally accept the name of the error as first or second argument.

* Response(error_name, status)

* Response(error_name, func)

* Response(error_name, status, func)

* Response(status, error_name)

* Response(status, error_name, func)

By default (i.e. if Response only defines a status code) then:

  • success HTTP responses use code 200 (OK) and error HTTP responses use code 400 (BadRequest)
  • success gRPC responses use code 0 (OK) and error gRPC response use code 2 (Unknown)
  • The result type attributes are all mapped to the HTTP response body or gRPC response message.

Example:

Method("create", func() {
    Payload(CreatePayload)
    Result(CreateResult)
    Error("an_error")

    HTTP(func() {
        Response(StatusAccepted, func() { // HTTP status code set using argument
            Description("Response used for async creations")
            Tag("outcome", "accepted") // Tag identifies a result type attribute and corresponding
                                       // value for this response to be selected.
            Header("taskHref")         // map "taskHref" attribute to header, all others to body
        })

        Response(StatusCreated, func () {
            Tag("outcome", "created")  // CreateResult type to describe body
        })

        Response(func() {
            Description("Response used when item already exists")
            Code(StatusNoContent) // HTTP status code set using Code
            Body(Empty)           // Override method result type
        })

        Response("an_error", StatusConflict) // Override default of 400
    })

    GRPC(func() {
        Response(CodeOK, func() {
            Metadata("taskHref") // map "taskHref" attribute to metadata, all others to message
        })

        Response("an_error", CodeInternal, func() {
            Description("Error returned for internal errors")
        })
    })
})

func Result

func Result(val interface{}, args ...interface{})

Result defines the data type of a method output.

Result must appear in a Method expression.

Result takes one to three arguments. The first argument is either a type or a DSL function. If the first argument is a type then an optional description may be passed as second argument. Finally a DSL may be passed as last argument that further specializes the type by providing additional validations (e.g. list of required attributes) The DSL may also specify a view when the first argument is a result type corresponding to the view rendered by this method. If no view is specified then the generated code defines response methods for all views.

The valid syntax for Result is thus:

Result(Type)

Result(func())

Result(Type, "description")

Result(Type, func())

Result(Type, "description", func())

Examples:

// Define result using primitive type
Method("add", func() {
    Result(Int32)
})

// Define result using primitive type and description
Method("add", func() {
    Result(Int32, "Resulting sum")
})

// Define result using primitive type, description and validations.
Method("add", func() {
    Result(Int32, "Resulting sum", func() {
        Minimum(0)
    })
})

// Define result using object defined inline
Method("add", func() {
    Result(func() {
        Description("Result defines a single field which is the sum.")
        Attribute("value", Int32, "Resulting sum")
        Required("value")
    })
})

// Define result type using user type
Method("add", func() {
    Result(Sum)
})

// Specify view and required attributes on result type
Method("add", func() {
    Result(Sum, func() {
        View("default")
        Required("value")
    })
})

func ResultType

func ResultType(identifier string, args ...interface{}) *expr.ResultTypeExpr

ResultType defines a result type used to describe a method response.

Result types have a unique identifier as described in RFC 6838. The identifier defines the default value for the Content-Type header of HTTP responses. Result types may also define a type name used to override the default Go type name generated from the identifier.

The result type expression includes a listing of all the response attributes. Views specify which of the attributes are actually rendered so that the same result type expression may represent multiple rendering of a given response.

All result types have a view named "default". This view is used to render the result type in responses when no other view is specified. If the default view is not explicitly described in the DSL then one is created that lists all the result type attributes.

Note: it is not required to use a ResultType to describe the type of a method result, Type can also be used and is preferred if there is no need to define multiple views.

ResultType is a top level DSL.

ResultType accepts two or three arguments: the result type identifier, an optional type name and the defining DSL.

Example:

var BottleMT = ResultType("application/vnd.goa.example.bottle", "BottleResult", func() {
    Description("A bottle of wine")
    ContentType("application/json") // Override Content-Type header

    Attributes(func() {
        Attribute("id", Int, "ID of bottle")
        Attribute("href", String, "API href of bottle")
        Attribute("account", Account, "Owner account")
        Attribute("origin", Origin, "Details on wine origin")
        Required("id", "href")
    })

    View("default", func() {        // Explicitly define default view
        Attribute("id")
        Attribute("href")
    })

    View("extended", func() {       // Define "extended" view
        Attribute("id")
        Attribute("href")
        Attribute("account")
        Attribute("origin")
    })
 })

func Scope

func Scope(name string, desc ...string)

Scope has two uses: in JWTSecurity or OAuth2Security it defines a scope supported by the scheme. In Security it lists required scopes.

Scope must appear in Security, BasicSecurity, APIKeySecurity, JWTSecurity or OAuth2Security.

Scope accepts one or two arguments: the first argument is the scope name and when used in JWTSecurity or OAuth2Security the second argument is a description.

Example:

var JWT = JWTSecurity("JWT", func() {
    Scope("api:read", "Read access") // Defines a scope
    Scope("api:write", "Write access")
})

Method("secured", func() {
    Security(JWT, func() {
        Scope("api:read") // Required scope for auth
    })
})

func Security

func Security(args ...interface{})

Security defines authentication requirements to access a service or a service method.

The requirement refers to one or more OAuth2Security, BasicAuthSecurity, APIKeySecurity or JWTSecurity security scheme. If the schemes include a OAuth2Security or JWTSecurity scheme then required scopes may be listed by name in the Security DSL. All the listed schemes must be validated by the client for the request to be authorized. Security may appear multiple times in the same scope in which case the client may validate any one of the requirements for the request to be authorized.

Security must appear in a Service or Method expression.

Security accepts an arbitrary number of security schemes as argument specified by name or by reference and an optional DSL function as last argument.

Examples:

var _ = Service("calculator", func() {
    // Override default API security requirements. Accept either basic
    // auth or OAuth2 access token with "api:read" scope.
    Security(BasicAuth)
    Security("oauth2", func() {
        Scope("api:read")
    })

    Method("add", func() {
        Description("Add two operands")

        // Override default service security requirements. Require
        // both basic auth and OAuth2 access token with "api:write"
        // scope.
        Security(BasicAuth, "oauth2", func() {
            Scope("api:write")
        })

        Payload(Operands)
        Error(ErrBadRequest, ErrorResult)
    })

    Method("health-check", func() {
        Description("Check health")

        // Remove need for authorization for this endpoint.
        NoSecurity()

        Payload(Operands)
        Error(ErrBadRequest, ErrorResult)
    })
})

func Server

func Server(name string, fn ...func()) *expr.ServerExpr

Server describes a single process listening for client requests. The DSL defines the set of services that the server exposes as well as host details. Not defining a server in a design has the same effect as defining a single server that exposes all of the services defined in the design in a single host listening on "locahost" and using port 80 for HTTP endpoints and 8080 for GRPC endpoints.

The Server expression is leveraged by the example generator to produce the service and client commands. It is also consumed by the OpenAPI specification generator. There is one specification generated per server. The first URI of the first host is used to set the OpenAPI v2 specification 'host' and 'basePath' values.

Server must appear in a API expression.

Server takes two arguments: the name of the server and the defining DSL.

Example:

 var _ = API("calc", func() {
     Server("calcsvr", func() {
         Description("calcsvr hosts the Calculator Service.")

         // List the services hosted by this server.
         Services("calc")

         // List the Hosts and their transport URLs.
         Host("production", func() {
            Description("Production host.")
            // URIs can be parameterized using {param} notation.
            URI("https://{version}.goa.design/calc")
            URI("grpcs://{version}.goa.design")

            // Variable describes a URI variable.
            Variable("version", String, "API version", func() {
                // URI parameters must have a default value and/or an
                // enum validation.
                Default("v1")
            })
        })

        Host("development", func() {
            Description("Development hosts.")
            // Transport specific URLs, supported schemes are:
            // 'http', 'https', 'grpc' and 'grpcs' with the respective default
            // ports: 80, 443, 8080, 8443.
            URI("http://localhost:80/calc")
            URI("grpc://localhost:8080")
        })
    })
})

func Service

func Service(name string, fn func()) *expr.ServiceExpr

Service defines a group of remotely accessible methods that are hosted together. The service DSL makes it possible to define the methods, their input and output as well as the errors they may return independently of the underlying transport (HTTP or gRPC). The transport specific DSLs defined by the HTTP and GRPC functions define the mapping between the input, output and error type attributes and the transport data (e.g. HTTP headers, HTTP bodies or gRPC messages).

The Service expression is leveraged by the code generators to define the business layer service interface, the endpoint layer as well as the transport layer including input validation, marshalling and unmarshalling. It also affects the generated OpenAPI specification.

Service is as a top level expression.

Service accepts two arguments: the name of the service - which must be unique in the design package - and its defining DSL.

Example:

var _ = Service("divider", func() {
    Title("divider service") // optional

    Error("Unauthorized") // error that apply to all the service methods
    HTTP(func() {         // HTTP mapping for error responses
        // Use HTTP status 401 for 'Unauthorized' errors.
        Response("Unauthorized", StatusUnauthorized)
    })

    Method("divide", func() {   // Defines a service method.
        Description("Divide divides two value.") // optional
        Payload(DividePayload)                   // input type
        Result(Float64)                          // output type
        Error("DivisionByZero")                  // method specific error
        // No HTTP mapping for "DivisionByZero" means default of status
        // 400 and error struct serialized in HTTP response body.

        HTTP(func() {      // Defines HTTP transport mapping.
            GET("/div")    // HTTP verb and path
            Param("a")     // query string parameter
            Param("b")     // 'a' and 'b' are attributes of DividePayload.
            // No 'Response' DSL means default of status 200 and result
            // marshaled in HTTP response body.
        })
    })
})

func Services

func Services(svcs ...string)

Services sets the list of services implemented by a server.

Services must appear in a Server expression.

Services takes one or more strings as argument corresponding to service names.

Example:

var _ = Server("calcsvr", func() {
    Services("calc", "adder")
    Services("other") // Multiple calls to Services are OK
})

func SkipRequestBodyEncodeDecode

func SkipRequestBodyEncodeDecode()

SkipRequestBodyEncodeDecode prevents Goa from generating the request encoding (client) and decoding (server) code. Instead the service method gets direct access to the HTTP body reader. The client method provides a reader from which to stream the request body. This makes it possible to stream requests without requiring the entire content to be loaded in memory for encoding/decoding. Note that the use of this function is incompatible with gRPC and calling it on a method that defines a gRPC transport is an error.

SkipRequestBodyEncodeDecode must appear in a HTTP endpoint expression.

Example:

var _ = Service("upload", func() {
    Method("upload", func() {
        Payload(func() {
            Attribute("id", String)
            Attribute("length", Int)
        })
        HTTP(func() {
            POST("/{id}")
            Header("length:Content-Length")
            SkipRequestBodyEncodeDecode()
        })
    })

func SkipResponseBodyEncodeDecode

func SkipResponseBodyEncodeDecode()

SkipResponseBodyEncodeDecode prevents Goa from generating the response encoding (server) and decoding (client) code. Instead the service method returns a reader from which to stream the HTTP response body io. The client also gets access to a reader to stream the incoming response body. This makes it possible to stream responses without requiring the entire content to be loaded in memory for encoding/decoding. Note that the use of this function is incompatible with gRPC and calling it on a method that defines a gRPC transport is an error.

SkipResponseBodyEncodeDecode must appear in a HTTP endpoint expression.

Example:

var _ = Service("download", func() {
    Method("download", func() {
        Payload(String)
        Result(func() {
            Attribute("length", Int)
        })
        HTTP(func() {
            POST("/{id}")
            SkipResponseBodyEncodeDecode()
            Response(StatusOK, func() {
                Header("length:Content-Length")
            })
        })
    })

func StreamingPayload

func StreamingPayload(val interface{}, args ...interface{})

StreamingPayload defines a method that accepts a stream of instances of the given type.

StreamingPayload must appear in a Method expression.

The arguments to a StreamingPayload DSL is same as the Payload DSL.

Examples:

// Method payload is the JWT token and the method streaming payload is a
// stream of strings.
Method("upper", func() {
    Payload(func() {
        Token("token", String, func() {
            Description("JWT used for authentication")
        })
    })
    StreamingPayload(String)
})

// Method streaming payload is a stream of string with validation set
// on each
Method("upper"), func() {
    StreamingPayload(String, "string to convert to uppercase", func() {
        Pattern("^[a-z]")
    })
}

// Method payload is a stream of objects defined inline
Method("add", func() {
    StreamingPayload(func() {
        Description("Left and right operands to add")
        Attribute("left", Int32, "Left operand")
        Attribute("right", Int32, "Left operand")
        Required("left", "right")
    })
})

// Method payload is a stream of user type
Method("add", func() {
    StreamingPayload(Operands)
})

func StreamingResult

func StreamingResult(val interface{}, args ...interface{})

StreamingResult defines a method that streams instances of the given type.

StreamingResult must appear in a Method expression.

The arguments to a StreamingResult DSL is same as the Result DSL.

Examples:

// Method result is a stream of integers
Method("add", func() {
    StreamingResult(Int32)
})

Method("add", func() {
    StreamingResult(Int32, "Resulting sum")
})

// Method result is a stream of integers with validation set on each
Method("add", func() {
    StreamingResult(Int32, "Resulting sum", func() {
        Minimum(0)
    })
})

// Method result is a stream of objects defined inline
Method("add", func() {
    StreamingResult(func() {
        Description("Result defines a single field which is the sum.")
        Attribute("value", Int32, "Resulting sum")
        Required("value")
    })
})

// Method result is a stream of user type
Method("add", func() {
    StreamingResult(Sum)
})

// Method result is a stream of result type with a view
Method("add", func() {
    StreamingResult(Sum, func() {
        View("default")
        Required("value")
    })
})

func TRACE

func TRACE(path string) *expr.RouteExpr

TRACE creates a route using the TRACE HTTP method. See GET.

func Tag

func Tag(name, value string)

Tag identifies a method result type field and a value. The algorithm that encodes the result into the HTTP response iterates through the responses and uses the first response that has a matching tag (that is for which the result field with the tag name matches the tag value). There must be one and only one response with no Tag expression, this response is used when no other tag matches.

Tag must appear in Response.

Tag accepts two arguments: the name of the field and the (string) value.

Example:

Method("create", func() {
    Result(CreateResult)
    HTTP(func() {
        Response(StatusCreated, func() {
            Tag("outcome", "created") // Assumes CreateResult has attribute
                                      // "outcome" which may be "created"
                                      // or "accepted"
        })

        Response(StatusAccepted, func() {
            Tag("outcome", "accepted")
        })

        Response(StatusOK)            // Default response if "outcome" is
                                      // neither "created" nor "accepted"
    })
})

func Temporary

func Temporary()

Temporary qualifies an error type as describing temporary (i.e. retryable) errors.

Temporary must appear in a Error expression.

Temporary takes no argument.

Example:

var _ = Service("divider", func() {
    Error("request_timeout", func() {
        Temporary()
    })
})

func TermsOfService

func TermsOfService(terms string)

TermsOfService describes the API terms of services or links to them.

TermsOfService must appear in a API expression.

TermsOfService takes a single argument which is the TOS text or URL.

Example:

var _ = API("github", func() {
    TermsOfService("https://help.github.com/articles/github-terms-of-API/"
})

func Timeout

func Timeout()

Timeout qualifies an error type as describing errors due to timeouts.

Timeout must appear in a Error expression.

Timeout takes no argument.

Example:

var _ = Service("divider", func() {
    Error("request_timeout", func() {
        Timeout()
    })
})

func Title

func Title(val string)

Title sets the API title. It is used by the generated OpenAPI specification.

Title must appear in a API expression.

Title accepts a single string argument.

Example:

var _ = API("divider", func() {
    Title("divider API")
})

func Token

func Token(name string, args ...interface{})

Token defines the attribute used to provide the JWT to an endpoint secured via JWT. The parameters and usage of Token are the same as the goa DSL Attribute function.

The generated code produced by goa uses the value of the corresponding payload field to initialize the Authorization header.

Example:

Method("secured", func() {
    Security(JWT)
    Payload(func() {
        Token("token", String, "JWT token used to perform authorization")
        Required("token")
    })
    Result(String)
    HTTP(func() {
        // The "Authorization" header is defined implicitly.
        GET("/")
    })
})

func TokenField

func TokenField(tag interface{}, name string, args ...interface{})

TokenField is syntactic sugar to define a JWT token attribute with the "rpc:tag" meta set with the value of the first argument.

TokenField takes the same arguments as Token with the addition of the tag value as the first argument.

func Trailers

func Trailers(fn func())

Trailers defines gRPC trailers in response metadata.

Trailers must appear in a gRPC response expression to describe gRPC trailers in response metadata.

Trailers takes one argument of function type which lists the attributes that must be set in the trailer response metadata instead of the message. If Trailers is set in the gRPC response expression, it inherits the attribute properties (description, type, meta, validations etc.) from the method result.

Example:

var CreatePayload = Type("CreatePayload", func() {
    Field(1, "name", String, "Name of account")
    TokenField(2, "token", String, "JWT token for authentication")
})

var CreateResult = ResultType("application/vnd.create", func() {
    Attributes(func() {
        Field(1, "name", String, "Name of the created resource")
        Field(2, "href", String, "Href of the created resource")
    })
})

Method("create", func() {
    Payload(CreatePayload)
    Result(CreateResult)
    GRPC(func() {
        Response(func() {
            Code(CodeOK)
            Trailers(func() {
                Attribute("name") // "name" sent in the trailer metadata
            })
        })
    })
})

func Type

func Type(name string, args ...interface{}) expr.UserType

Type defines a user type. A user type has a unique name and may be an alias to an existing type or may describe a completely new type using a list of attributes (object fields). Attribute types may themselves be user type. When a user type is defined as an alias to another type it may define additional validations - for example it a user type which is an alias of String may define a validation pattern that all instances of the type must match.

Type is a top level definition.

Type takes two or three arguments: the first argument is the name of the type. The name must be unique. The second argument is either another type or a function. If the second argument is a type then there may be a function passed as third argument.

Example:

// simple alias
var MyString = Type("MyString", String)

// alias with description and additional validation
var Hostname = Type("Hostname", String, func() {
    Description("A host name")
    Format(FormatHostname)
})

// new type
var SumPayload = Type("SumPayload", func() {
    Description("Type sent to add method")

    Attribute("a", String)                 // string attribute "a"
    Attribute("b", Int32, "operand")       // attribute with description
    Attribute("operands", ArrayOf(Int32))  // array attribute
    Attribute("ops", MapOf(String, Int32)) // map attribute
    Attribute("c", SumMod)                 // attribute using user type
    Attribute("len", Int64, func() {       // attribute with validation
        Minimum(1)
    })

    Required("a")                          // Required attributes
    Required("b", "c")
})

func TypeName

func TypeName(name string)

TypeName makes it possible to set the Go struct name for a type or result type in the generated code. By default goa uses the name (type) or identifier (result type) given in the DSL and computes a valid Go identifier from it. This function makes it possible to override that and provide a custom name. name must be a valid Go identifier.

TypeName must appear in a Type or ResultType expression.

func URI

func URI(uri string)

URI defines a server host URI. A single host may define multiple URIs. The supported schemes are 'http', 'https', 'grpc' and 'grpcs' where 'grpcs' indicates gRPC using client-side SSL/TLS. gRPC URIs may only define the authority component (in particular no path). URIs may be parameterized using the {param} notation. Note that the variables appearing in a URI must be provided when the service is initialized and in particular their values cannot defer between requests.

The URI expression is leveraged by the example generator to produce the service and client commands. It is also consumed by the OpenAPI specification generator to initialize the server objects.

URI must appear in a Host expression.

URI takes one argument: a string representing the URI value.

Example:

var _ = Server("calcsvc", func() {
    Host("development", func() {
        URI("http://localhost:80/{version}/calc")
        URI("grpc://localhost:8080")
    })
})

func URL

func URL(url string)

URL sets the contact, license or external documentation URL.

URL must appear in Contact, License or Docs.

URL accepts a single argument which is the URL.

Example:

Docs(func() {
    URL("https://goa.design")
})

func Username

func Username(name string, args ...interface{})

Username defines the attribute used to provide the username to an endpoint secured with basic authentication. The parameters and usage of Username are the same as the goa DSL Attribute function.

The generated code produced by goa uses the value of the corresponding payload field to compute the basic authentication Authorization header value.

Username must appear in Payload or Type.

Example:

Method("login", func() {
    Security(Basic)
    Payload(func() {
        Username("user", String)
        Password("pass", String)
    })
    HTTP(func() {
        // The "Authorization" header is defined implicitly.
        POST("/login")
    })
})

func UsernameField

func UsernameField(tag interface{}, name string, args ...interface{})

UsernameField is syntactic sugar to define a username attribute with the "rpc:tag" meta set with the value of the first argument.

UsernameField takes the same arguments as Username with the addition of the tag value as the first argument.

func Value

func Value(val interface{})

Value sets the example value.

Value must appear in Example.

Value takes one argument: the example value.

Example:

Example("A simple bottle", func() {
    Description("This bottle has an ID set to 1")
    Value(Val{"ID": 1})
})

func Variable

func Variable(name string, args ...interface{})

Variable defines a server host URI variable.

The URI expression is leveraged by the example generator to produce the service and client commands. It is also consumed by the OpenAPI specification generator to initialize the server objects.

Variable must appear in a Host expression.

The Variable DSL is the same as the Attribute DSL with the following two restrictions:

  1. The type used to define the variable must be a primitive.
  2. The variable must have a default value and/or a enum validation.

Example:

var _ = Server("calcsvr", func() {
    Host("production", func() {
        URI("https://{version}.goa.design/calc")
        URI("grpcs://{version}.goa.design")

        Variable("version", String, "API version", func() {
            Enum("v1", "v2")
        })
    })
})

func Version

func Version(ver string)

Version specifies the API version. One design describes one version.

Version must appear in a API expression.

Version accepts a single string argument.

Example:

var _ = API("divider", func() {
    Version("1.0")
})

func View

func View(name string, adsl ...func())

View has two usages:

- when used inside a ResultType DSL function it defines a view for the result type. A view lists a subset of the result type attributes that are used when marshalling responses.

- when used inside a Result DSL function it defines the view used to marshal the result type returned by the method.

Note that the view used to render a response can also be set dynamically by the method code in which case the result function should not specify a view in the design. The attribute names listed in a view must be identical to existing attributes in the result type on which the view is defined. If an attribute is itself a result type then the view may specify which view to use when marshaling the attribute using the View function recursively, see example below. All result types must have a view called "default" which is the view used to marshal results when no specific view is specified.

View must appear in a ResultType or a Result expression.

View accepts two arguments for the first usage: the view name and its defining DSL. View accepts a single argument for the second usage: the view name used to render the result.

Examples:

// MyResultType defines 2 views.
var MyResultType = ResultType("application/vnd.goa.my", func() {
    Attributes(func() {
        Attribute("id", String)
        Attribute("name", String)
        Attribute("origin", OriginResult)
    })

    View("default", func() {
        // "id" and "name" must be result type attributes
        Attribute("id")
        Attribute("name")
    })

    View("extended", func() {
        Attribute("id")
        Attribute("name")
        Attribute("origin", func() {
            // Use view "extended" to render attribute "origin"
            View("extended")
        })
    })
})

// MyMethod uses the extended view of MyResultType to marshal the
// response.
var _ = Service("MyService", func() {
    Method("MyMethod", func() {
        Result(MyResultType, func() { View("extended") })
        GRPC(func() {})
    })
})

Types

type Val

type Val expr.Val

Val is an alias for expr.Val.

Jump to

Keyboard shortcuts

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