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 . "github.com/StemsDAO/goa-grpc-option/v3/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
- Variables
- func API(name string, fn func()) *expr.APIExpr
- func APIKey(scheme, name string, args ...interface{})
- func APIKeyField(tag interface{}, scheme, name string, args ...interface{})
- func APIKeySecurity(name string, fn ...func()) *expr.SchemeExpr
- func AccessToken(name string, args ...interface{})
- func AccessTokenField(tag interface{}, name string, args ...interface{})
- func ArrayOf(v interface{}, fn ...func()) *expr.Array
- func Attribute(name string, args ...interface{})
- func Attributes(fn func())
- func AuthorizationCodeFlow(authorizationURL, tokenURL, refreshURL string)
- func BasicAuthSecurity(name string, fn ...func()) *expr.SchemeExpr
- func Body(args ...interface{})
- func CONNECT(path string) *expr.RouteExpr
- func CanonicalMethod(name string)
- func ClientCredentialsFlow(tokenURL, refreshURL string)
- func Code(code int)
- func Consumes(args ...string)
- func Contact(fn func())
- func ContentType(typ string)
- func ConvertTo(obj interface{})
- func Cookie(name string, args ...interface{})
- func CookieDomain(d string)
- func CookieHTTPOnly()
- func CookieMaxAge(n int)
- func CookiePath(p string)
- func CookieSecure()
- func CreateFrom(obj interface{})
- func DELETE(path string) *expr.RouteExpr
- func Default(def interface{})
- func Description(d string)
- func Docs(fn func())
- func Elem(fn func())
- func Email(email string)
- func Enum(vals ...interface{})
- func Error(name string, args ...interface{})
- func ErrorName(args ...interface{})
- func Example(args ...interface{})
- func ExclusiveMaximum(val interface{})
- func ExclusiveMinimum(val interface{})
- func Extend(t expr.DataType)
- func Fault()
- func Field(tag interface{}, name string, args ...interface{})
- func Files(path, filename string, fns ...func())
- func Format(f expr.ValidationFormat)
- func GET(path string) *expr.RouteExpr
- func GRPC(fn func())
- func HEAD(path string) *expr.RouteExpr
- func HTTP(fns ...func())
- func Header(name string, args ...interface{})
- func Headers(args interface{})
- func Host(name string, fn func())
- func ImplicitFlow(authorizationURL, refreshURL string)
- func JWTSecurity(name string, fn ...func()) *expr.SchemeExpr
- func Key(fn func())
- func License(fn func())
- func ListOf(v interface{}, adsl ...func()) *expr.ResultTypeExpr
- func MapOf(k, v interface{}, fn ...func()) *expr.Map
- func MapParams(args ...interface{})
- func MaxLength(val int)
- func Maximum(val interface{})
- func Message(fn func())
- func Meta(name string, value ...string)
- func Metadata(fn func())
- func Method(name string, fn func())
- func MinLength(val int)
- func Minimum(val interface{})
- func MultipartRequest()
- func Name(name string)
- func NoSecurity()
- func OAuth2Security(name string, fn ...func()) *expr.SchemeExpr
- func OPTIONS(path string) *expr.RouteExpr
- func OneOf(name string, args ...interface{})
- func Option(tag, value string)
- func PATCH(path string) *expr.RouteExpr
- func POST(path string) *expr.RouteExpr
- func PUT(path string) *expr.RouteExpr
- func Package(name string)
- func Param(name string, args ...interface{})
- func Params(args interface{})
- func Parent(name string)
- func Password(name string, args ...interface{})
- func PasswordField(tag interface{}, name string, args ...interface{})
- func PasswordFlow(tokenURL, refreshURL string)
- func Path(val string)
- func Pattern(p string)
- func Payload(val interface{}, args ...interface{})
- func Produces(args ...string)
- func Redirect(url string, code int)
- func Reference(t expr.DataType)
- func Required(names ...string)
- func Response(val interface{}, args ...interface{})
- func Result(val interface{}, args ...interface{})
- func ResultType(identifier string, args ...interface{}) *expr.ResultTypeExpr
- func Scope(name string, desc ...string)
- func Security(args ...interface{})
- func Server(name string, fn ...func()) *expr.ServerExpr
- func Service(name string, fn func()) *expr.ServiceExpr
- func Services(svcs ...string)
- func SkipRequestBodyEncodeDecode()
- func SkipResponseBodyEncodeDecode()
- func StreamingPayload(val interface{}, args ...interface{})
- func StreamingResult(val interface{}, args ...interface{})
- func TRACE(path string) *expr.RouteExpr
- func Tag(name, value string)
- func Temporary()
- func TermsOfService(terms string)
- func Timeout()
- func Title(val string)
- func Token(name string, args ...interface{})
- func TokenField(tag interface{}, name string, args ...interface{})
- func Trailers(fn func())
- func Type(name string, args ...interface{}) expr.UserType
- func TypeName(name string)
- func URI(uri string)
- func URL(url string)
- func Username(name string, args ...interface{})
- func UsernameField(tag interface{}, name string, args ...interface{})
- func Value(val interface{})
- func Variable(name string, args ...interface{})
- func Version(ver string)
- func View(name string, adsl ...func())
- type Val
Constants ¶
const ( // InvalidFieldType is the error name for invalid field type errors. InvalidFieldType = pkg.InvalidFieldType // MissingField is the error name for missing field errors. MissingField = pkg.MissingField // InvalidEnumValue is the error name for invalid enum value errors. InvalidEnumValue = pkg.InvalidEnumValue // InvalidFormat is the error name for invalid format errors. InvalidFormat = pkg.InvalidFormat // InvalidPattern is the error name for invalid pattern errors. InvalidPattern = pkg.InvalidPattern // InvalidRange is the error name for invalid range errors. InvalidRange = pkg.InvalidRange // InvalidLength is the error name for invalid length errors. InvalidLength = pkg.InvalidLength )
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 = 14 // CodeDataLoss represents the gRPC response code "DataLoss". CodeDataLoss = 15 // CodeUnauthenticated represents the gRPC response code "Unauthenticated". CodeUnauthenticated = 16 )
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 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 StatusInternalServerError = expr.StatusInternalServerError StatusNotImplemented = expr.StatusNotImplemented StatusBadGateway = expr.StatusBadGateway StatusGatewayTimeout = expr.StatusGatewayTimeout StatusHTTPVersionNotSupported = expr.StatusHTTPVersionNotSupported StatusVariantAlsoNegotiates = expr.StatusVariantAlsoNegotiates StatusInsufficientStorage = expr.StatusInsufficientStorage StatusLoopDetected = expr.StatusLoopDetected StatusNotExtended = expr.StatusNotExtended StatusNetworkAuthenticationRequired = expr.StatusNetworkAuthenticationRequired )
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 )
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 ¶
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 )
var Empty = expr.Empty
Empty represents empty values.
Functions ¶
func API ¶
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 ¶
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: ListOf and ArrayOf both return array types. ListOf returns a result type where ArrayOf returns a user type. In general you want to use ListOf 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 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 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:
- Look for an attribute with the same name as the field
- Look for an attribute with the same name as the field but with the first letter being lowercase
- 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 ¶
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 "secure" 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:
- Look for an attribute with the same name as the field
- Look for an attribute with the same name as the field but with the first letter being lowercase
- 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 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. Error may also appear under the API expression to create reusable error definitions.
See Attribute for details on the Error arguments.
Example:
var _ = API("calc", func() { Error("invalid_argument") // Uses type ErrorResult HTTP(func() { Response("invalid_argument", StatusBadRequest) }) }) var _ = Service("divider", func() { Error("invalid_arguments") // Refers to error defined above. // No need to define HTTP mapping again. // Method which uses the default type for its response. Method("divide", func() { Payload(DivideRequest) Error("div_by_zero", DivByZero, "Division by zero") }) })
func ErrorName ¶
func ErrorName(args ...interface{})
ErrorName identifies the attribute of a custom error type used to select the returned error response when multiple errors of that type are defined on the same method. The value of the field identifies the error name 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 defined with ErrorName on types used to define errors.
ErrorName must appear in a Type or ResultType expression.
ErrorName takes the same arguments as Attribute or Field.
Example design:
// All the methods exposed by service MyService can return the errors // "internal_error" and "bad_request". Both errors have the same type // CustomErrorType. "internal_error" is mapped to HTTP status 500 and // "bad_request" is mapped to HTTP status 400. var _ = Service("MyService", func() { Error("internal_error", CustomErrorType) Error("bad_request", CustomErrorType) HTTP(func() { Response("internal_error", StatusInternalServerError) Response("bad_request", StatusBadRequest) }) Method("Method", func() { Payload(String) HTTP(func() { GET("/") }) }) }) var CustomErrorType = Type("CustomError", func() { // The "name" attribute is used to select the error response. // name should be set to either "internal_error" or "bad_request" by // the service method returning the error. ErrorName("name", String, "Name of error.") Attribute("message", String, "Message of error.") Attribute("occurred_at", String, "Time error occurred.", func() { Format(FormatDateTime) }) Required("name", "message", "occurred_at") })
Example usage:
func (s *svc) Method(ctx context.Context, p string) error { // ... if err != nil { return &myservice.CustomError{ Name: "internal_error", // HTTP response status is 500. Message: "Something went wrong", OccurredAt: time.Now().Format(time.RFC3339), } } // ... return nil }
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 "openapi: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 ExclusiveMaximum ¶
func ExclusiveMaximum(val interface{})
ExclusiveMaximum adds a "exclusiveMaximum" validation to the attribute. See http://json-schema.org/draft/2019-09/json-schema-validation.html#rfc.section.6.2.3.
Example:
Attribute("float", float32, func() { ExclusiveMaximum(100) })
func ExclusiveMinimum ¶
func ExclusiveMinimum(val interface{})
ExclusiveMinimum adds a "exclusiveMinimum" validation to the attribute. See http://json-schema.org/draft/2019-09/json-schema-validation.html#rfc.section.6.2.5.
Example:
Attribute("float", float32, func() { ExclusiveMinimum(100) })
func Extend ¶
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 that defines a tag, e.g. for protobuf. The result is the same as calling Attribute with the "rpc:tag" meta set with the value of the first argument.
Field can 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 an 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". If you do not explicitly map index.html under a wildcard path, the underlying http.ServeFile() call will return a redirect to ./ instead of the index.html file.
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 ¶
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 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 ¶
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 ListOf ¶
func ListOf(v interface{}, adsl ...func()) *expr.ResultTypeExpr
ListOf creates a list result type from its element result type. A list result type represents the content of responses that return a list 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 "list".
ListOf must appear wherever ResultType can.
ListOf 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 = ListOf(DivisionResult) var TinyMultiResults = ListOf(DivisionResult, func() { View("tiny") // use "tiny" view to render the list elements }) var MultiResultsExample = ListOf(DivisionResult, func() { Attributes(func() { Example("DivisionResult List Examples", func() { Value([]Val{ { "value": 4.167, "reminder": 0, }, { "value": 3.0, "reminder": 0, }, }) }) }) })
func MapOf ¶
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 Review = Type("Review", func() { Attribute("ratings", MapOf(Bottle, Int32), "Bottle ratings", func() { Elem(func() { Minimum(1) Maximum(5) }) }) })
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 ¶
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" DEPRECATED, use ErrorName instead.
- "struct:pkg:path" overrides where the Go type generated for the enclosing user type definition is generated. Both the file location and Go package name are overridden. The file location is computed by appending the location of the gen folder with the string given as second argument to Meta. So for example Meta("struct:pkg:path", "foo/bar") will generate the Go type in the file "gen/foo/bar/<name>.go" where <name> is the name of the type. Additionally the package name is computed by taking the base path of the provided location ("bar" in the prior example). The example below causes the Go type declaration for MyType to live in the file gen/types/mytype.go with the package name "types":
package design var MyType = Type("MyType", func() { Attribute("name") Meta("struct:pkg:path", "types") })
- "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:field:proto" overrides the generated protobuf field type. If the type is defined in a separate proto file, the last three elements define the proto file import path, Go type name and Go import path respectively.
var Timestamp = Type("Timestamp", func() { Description("Google timestamp compatible design") Field(1, "seconds", Int64, "Unix timestamp in seconds", func() { Meta("struct:field:proto", "int64") // Goa generates sint64 by default }) Field(2, "nanos", Int32, "Unix timestamp in nanoseconds", func() { Meta("struct:field:proto", "int32") // Goa generates sint32 by default }) }) var MyType = Type("MyType", func() { Field(1, "created_at", Timestamp, func() { Meta("struct:field:proto", "google.protobuf.Timestamp", "google/protobuf/timestamp.proto", "Timestamp", "google.golang.org/protobuf/types/known/timestamppb") }) })
- "struct:field:proto:wrapper" allows to override the generated protobuf field name when user type is being wrapped. Defaults to "field".
Method("ArtistRoles_ListAll", func() { Result(ListOf(ArtistRole), func() { Meta("struct:field:proto:wrapper", "artist_role") }) })
- "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") }) })
- "protoc:include" provides the list of import paths used to invoke protoc. Applicable to API and service definitions only. If used on an API definition the include paths are used for all services.
var _ = API("myapi", func() { Meta("protoc:include", "/usr/include", "/usr/local/include") }) var _ = Service("service1", func() { Meta("protoc:include", "/usr/local/include/google/protobuf") })
- "proto:option" allows to add protobuf option directives to methods and service definitions.
var _ = Service("service1", func() { Meta("proto:option", "my_option_svc", `"Hello world!"`) Method("MyMethod", func() { Meta("proto:option", "my_option_rpc", "{type: QUERY}") }) })
- "swagger:generate" DEPRECATED, use "openapi:generate" instead.
- "openapi:generate" specifies whether OpenAPI specification should be generated. Defaults to true. Applicable to services, methods and file servers.
var _ = Service("MyService", func() { Meta("openapi:generate", "false") })
- "swagger:summary" DEPRECATED, use "openapi:summary" instead
- "openapi:summary" sets the OpenAPI operation summary field. The special value "{path}" is replaced with the method HTTP path. Applicable to methods or to API .
var _ = Service("MyService", func() { Method("MyMethod", func() { Meta("openapi:summary", "Summary of MyMethod") }) })
- "openapi:operationId" sets the OpenAPI operationId field format. The following special values will be replaced with operation-specific information:
"{service}" is replaced with the name of the service "{method}" is replaced with the name of the method "(#{routeIndex})" is replaced with the index of the path in cases where a method has more than one route associated with it. The index will never be added when only one route exists. The # character may be swapped for any content you wish to use as a spacer between the preceding content and the route index.
If you wish to specify a static operationId, omitting any of the above special values will render the operationId as a literal.
Defaults to "{service}#{method}(#{routeIndex})". Applicable to methods, services, or to API.
var _ = Service("MyService", func() { Method("MyMethod", func() { // Generates MyService.MyMethod Meta("openapi:operationId", "{service}.{method}(.{routeIndex})") }) })
- "swagger:example" DEPRECATED, use "openapi:example" instead
- "openapi: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("openapi:example", "false") })
- "swagger:tag:xxx" DEPRECATED, use "openapi:tag:xxx" instead
- "openapi:tag:xxx" sets the OpenAPI object field tag xxx. Applicable to services and methods.
var _ = Service("MyService", func() { Method("MyMethod", func() { Meta("openapi:tag:Backend") Meta("openapi:tag:Backend:desc", "Description of Backend") Meta("openapi:tag:Backend:url", "http://example.com") Meta("openapi:tag:Backend:url:desc", "See more docs here") Meta("openapi:tag:Backend:extension:x-data", `{"foo":"bar"}`) }) })
- "swagger:extension:xxx" DEPRECATED, use "openapi:extension:xxx" instead
- "openapi:extension:xxx" sets the OpenAPI extensions xxx. The value can be any valid JSON. Applicable to API (OpenAPI info and tag objects), Service (OpenAPI paths object), Method (OpenAPI path-item object), Route (OpenAPI operation object), Param (OpenAPI parameter object), Response (OpenAPI response object) and Security (OpenAPI security-scheme object). See https://github.com/OAI/OpenAPI-Specification/blob/master/guidelines/EXTENSIONS.md.
var _ = API("MyAPI", func() { Meta("openapi: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 OneOf ¶
func OneOf(name string, args ...interface{})
OneOf creates a union type from a name and a list of attributes.
OneOf may be used wherever Attribute can.
OneOf takes a name as first argument, a description as optional second argument and a function that lists the union types as last argument.
Example:
var PetOwner = Type("PetOwner", func() { Name("name", String) OneOf("pet", "Owner's pet", func() { Attribute("cat", Cat, "Cats are cool") Attribute("dog", Dog, "Dogs are cool too") }) })
func Package ¶
func Package(name string)
Package defines the name of the protobuf package. It defaults to the name of the service (in snake_case).
Package must appear in a service GRPC expression.
Package accepts one argument: the name of the protobuf package.
Example:
var GRPCService = Service("my_grpc_service", func() { GRPC(func() { Package("svc") }) Method("add", func() { Payload(func() { Field(1, "a", Int) Field(2, "b", Int) }) Result(Int) }) GRPC(func() {}) })
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 a 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 Redirect ¶
Redirect indicates that HTTP requests reply to the request with a redirect. The logic is the same as the standard http package Redirect function.
Redirect must appear in a HTTP endpoint expression or a HTTP file server expression.
Redirect accepts 2 arguments. The first argument is the URL that is being redirected to. The second argument is the HTTP status code.
Example:
var _ = Service("service", func() { Method("method", func() { HTTP(func() { GET("/resources") Redirect("/redirect/dest", StatusMovedPermanently) }) }) }) var _ = Service("service", func() { Files("/file.json", "/path/to/file.json", func() { Redirect("/redirect/dest", StatusMovedPermanently) }) })
func Reference ¶
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. 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") 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 ¶
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 an entire API, service or individual 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 API, 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() { Description("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 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 ¶
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 if 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:
- The type used to define the variable must be a primitive.
- 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() {}) }) })