goa v1.4.0
Announcing goa v1.4.0
It’s been almost a year since the last official release of goa. During that year
many contributions have been made including both new features and bug fixes. The
team has also been hard at work on v2 making good progress there but this post
is about the latest v1 release: goa v1.4.0
.
New Features
Multipart Form Encoding
Taichi Sasaki (@tchssk) added native support for multipart form encoding as
described in the
HTML 4 Specification.
The new MultipartForm
function can be used in an action design as follows:
var _ = Resource("profiles", func() {
Action("submit", func() {
Routing(POST("profiles"))
Payload(ProfilePayload)
MultipartForm() // Uses "multipart/form-data" encoding
Description("Post accepts a multipart form encoded request")
Response(OK, ResultMedia)
})
})
The Multipart Form Encoding example provides a complete design and example implementation.
Add support for multipart form requests #1606 - Taichi Sasaki
Primitive File Type
Taichi Sasaki (@tchssk) also added the ability to map payload attributes to
multipart files making it convenient to implement file upload in goa. The new
File
type can be used in combination with MultipartForm()
as follows:
var _ = Resource("profiles", func() {
Action("submit", func() {
Routing(POST("profiles"))
Payload(ProfilePayload)
MultipartForm() // Uses "multipart/form-data" encoding
Description("Post accepts a multipart form encoded request")
Response(OK, ResultMedia)
})
})
var ProfilePayload = Type("ProfilePayload", func() {
Attribute("name", String, "Name")
Attribute("birthday", DateTime, "Birthday")
Attribute("icon", File, "Icon") // Attribute "icon" contains a file
Required("name", "birthday", "icon")
})
The controller can then simply access the file content as follows:
file, err := ctx.Payload.Icon.Open()
if err != nil {
return err
}
defer file.Close()
f, err := os.OpenFile("./icons/"+ctx.Payload.Icon.Filename, os.O_WRONLY|os.O_CREATE, 0666)
if err != nil {
return fmt.Errorf("failed to save file: %s", err) // causes a 500 response
}
defer f.Close()
io.Copy(f, file)
The Multipart Form Encoding example provides a complete design and example implementation.
Add a primitive type File #1642 - Taichi Sasaki
Sensitive Headers Suppression
Adam Hanna (@adam-hanna) made it possible to identify header values that should
not be logged by the LogRequest
middleware. The names of the corresponding
headers should be given to the new variadic middleware constructor parameter:
middleware.LogRequest(true, "Authorization", "Api-Key", "Owner-Email")
Add ability to suppress sensitive headers from log #1691 - Adam Hanna
OpenAPI Specification Read-Only Fields
Daniel I. Khan Ramiro (@dikhan) added the ability to specify read-only attributes. Such attributes are marked as read-only in the generated OpenAPI specification and behave like other attributes otherwise.
var TypeWithReadOnlyAttributes = Type("Foo", func() {
Attribute("standard", String)
Attribute("read-only", String, func() {
ReadOnly()
})
})
Add support for readonly attributes #1776 - Daniel I. Khan Ramiro
Support for RFC3339 Date Format
Konstantin Lepa (@k-lepa) added support for date only format. goa had support
for the RFC3339 DateTime format this PR adds support for the RFC3339 Date
format, eg: 2017-11-16
.
var TypeWithDate = Type("Foo", func() {
Attribute("date", String, func() {
Format("date")
})
})
Add RFC3339 date format #1787 - Konstantin Lepa
Support JWT Authorization via Query String
Jie Kang (@jiekang) made it possible for clients to provide the JWT token used for authorization in the HTTP request query string parameters (on top of HTTP headers).
Add support for JWT Token authorization via query parameter #1800 - Jie Kang
Bug Fixes
As noted in the introduction this release comes with many bug fixes as well:
- Properly format JavaScript generator Go example code #1497 - Raphael Simon
- Properly test for required attributes when unmarshaling #1521 - Raphael Simon
- Remove the unused valiable #1550 - @ikawaha
- Prevent “Any” fields from pointing to *interface{} #1591 - Alex Brausewetter
- Prevent pointer to ‘*interface{}’ in user types #1611 - Alex Brausewetter
- Fix MuxHandler initialization race #1627 - Robert Wooley
- Validate different wildcards only if request method is the same #1583 - Egor Kovetskiy
- Make sure to finalize parent resources first. #1655 - Raphael Simon
- Fix serialization of default values for non string and non integer attributes. #1681 - Raphael Simon
- Properly generate validation for URL parameter arrays #1721 - Raphael Simon
- Add a yaml tag to generated types fields #1733
- Make request header logging order consistent #1748 - Raphael Simon
- Fix for v1 multipart/form-data Swagger semantic error #1744 - Mark Songhurst
- Make sure default output dir is set #1751 - Raphael Simon
- Fix gocyclo dependency #1772 - Konstantin Lepa & Raphael Simon
- Fix minItems/maxItems for array type #1775 - Konstantin Lepa
- Fix recursive types #1774 - Konstantin Lepa
- Fix client tests when GOPATH is /go #1773
- Fix design.HasFile for recursive user types #1791 - Konstantin Lepa
Thank You!
A big thank you to all the contributors! A special thank you to Jie Kang who helped put together these release notes.
As we look ahead for goa the big ticket item is the release of v2. v2 is being used in production in a few sites already, the last pieces needed before it can be released (i.e. made the default version) are the gRPC transport and better documentation. Head over to the repo and check out the README for more information.