Skip to content

Instantly share code, notes, and snippets.

@igtm
Created December 15, 2020 12:15
Show Gist options
  • Save igtm/ec7e325fdf8cf1d63f0a24ae5d2c15df to your computer and use it in GitHub Desktop.
Save igtm/ec7e325fdf8cf1d63f0a24ae5d2c15df to your computer and use it in GitHub Desktop.
example code of uploading file on Goa v3
package design
import . "goa.design/goa/v3/dsl"
// TODO
// var _ = API("foo", func() { ....
var SourceFilePayload = Type("SourceFilePayload", func() {
Attribute("file_name", String, "uploaded file name", func() {
Example("foo.jpg")
})
Attribute("content", Bytes, "content of image")
Attribute("format", String, "uploaded file format", func() {
Example("image/jpeg")
})
Required(
"file_name",
"content",
"format",
)
})
var _ = Service("file", func() {
HTTP(func() {
Path("/file")
})
Method("upload", func() {
Description("upload a file")
Payload(SourceFilePayload)
HTTP(func() {
POST("/")
MultipartRequest()
})
})
})
package foo
import (
"bytes"
"image"
"io"
"io/ioutil"
"mime/multipart"
_ "image/gif"
_ "image/jpeg"
_ "image/png"
"foo/server/gen/file"
)
// FileUploadDecoderFunc implements the multipart decoder for service
// "file" endpoint "upload". The decoder must populate the argument p
// after encoding.
func FileUploadDecoderFunc(mr *multipart.Reader, p **file.SourceFilePayload) error {
// Add multipart request decoder logic here
var r file.SourceFilePayload
for {
part, err := mr.NextPart()
if err == io.EOF {
break
}
if err != nil {
return err
}
if part.FileName() != "" {
slurp, err := ioutil.ReadAll(part)
if err != nil {
return err
}
r.FileName = part.FileName()
r.Content = slurp
// guess mime type
slurpReader := bytes.NewReader(slurp)
_, ft, err := image.Decode(slurpReader)
if err != nil {
return err
}
r.Format = ft
break
}
}
*p = &r
return nil
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment